diff --git a/of11/message.go b/of11/message.go
new file mode 100644
index 0000000..addceda
--- /dev/null
+++ b/of11/message.go
@@ -0,0 +1,5988 @@
+/*
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+ * Copyright (c) 2011, 2012 Open Networking Foundation
+ * Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler.
+ * Copyright 2018, Red Hat, Inc.
+ */
+// Automatically generated by LOXI from template module.go
+// Do not modify
+
+package of11
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"net"
+
+	"github.com/opencord/goloxi"
+)
+
+type Header struct {
+	Version uint8
+	Type    uint8
+	Length  uint16
+	Xid     uint32
+}
+
+type IHeader interface {
+	goloxi.Serializable
+	GetVersion() uint8
+	GetType() uint8
+	GetLength() uint16
+	GetXid() uint32
+}
+
+func (self *Header) GetVersion() uint8 {
+	return self.Version
+}
+
+func (self *Header) SetVersion(v uint8) {
+	self.Version = v
+}
+
+func (self *Header) GetType() uint8 {
+	return self.Type
+}
+
+func (self *Header) SetType(v uint8) {
+	self.Type = v
+}
+
+func (self *Header) GetLength() uint16 {
+	return self.Length
+}
+
+func (self *Header) SetLength(v uint16) {
+	self.Length = v
+}
+
+func (self *Header) GetXid() uint32 {
+	return self.Xid
+}
+
+func (self *Header) SetXid(v uint32) {
+	self.Xid = v
+}
+
+func (self *Header) Serialize(encoder *goloxi.Encoder) error {
+
+	encoder.PutUint8(uint8(2))
+	encoder.PutUint8(uint8(self.Type))
+	encoder.PutUint16(uint16(self.Length))
+	encoder.PutUint32(uint32(self.Xid))
+
+	return nil
+}
+func (self *Header) Decode(decoder *goloxi.Decoder) error {
+	if decoder.Length() < 8 {
+		return fmt.Errorf("Header packet too short: %d < 8", decoder.Length())
+	}
+
+	self.Version = uint8(decoder.ReadByte())
+	self.Type = uint8(decoder.ReadByte())
+	self.Length = uint16(decoder.ReadUint16())
+	oldDecoder := decoder
+	defer func() { decoder = oldDecoder }()
+	decoder = decoder.SliceDecoder(int(self.Length), 2+2)
+	self.Xid = uint32(decoder.ReadUint32())
+
+	return nil
+}
+func DecodeHeader(decoder *goloxi.Decoder) (IHeader, error) {
+	_header := &Header{}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("Header packet too short: %d < 8", decoder.Length())
+	}
+	_header.Version = uint8(decoder.ReadByte())
+	_header.Type = uint8(decoder.ReadByte())
+	_header.Length = uint16(decoder.ReadUint16())
+	oldDecoder := decoder
+	defer func() { decoder = oldDecoder }()
+	decoder = decoder.SliceDecoder(int(_header.Length), 2+2)
+	_header.Xid = uint32(decoder.ReadUint32())
+
+	switch _header.Type {
+	case 0:
+		return DecodeHello(_header, decoder)
+	case 1:
+		return DecodeErrorMsg(_header, decoder)
+	case 2:
+		return DecodeEchoRequest(_header, decoder)
+	case 3:
+		return DecodeEchoReply(_header, decoder)
+	case 4:
+		return DecodeExperimenter(_header, decoder)
+	case 5:
+		return DecodeFeaturesRequest(_header, decoder)
+	case 6:
+		return DecodeFeaturesReply(_header, decoder)
+	case 7:
+		return DecodeGetConfigRequest(_header, decoder)
+	case 8:
+		return DecodeGetConfigReply(_header, decoder)
+	case 9:
+		return DecodeSetConfig(_header, decoder)
+	case 10:
+		return DecodePacketIn(_header, decoder)
+	case 11:
+		return DecodeFlowRemoved(_header, decoder)
+	case 12:
+		return DecodePortStatus(_header, decoder)
+	case 13:
+		return DecodePacketOut(_header, decoder)
+	case 14:
+		return DecodeFlowMod(_header, decoder)
+	case 15:
+		return DecodeGroupMod(_header, decoder)
+	case 16:
+		return DecodePortMod(_header, decoder)
+	case 17:
+		return DecodeTableMod(_header, decoder)
+	case 18:
+		return DecodeStatsRequest(_header, decoder)
+	case 19:
+		return DecodeStatsReply(_header, decoder)
+	case 20:
+		return DecodeBarrierRequest(_header, decoder)
+	case 21:
+		return DecodeBarrierReply(_header, decoder)
+	case 22:
+		return DecodeQueueGetConfigRequest(_header, decoder)
+	case 23:
+		return DecodeQueueGetConfigReply(_header, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'Header'", _header.Type)
+	}
+}
+
+func NewHeader(_type uint8) *Header {
+	obj := &Header{}
+	obj.Type = _type
+	return obj
+}
+
+type StatsReply struct {
+	*Header
+	StatsType uint16
+	Flags     StatsReplyFlags
+}
+
+type IStatsReply interface {
+	IHeader
+	GetStatsType() uint16
+	GetFlags() StatsReplyFlags
+}
+
+func (self *StatsReply) GetStatsType() uint16 {
+	return self.StatsType
+}
+
+func (self *StatsReply) SetStatsType(v uint16) {
+	self.StatsType = v
+}
+
+func (self *StatsReply) GetFlags() StatsReplyFlags {
+	return self.Flags
+}
+
+func (self *StatsReply) SetFlags(v StatsReplyFlags) {
+	self.Flags = v
+}
+
+func (self *StatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.StatsType))
+	encoder.PutUint16(uint16(self.Flags))
+
+	return nil
+}
+
+func DecodeStatsReply(parent *Header, decoder *goloxi.Decoder) (IStatsReply, error) {
+	_statsreply := &StatsReply{Header: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("StatsReply packet too short: %d < 4", decoder.Length())
+	}
+	_statsreply.StatsType = uint16(decoder.ReadUint16())
+	_statsreply.Flags = StatsReplyFlags(decoder.ReadUint16())
+
+	switch _statsreply.StatsType {
+	case 0:
+		return DecodeDescStatsReply(_statsreply, decoder)
+	case 1:
+		return DecodeFlowStatsReply(_statsreply, decoder)
+	case 2:
+		return DecodeAggregateStatsReply(_statsreply, decoder)
+	case 3:
+		return DecodeTableStatsReply(_statsreply, decoder)
+	case 4:
+		return DecodePortStatsReply(_statsreply, decoder)
+	case 5:
+		return DecodeQueueStatsReply(_statsreply, decoder)
+	case 6:
+		return DecodeGroupStatsReply(_statsreply, decoder)
+	case 7:
+		return DecodeGroupDescStatsReply(_statsreply, decoder)
+	case 65535:
+		return DecodeExperimenterStatsReply(_statsreply, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'StatsReply'", _statsreply.StatsType)
+	}
+}
+
+func NewStatsReply(_stats_type uint16) *StatsReply {
+	obj := &StatsReply{
+		Header: NewHeader(19),
+	}
+	obj.StatsType = _stats_type
+	return obj
+}
+
+type AggregateStatsReply struct {
+	*StatsReply
+	PacketCount uint64
+	ByteCount   uint64
+	FlowCount   uint32
+}
+
+type IAggregateStatsReply interface {
+	IStatsReply
+	GetPacketCount() uint64
+	GetByteCount() uint64
+	GetFlowCount() uint32
+}
+
+func (self *AggregateStatsReply) GetPacketCount() uint64 {
+	return self.PacketCount
+}
+
+func (self *AggregateStatsReply) SetPacketCount(v uint64) {
+	self.PacketCount = v
+}
+
+func (self *AggregateStatsReply) GetByteCount() uint64 {
+	return self.ByteCount
+}
+
+func (self *AggregateStatsReply) SetByteCount(v uint64) {
+	self.ByteCount = v
+}
+
+func (self *AggregateStatsReply) GetFlowCount() uint32 {
+	return self.FlowCount
+}
+
+func (self *AggregateStatsReply) SetFlowCount(v uint32) {
+	self.FlowCount = v
+}
+
+func (self *AggregateStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint64(uint64(self.PacketCount))
+	encoder.PutUint64(uint64(self.ByteCount))
+	encoder.PutUint32(uint32(self.FlowCount))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeAggregateStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*AggregateStatsReply, error) {
+	_aggregatestatsreply := &AggregateStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("AggregateStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	_aggregatestatsreply.PacketCount = uint64(decoder.ReadUint64())
+	_aggregatestatsreply.ByteCount = uint64(decoder.ReadUint64())
+	_aggregatestatsreply.FlowCount = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+	return _aggregatestatsreply, nil
+}
+
+func NewAggregateStatsReply() *AggregateStatsReply {
+	obj := &AggregateStatsReply{
+		StatsReply: NewStatsReply(2),
+	}
+	return obj
+}
+
+type StatsRequest struct {
+	*Header
+	StatsType uint16
+	Flags     StatsRequestFlags
+}
+
+type IStatsRequest interface {
+	IHeader
+	GetStatsType() uint16
+	GetFlags() StatsRequestFlags
+}
+
+func (self *StatsRequest) GetStatsType() uint16 {
+	return self.StatsType
+}
+
+func (self *StatsRequest) SetStatsType(v uint16) {
+	self.StatsType = v
+}
+
+func (self *StatsRequest) GetFlags() StatsRequestFlags {
+	return self.Flags
+}
+
+func (self *StatsRequest) SetFlags(v StatsRequestFlags) {
+	self.Flags = v
+}
+
+func (self *StatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.StatsType))
+	encoder.PutUint16(uint16(self.Flags))
+
+	return nil
+}
+
+func DecodeStatsRequest(parent *Header, decoder *goloxi.Decoder) (IStatsRequest, error) {
+	_statsrequest := &StatsRequest{Header: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("StatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	_statsrequest.StatsType = uint16(decoder.ReadUint16())
+	_statsrequest.Flags = StatsRequestFlags(decoder.ReadUint16())
+
+	switch _statsrequest.StatsType {
+	case 0:
+		return DecodeDescStatsRequest(_statsrequest, decoder)
+	case 1:
+		return DecodeFlowStatsRequest(_statsrequest, decoder)
+	case 2:
+		return DecodeAggregateStatsRequest(_statsrequest, decoder)
+	case 3:
+		return DecodeTableStatsRequest(_statsrequest, decoder)
+	case 4:
+		return DecodePortStatsRequest(_statsrequest, decoder)
+	case 5:
+		return DecodeQueueStatsRequest(_statsrequest, decoder)
+	case 6:
+		return DecodeGroupStatsRequest(_statsrequest, decoder)
+	case 7:
+		return DecodeGroupDescStatsRequest(_statsrequest, decoder)
+	case 65535:
+		return DecodeExperimenterStatsRequest(_statsrequest, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'StatsRequest'", _statsrequest.StatsType)
+	}
+}
+
+func NewStatsRequest(_stats_type uint16) *StatsRequest {
+	obj := &StatsRequest{
+		Header: NewHeader(18),
+	}
+	obj.StatsType = _stats_type
+	return obj
+}
+
+type AggregateStatsRequest struct {
+	*StatsRequest
+	TableId    uint8
+	OutPort    Port
+	OutGroup   uint32
+	Cookie     uint64
+	CookieMask uint64
+	Match      Match
+}
+
+type IAggregateStatsRequest interface {
+	IStatsRequest
+	GetTableId() uint8
+	GetOutPort() Port
+	GetOutGroup() uint32
+	GetCookie() uint64
+	GetCookieMask() uint64
+	GetMatch() Match
+}
+
+func (self *AggregateStatsRequest) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *AggregateStatsRequest) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *AggregateStatsRequest) GetOutPort() Port {
+	return self.OutPort
+}
+
+func (self *AggregateStatsRequest) SetOutPort(v Port) {
+	self.OutPort = v
+}
+
+func (self *AggregateStatsRequest) GetOutGroup() uint32 {
+	return self.OutGroup
+}
+
+func (self *AggregateStatsRequest) SetOutGroup(v uint32) {
+	self.OutGroup = v
+}
+
+func (self *AggregateStatsRequest) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *AggregateStatsRequest) SetCookie(v uint64) {
+	self.Cookie = v
+}
+
+func (self *AggregateStatsRequest) GetCookieMask() uint64 {
+	return self.CookieMask
+}
+
+func (self *AggregateStatsRequest) SetCookieMask(v uint64) {
+	self.CookieMask = v
+}
+
+func (self *AggregateStatsRequest) GetMatch() Match {
+	return self.Match
+}
+
+func (self *AggregateStatsRequest) SetMatch(v Match) {
+	self.Match = v
+}
+
+func (self *AggregateStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	self.OutPort.Serialize(encoder)
+	encoder.PutUint32(uint32(self.OutGroup))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint64(uint64(self.Cookie))
+	encoder.PutUint64(uint64(self.CookieMask))
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeAggregateStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*AggregateStatsRequest, error) {
+	_aggregatestatsrequest := &AggregateStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 108 {
+		return nil, fmt.Errorf("AggregateStatsRequest packet too short: %d < 108", decoder.Length())
+	}
+	decoder.Skip(4)
+	_aggregatestatsrequest.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_aggregatestatsrequest.OutPort.Decode(decoder)
+	_aggregatestatsrequest.OutGroup = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+	_aggregatestatsrequest.Cookie = uint64(decoder.ReadUint64())
+	_aggregatestatsrequest.CookieMask = uint64(decoder.ReadUint64())
+	if err := _aggregatestatsrequest.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _aggregatestatsrequest, nil
+}
+
+func NewAggregateStatsRequest() *AggregateStatsRequest {
+	obj := &AggregateStatsRequest{
+		StatsRequest: NewStatsRequest(2),
+	}
+	return obj
+}
+
+type ErrorMsg struct {
+	*Header
+	ErrType uint16
+}
+
+type IErrorMsg interface {
+	IHeader
+	GetErrType() uint16
+}
+
+func (self *ErrorMsg) GetErrType() uint16 {
+	return self.ErrType
+}
+
+func (self *ErrorMsg) SetErrType(v uint16) {
+	self.ErrType = v
+}
+
+func (self *ErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.ErrType))
+
+	return nil
+}
+
+func DecodeErrorMsg(parent *Header, decoder *goloxi.Decoder) (IErrorMsg, error) {
+	_errormsg := &ErrorMsg{Header: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("ErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_errormsg.ErrType = uint16(decoder.ReadUint16())
+
+	switch _errormsg.ErrType {
+	case 0:
+		return DecodeHelloFailedErrorMsg(_errormsg, decoder)
+	case 1:
+		return DecodeBadRequestErrorMsg(_errormsg, decoder)
+	case 2:
+		return DecodeBadActionErrorMsg(_errormsg, decoder)
+	case 3:
+		return DecodeBadInstructionErrorMsg(_errormsg, decoder)
+	case 4:
+		return DecodeBadMatchErrorMsg(_errormsg, decoder)
+	case 5:
+		return DecodeFlowModFailedErrorMsg(_errormsg, decoder)
+	case 6:
+		return DecodeGroupModFailedErrorMsg(_errormsg, decoder)
+	case 7:
+		return DecodePortModFailedErrorMsg(_errormsg, decoder)
+	case 8:
+		return DecodeTableModFailedErrorMsg(_errormsg, decoder)
+	case 9:
+		return DecodeQueueOpFailedErrorMsg(_errormsg, decoder)
+	case 10:
+		return DecodeSwitchConfigFailedErrorMsg(_errormsg, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'ErrorMsg'", _errormsg.ErrType)
+	}
+}
+
+func NewErrorMsg(_err_type uint16) *ErrorMsg {
+	obj := &ErrorMsg{
+		Header: NewHeader(1),
+	}
+	obj.ErrType = _err_type
+	return obj
+}
+
+type BadActionErrorMsg struct {
+	*ErrorMsg
+	Code BadActionCode
+	Data []byte
+}
+
+type IBadActionErrorMsg interface {
+	IErrorMsg
+	GetCode() BadActionCode
+	GetData() []byte
+}
+
+func (self *BadActionErrorMsg) GetCode() BadActionCode {
+	return self.Code
+}
+
+func (self *BadActionErrorMsg) SetCode(v BadActionCode) {
+	self.Code = v
+}
+
+func (self *BadActionErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadActionErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadActionErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBadActionErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadActionErrorMsg, error) {
+	_badactionerrormsg := &BadActionErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadActionErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badactionerrormsg.Code = BadActionCode(decoder.ReadUint16())
+	_badactionerrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badactionerrormsg, nil
+}
+
+func NewBadActionErrorMsg() *BadActionErrorMsg {
+	obj := &BadActionErrorMsg{
+		ErrorMsg: NewErrorMsg(2),
+	}
+	return obj
+}
+
+type BadInstructionErrorMsg struct {
+	*ErrorMsg
+	Code BadInstructionCode
+	Data []byte
+}
+
+type IBadInstructionErrorMsg interface {
+	IErrorMsg
+	GetCode() BadInstructionCode
+	GetData() []byte
+}
+
+func (self *BadInstructionErrorMsg) GetCode() BadInstructionCode {
+	return self.Code
+}
+
+func (self *BadInstructionErrorMsg) SetCode(v BadInstructionCode) {
+	self.Code = v
+}
+
+func (self *BadInstructionErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadInstructionErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadInstructionErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBadInstructionErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadInstructionErrorMsg, error) {
+	_badinstructionerrormsg := &BadInstructionErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadInstructionErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badinstructionerrormsg.Code = BadInstructionCode(decoder.ReadUint16())
+	_badinstructionerrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badinstructionerrormsg, nil
+}
+
+func NewBadInstructionErrorMsg() *BadInstructionErrorMsg {
+	obj := &BadInstructionErrorMsg{
+		ErrorMsg: NewErrorMsg(3),
+	}
+	return obj
+}
+
+type BadMatchErrorMsg struct {
+	*ErrorMsg
+	Code BadMatchCode
+	Data []byte
+}
+
+type IBadMatchErrorMsg interface {
+	IErrorMsg
+	GetCode() BadMatchCode
+	GetData() []byte
+}
+
+func (self *BadMatchErrorMsg) GetCode() BadMatchCode {
+	return self.Code
+}
+
+func (self *BadMatchErrorMsg) SetCode(v BadMatchCode) {
+	self.Code = v
+}
+
+func (self *BadMatchErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadMatchErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadMatchErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBadMatchErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadMatchErrorMsg, error) {
+	_badmatcherrormsg := &BadMatchErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadMatchErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badmatcherrormsg.Code = BadMatchCode(decoder.ReadUint16())
+	_badmatcherrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badmatcherrormsg, nil
+}
+
+func NewBadMatchErrorMsg() *BadMatchErrorMsg {
+	obj := &BadMatchErrorMsg{
+		ErrorMsg: NewErrorMsg(4),
+	}
+	return obj
+}
+
+type BadRequestErrorMsg struct {
+	*ErrorMsg
+	Code BadRequestCode
+	Data []byte
+}
+
+type IBadRequestErrorMsg interface {
+	IErrorMsg
+	GetCode() BadRequestCode
+	GetData() []byte
+}
+
+func (self *BadRequestErrorMsg) GetCode() BadRequestCode {
+	return self.Code
+}
+
+func (self *BadRequestErrorMsg) SetCode(v BadRequestCode) {
+	self.Code = v
+}
+
+func (self *BadRequestErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadRequestErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadRequestErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBadRequestErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadRequestErrorMsg, error) {
+	_badrequesterrormsg := &BadRequestErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadRequestErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badrequesterrormsg.Code = BadRequestCode(decoder.ReadUint16())
+	_badrequesterrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badrequesterrormsg, nil
+}
+
+func NewBadRequestErrorMsg() *BadRequestErrorMsg {
+	obj := &BadRequestErrorMsg{
+		ErrorMsg: NewErrorMsg(1),
+	}
+	return obj
+}
+
+type BarrierReply struct {
+	*Header
+}
+
+type IBarrierReply interface {
+	IHeader
+}
+
+func (self *BarrierReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBarrierReply(parent *Header, decoder *goloxi.Decoder) (*BarrierReply, error) {
+	_barrierreply := &BarrierReply{Header: parent}
+	return _barrierreply, nil
+}
+
+func NewBarrierReply() *BarrierReply {
+	obj := &BarrierReply{
+		Header: NewHeader(21),
+	}
+	return obj
+}
+
+type BarrierRequest struct {
+	*Header
+}
+
+type IBarrierRequest interface {
+	IHeader
+}
+
+func (self *BarrierRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBarrierRequest(parent *Header, decoder *goloxi.Decoder) (*BarrierRequest, error) {
+	_barrierrequest := &BarrierRequest{Header: parent}
+	return _barrierrequest, nil
+}
+
+func NewBarrierRequest() *BarrierRequest {
+	obj := &BarrierRequest{
+		Header: NewHeader(20),
+	}
+	return obj
+}
+
+type Experimenter struct {
+	*Header
+	Experimenter uint32
+}
+
+type IExperimenter interface {
+	IHeader
+	GetExperimenter() uint32
+}
+
+func (self *Experimenter) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *Experimenter) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *Experimenter) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Experimenter))
+
+	return nil
+}
+
+func DecodeExperimenter(parent *Header, decoder *goloxi.Decoder) (IExperimenter, error) {
+	_experimenter := &Experimenter{Header: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("Experimenter packet too short: %d < 4", decoder.Length())
+	}
+	_experimenter.Experimenter = uint32(decoder.ReadUint32())
+
+	switch _experimenter.Experimenter {
+	case 8992:
+		return DecodeNiciraHeader(_experimenter, decoder)
+	case 6035143:
+		return DecodeBsnHeader(_experimenter, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'Experimenter'", _experimenter.Experimenter)
+	}
+}
+
+func NewExperimenter(_experimenter uint32) *Experimenter {
+	obj := &Experimenter{
+		Header: NewHeader(4),
+	}
+	obj.Experimenter = _experimenter
+	return obj
+}
+
+type BsnHeader struct {
+	*Experimenter
+	Subtype uint32
+}
+
+type IBsnHeader interface {
+	IExperimenter
+	GetSubtype() uint32
+}
+
+func (self *BsnHeader) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *BsnHeader) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *BsnHeader) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Experimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeBsnHeader(parent *Experimenter, decoder *goloxi.Decoder) (IBsnHeader, error) {
+	_bsnheader := &BsnHeader{Experimenter: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnHeader packet too short: %d < 4", decoder.Length())
+	}
+	_bsnheader.Subtype = uint32(decoder.ReadUint32())
+
+	switch _bsnheader.Subtype {
+	case 3:
+		return DecodeBsnSetMirroring(_bsnheader, decoder)
+	case 4:
+		return DecodeBsnGetMirroringRequest(_bsnheader, decoder)
+	case 5:
+		return DecodeBsnGetMirroringReply(_bsnheader, decoder)
+	case 9:
+		return DecodeBsnGetInterfacesRequest(_bsnheader, decoder)
+	case 10:
+		return DecodeBsnGetInterfacesReply(_bsnheader, decoder)
+	case 11:
+		return DecodeBsnSetPktinSuppressionRequest(_bsnheader, decoder)
+	case 15:
+		return DecodeBsnVirtualPortCreateRequest(_bsnheader, decoder)
+	case 16:
+		return DecodeBsnVirtualPortCreateReply(_bsnheader, decoder)
+	case 17:
+		return DecodeBsnVirtualPortRemoveRequest(_bsnheader, decoder)
+	case 18:
+		return DecodeBsnBwEnableSetRequest(_bsnheader, decoder)
+	case 19:
+		return DecodeBsnBwEnableGetRequest(_bsnheader, decoder)
+	case 20:
+		return DecodeBsnBwEnableGetReply(_bsnheader, decoder)
+	case 21:
+		return DecodeBsnBwClearDataRequest(_bsnheader, decoder)
+	case 22:
+		return DecodeBsnBwClearDataReply(_bsnheader, decoder)
+	case 23:
+		return DecodeBsnBwEnableSetReply(_bsnheader, decoder)
+	case 25:
+		return DecodeBsnSetPktinSuppressionReply(_bsnheader, decoder)
+	case 26:
+		return DecodeBsnVirtualPortRemoveReply(_bsnheader, decoder)
+	case 31:
+		return DecodeBsnPduTxRequest(_bsnheader, decoder)
+	case 32:
+		return DecodeBsnPduTxReply(_bsnheader, decoder)
+	case 33:
+		return DecodeBsnPduRxRequest(_bsnheader, decoder)
+	case 34:
+		return DecodeBsnPduRxReply(_bsnheader, decoder)
+	case 35:
+		return DecodeBsnPduRxTimeout(_bsnheader, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'BsnHeader'", _bsnheader.Subtype)
+	}
+}
+
+func NewBsnHeader(_subtype uint32) *BsnHeader {
+	obj := &BsnHeader{
+		Experimenter: NewExperimenter(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type BsnBwClearDataReply struct {
+	*BsnHeader
+	Status uint32
+}
+
+type IBsnBwClearDataReply interface {
+	IBsnHeader
+	GetStatus() uint32
+}
+
+func (self *BsnBwClearDataReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnBwClearDataReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnBwClearDataReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwClearDataReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwClearDataReply, error) {
+	_bsnbwcleardatareply := &BsnBwClearDataReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnBwClearDataReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnbwcleardatareply.Status = uint32(decoder.ReadUint32())
+	return _bsnbwcleardatareply, nil
+}
+
+func NewBsnBwClearDataReply() *BsnBwClearDataReply {
+	obj := &BsnBwClearDataReply{
+		BsnHeader: NewBsnHeader(22),
+	}
+	return obj
+}
+
+type BsnBwClearDataRequest struct {
+	*BsnHeader
+}
+
+type IBsnBwClearDataRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnBwClearDataRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwClearDataRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwClearDataRequest, error) {
+	_bsnbwcleardatarequest := &BsnBwClearDataRequest{BsnHeader: parent}
+	return _bsnbwcleardatarequest, nil
+}
+
+func NewBsnBwClearDataRequest() *BsnBwClearDataRequest {
+	obj := &BsnBwClearDataRequest{
+		BsnHeader: NewBsnHeader(21),
+	}
+	return obj
+}
+
+type BsnBwEnableGetReply struct {
+	*BsnHeader
+	Enabled uint32
+}
+
+type IBsnBwEnableGetReply interface {
+	IBsnHeader
+	GetEnabled() uint32
+}
+
+func (self *BsnBwEnableGetReply) GetEnabled() uint32 {
+	return self.Enabled
+}
+
+func (self *BsnBwEnableGetReply) SetEnabled(v uint32) {
+	self.Enabled = v
+}
+
+func (self *BsnBwEnableGetReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Enabled))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwEnableGetReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwEnableGetReply, error) {
+	_bsnbwenablegetreply := &BsnBwEnableGetReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnBwEnableGetReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnbwenablegetreply.Enabled = uint32(decoder.ReadUint32())
+	return _bsnbwenablegetreply, nil
+}
+
+func NewBsnBwEnableGetReply() *BsnBwEnableGetReply {
+	obj := &BsnBwEnableGetReply{
+		BsnHeader: NewBsnHeader(20),
+	}
+	return obj
+}
+
+type BsnBwEnableGetRequest struct {
+	*BsnHeader
+}
+
+type IBsnBwEnableGetRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnBwEnableGetRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwEnableGetRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwEnableGetRequest, error) {
+	_bsnbwenablegetrequest := &BsnBwEnableGetRequest{BsnHeader: parent}
+	return _bsnbwenablegetrequest, nil
+}
+
+func NewBsnBwEnableGetRequest() *BsnBwEnableGetRequest {
+	obj := &BsnBwEnableGetRequest{
+		BsnHeader: NewBsnHeader(19),
+	}
+	return obj
+}
+
+type BsnBwEnableSetReply struct {
+	*BsnHeader
+	Enable uint32
+	Status uint32
+}
+
+type IBsnBwEnableSetReply interface {
+	IBsnHeader
+	GetEnable() uint32
+	GetStatus() uint32
+}
+
+func (self *BsnBwEnableSetReply) GetEnable() uint32 {
+	return self.Enable
+}
+
+func (self *BsnBwEnableSetReply) SetEnable(v uint32) {
+	self.Enable = v
+}
+
+func (self *BsnBwEnableSetReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnBwEnableSetReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnBwEnableSetReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Enable))
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwEnableSetReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwEnableSetReply, error) {
+	_bsnbwenablesetreply := &BsnBwEnableSetReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnBwEnableSetReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnbwenablesetreply.Enable = uint32(decoder.ReadUint32())
+	_bsnbwenablesetreply.Status = uint32(decoder.ReadUint32())
+	return _bsnbwenablesetreply, nil
+}
+
+func NewBsnBwEnableSetReply() *BsnBwEnableSetReply {
+	obj := &BsnBwEnableSetReply{
+		BsnHeader: NewBsnHeader(23),
+	}
+	return obj
+}
+
+type BsnBwEnableSetRequest struct {
+	*BsnHeader
+	Enable uint32
+}
+
+type IBsnBwEnableSetRequest interface {
+	IBsnHeader
+	GetEnable() uint32
+}
+
+func (self *BsnBwEnableSetRequest) GetEnable() uint32 {
+	return self.Enable
+}
+
+func (self *BsnBwEnableSetRequest) SetEnable(v uint32) {
+	self.Enable = v
+}
+
+func (self *BsnBwEnableSetRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Enable))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwEnableSetRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwEnableSetRequest, error) {
+	_bsnbwenablesetrequest := &BsnBwEnableSetRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnBwEnableSetRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnbwenablesetrequest.Enable = uint32(decoder.ReadUint32())
+	return _bsnbwenablesetrequest, nil
+}
+
+func NewBsnBwEnableSetRequest() *BsnBwEnableSetRequest {
+	obj := &BsnBwEnableSetRequest{
+		BsnHeader: NewBsnHeader(18),
+	}
+	return obj
+}
+
+type BsnGetInterfacesReply struct {
+	*BsnHeader
+	Interfaces []*BsnInterface
+}
+
+type IBsnGetInterfacesReply interface {
+	IBsnHeader
+	GetInterfaces() []*BsnInterface
+}
+
+func (self *BsnGetInterfacesReply) GetInterfaces() []*BsnInterface {
+	return self.Interfaces
+}
+
+func (self *BsnGetInterfacesReply) SetInterfaces(v []*BsnInterface) {
+	self.Interfaces = v
+}
+
+func (self *BsnGetInterfacesReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	for _, obj := range self.Interfaces {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetInterfacesReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetInterfacesReply, error) {
+	_bsngetinterfacesreply := &BsnGetInterfacesReply{BsnHeader: parent}
+
+	for decoder.Length() >= 32 {
+		item, err := DecodeBsnInterface(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngetinterfacesreply.Interfaces = append(_bsngetinterfacesreply.Interfaces, item)
+		}
+	}
+	return _bsngetinterfacesreply, nil
+}
+
+func NewBsnGetInterfacesReply() *BsnGetInterfacesReply {
+	obj := &BsnGetInterfacesReply{
+		BsnHeader: NewBsnHeader(10),
+	}
+	return obj
+}
+
+type BsnGetInterfacesRequest struct {
+	*BsnHeader
+}
+
+type IBsnGetInterfacesRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnGetInterfacesRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetInterfacesRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetInterfacesRequest, error) {
+	_bsngetinterfacesrequest := &BsnGetInterfacesRequest{BsnHeader: parent}
+	return _bsngetinterfacesrequest, nil
+}
+
+func NewBsnGetInterfacesRequest() *BsnGetInterfacesRequest {
+	obj := &BsnGetInterfacesRequest{
+		BsnHeader: NewBsnHeader(9),
+	}
+	return obj
+}
+
+type BsnGetMirroringReply struct {
+	*BsnHeader
+	ReportMirrorPorts uint8
+}
+
+type IBsnGetMirroringReply interface {
+	IBsnHeader
+	GetReportMirrorPorts() uint8
+}
+
+func (self *BsnGetMirroringReply) GetReportMirrorPorts() uint8 {
+	return self.ReportMirrorPorts
+}
+
+func (self *BsnGetMirroringReply) SetReportMirrorPorts(v uint8) {
+	self.ReportMirrorPorts = v
+}
+
+func (self *BsnGetMirroringReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.ReportMirrorPorts))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetMirroringReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetMirroringReply, error) {
+	_bsngetmirroringreply := &BsnGetMirroringReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnGetMirroringReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsngetmirroringreply.ReportMirrorPorts = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _bsngetmirroringreply, nil
+}
+
+func NewBsnGetMirroringReply() *BsnGetMirroringReply {
+	obj := &BsnGetMirroringReply{
+		BsnHeader: NewBsnHeader(5),
+	}
+	return obj
+}
+
+type BsnGetMirroringRequest struct {
+	*BsnHeader
+	ReportMirrorPorts uint8
+}
+
+type IBsnGetMirroringRequest interface {
+	IBsnHeader
+	GetReportMirrorPorts() uint8
+}
+
+func (self *BsnGetMirroringRequest) GetReportMirrorPorts() uint8 {
+	return self.ReportMirrorPorts
+}
+
+func (self *BsnGetMirroringRequest) SetReportMirrorPorts(v uint8) {
+	self.ReportMirrorPorts = v
+}
+
+func (self *BsnGetMirroringRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.ReportMirrorPorts))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetMirroringRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetMirroringRequest, error) {
+	_bsngetmirroringrequest := &BsnGetMirroringRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnGetMirroringRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsngetmirroringrequest.ReportMirrorPorts = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _bsngetmirroringrequest, nil
+}
+
+func NewBsnGetMirroringRequest() *BsnGetMirroringRequest {
+	obj := &BsnGetMirroringRequest{
+		BsnHeader: NewBsnHeader(4),
+	}
+	return obj
+}
+
+type BsnPduRxReply struct {
+	*BsnHeader
+	Status  uint32
+	PortNo  Port
+	SlotNum uint8
+}
+
+type IBsnPduRxReply interface {
+	IBsnHeader
+	GetStatus() uint32
+	GetPortNo() Port
+	GetSlotNum() uint8
+}
+
+func (self *BsnPduRxReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnPduRxReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnPduRxReply) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnPduRxReply) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnPduRxReply) GetSlotNum() uint8 {
+	return self.SlotNum
+}
+
+func (self *BsnPduRxReply) SetSlotNum(v uint8) {
+	self.SlotNum = v
+}
+
+func (self *BsnPduRxReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	self.PortNo.Serialize(encoder)
+	encoder.PutUint8(uint8(self.SlotNum))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnPduRxReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnPduRxReply, error) {
+	_bsnpdurxreply := &BsnPduRxReply{BsnHeader: parent}
+	if decoder.Length() < 9 {
+		return nil, fmt.Errorf("BsnPduRxReply packet too short: %d < 9", decoder.Length())
+	}
+	_bsnpdurxreply.Status = uint32(decoder.ReadUint32())
+	_bsnpdurxreply.PortNo.Decode(decoder)
+	_bsnpdurxreply.SlotNum = uint8(decoder.ReadByte())
+	return _bsnpdurxreply, nil
+}
+
+func NewBsnPduRxReply() *BsnPduRxReply {
+	obj := &BsnPduRxReply{
+		BsnHeader: NewBsnHeader(34),
+	}
+	return obj
+}
+
+type BsnPduRxRequest struct {
+	*BsnHeader
+	TimeoutMs uint32
+	PortNo    Port
+	SlotNum   uint8
+	Data      []byte
+}
+
+type IBsnPduRxRequest interface {
+	IBsnHeader
+	GetTimeoutMs() uint32
+	GetPortNo() Port
+	GetSlotNum() uint8
+	GetData() []byte
+}
+
+func (self *BsnPduRxRequest) GetTimeoutMs() uint32 {
+	return self.TimeoutMs
+}
+
+func (self *BsnPduRxRequest) SetTimeoutMs(v uint32) {
+	self.TimeoutMs = v
+}
+
+func (self *BsnPduRxRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnPduRxRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnPduRxRequest) GetSlotNum() uint8 {
+	return self.SlotNum
+}
+
+func (self *BsnPduRxRequest) SetSlotNum(v uint8) {
+	self.SlotNum = v
+}
+
+func (self *BsnPduRxRequest) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnPduRxRequest) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnPduRxRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.TimeoutMs))
+	self.PortNo.Serialize(encoder)
+	encoder.PutUint8(uint8(self.SlotNum))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnPduRxRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnPduRxRequest, error) {
+	_bsnpdurxrequest := &BsnPduRxRequest{BsnHeader: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("BsnPduRxRequest packet too short: %d < 12", decoder.Length())
+	}
+	_bsnpdurxrequest.TimeoutMs = uint32(decoder.ReadUint32())
+	_bsnpdurxrequest.PortNo.Decode(decoder)
+	_bsnpdurxrequest.SlotNum = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_bsnpdurxrequest.Data = decoder.Read(int(decoder.Length()))
+	return _bsnpdurxrequest, nil
+}
+
+func NewBsnPduRxRequest() *BsnPduRxRequest {
+	obj := &BsnPduRxRequest{
+		BsnHeader: NewBsnHeader(33),
+	}
+	return obj
+}
+
+type BsnPduRxTimeout struct {
+	*BsnHeader
+	PortNo  Port
+	SlotNum uint8
+}
+
+type IBsnPduRxTimeout interface {
+	IBsnHeader
+	GetPortNo() Port
+	GetSlotNum() uint8
+}
+
+func (self *BsnPduRxTimeout) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnPduRxTimeout) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnPduRxTimeout) GetSlotNum() uint8 {
+	return self.SlotNum
+}
+
+func (self *BsnPduRxTimeout) SetSlotNum(v uint8) {
+	self.SlotNum = v
+}
+
+func (self *BsnPduRxTimeout) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.PortNo.Serialize(encoder)
+	encoder.PutUint8(uint8(self.SlotNum))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnPduRxTimeout(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnPduRxTimeout, error) {
+	_bsnpdurxtimeout := &BsnPduRxTimeout{BsnHeader: parent}
+	if decoder.Length() < 5 {
+		return nil, fmt.Errorf("BsnPduRxTimeout packet too short: %d < 5", decoder.Length())
+	}
+	_bsnpdurxtimeout.PortNo.Decode(decoder)
+	_bsnpdurxtimeout.SlotNum = uint8(decoder.ReadByte())
+	return _bsnpdurxtimeout, nil
+}
+
+func NewBsnPduRxTimeout() *BsnPduRxTimeout {
+	obj := &BsnPduRxTimeout{
+		BsnHeader: NewBsnHeader(35),
+	}
+	return obj
+}
+
+type BsnPduTxReply struct {
+	*BsnHeader
+	Status  uint32
+	PortNo  Port
+	SlotNum uint8
+}
+
+type IBsnPduTxReply interface {
+	IBsnHeader
+	GetStatus() uint32
+	GetPortNo() Port
+	GetSlotNum() uint8
+}
+
+func (self *BsnPduTxReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnPduTxReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnPduTxReply) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnPduTxReply) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnPduTxReply) GetSlotNum() uint8 {
+	return self.SlotNum
+}
+
+func (self *BsnPduTxReply) SetSlotNum(v uint8) {
+	self.SlotNum = v
+}
+
+func (self *BsnPduTxReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	self.PortNo.Serialize(encoder)
+	encoder.PutUint8(uint8(self.SlotNum))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnPduTxReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnPduTxReply, error) {
+	_bsnpdutxreply := &BsnPduTxReply{BsnHeader: parent}
+	if decoder.Length() < 9 {
+		return nil, fmt.Errorf("BsnPduTxReply packet too short: %d < 9", decoder.Length())
+	}
+	_bsnpdutxreply.Status = uint32(decoder.ReadUint32())
+	_bsnpdutxreply.PortNo.Decode(decoder)
+	_bsnpdutxreply.SlotNum = uint8(decoder.ReadByte())
+	return _bsnpdutxreply, nil
+}
+
+func NewBsnPduTxReply() *BsnPduTxReply {
+	obj := &BsnPduTxReply{
+		BsnHeader: NewBsnHeader(32),
+	}
+	return obj
+}
+
+type BsnPduTxRequest struct {
+	*BsnHeader
+	TxIntervalMs uint32
+	PortNo       Port
+	SlotNum      uint8
+	Data         []byte
+}
+
+type IBsnPduTxRequest interface {
+	IBsnHeader
+	GetTxIntervalMs() uint32
+	GetPortNo() Port
+	GetSlotNum() uint8
+	GetData() []byte
+}
+
+func (self *BsnPduTxRequest) GetTxIntervalMs() uint32 {
+	return self.TxIntervalMs
+}
+
+func (self *BsnPduTxRequest) SetTxIntervalMs(v uint32) {
+	self.TxIntervalMs = v
+}
+
+func (self *BsnPduTxRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnPduTxRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnPduTxRequest) GetSlotNum() uint8 {
+	return self.SlotNum
+}
+
+func (self *BsnPduTxRequest) SetSlotNum(v uint8) {
+	self.SlotNum = v
+}
+
+func (self *BsnPduTxRequest) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnPduTxRequest) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnPduTxRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.TxIntervalMs))
+	self.PortNo.Serialize(encoder)
+	encoder.PutUint8(uint8(self.SlotNum))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnPduTxRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnPduTxRequest, error) {
+	_bsnpdutxrequest := &BsnPduTxRequest{BsnHeader: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("BsnPduTxRequest packet too short: %d < 12", decoder.Length())
+	}
+	_bsnpdutxrequest.TxIntervalMs = uint32(decoder.ReadUint32())
+	_bsnpdutxrequest.PortNo.Decode(decoder)
+	_bsnpdutxrequest.SlotNum = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_bsnpdutxrequest.Data = decoder.Read(int(decoder.Length()))
+	return _bsnpdutxrequest, nil
+}
+
+func NewBsnPduTxRequest() *BsnPduTxRequest {
+	obj := &BsnPduTxRequest{
+		BsnHeader: NewBsnHeader(31),
+	}
+	return obj
+}
+
+type BsnSetMirroring struct {
+	*BsnHeader
+	ReportMirrorPorts uint8
+}
+
+type IBsnSetMirroring interface {
+	IBsnHeader
+	GetReportMirrorPorts() uint8
+}
+
+func (self *BsnSetMirroring) GetReportMirrorPorts() uint8 {
+	return self.ReportMirrorPorts
+}
+
+func (self *BsnSetMirroring) SetReportMirrorPorts(v uint8) {
+	self.ReportMirrorPorts = v
+}
+
+func (self *BsnSetMirroring) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.ReportMirrorPorts))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetMirroring(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetMirroring, error) {
+	_bsnsetmirroring := &BsnSetMirroring{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnSetMirroring packet too short: %d < 4", decoder.Length())
+	}
+	_bsnsetmirroring.ReportMirrorPorts = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _bsnsetmirroring, nil
+}
+
+func NewBsnSetMirroring() *BsnSetMirroring {
+	obj := &BsnSetMirroring{
+		BsnHeader: NewBsnHeader(3),
+	}
+	return obj
+}
+
+type BsnSetPktinSuppressionReply struct {
+	*BsnHeader
+	Status uint32
+}
+
+type IBsnSetPktinSuppressionReply interface {
+	IBsnHeader
+	GetStatus() uint32
+}
+
+func (self *BsnSetPktinSuppressionReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnSetPktinSuppressionReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnSetPktinSuppressionReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetPktinSuppressionReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetPktinSuppressionReply, error) {
+	_bsnsetpktinsuppressionreply := &BsnSetPktinSuppressionReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnSetPktinSuppressionReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnsetpktinsuppressionreply.Status = uint32(decoder.ReadUint32())
+	return _bsnsetpktinsuppressionreply, nil
+}
+
+func NewBsnSetPktinSuppressionReply() *BsnSetPktinSuppressionReply {
+	obj := &BsnSetPktinSuppressionReply{
+		BsnHeader: NewBsnHeader(25),
+	}
+	return obj
+}
+
+type BsnSetPktinSuppressionRequest struct {
+	*BsnHeader
+	Enabled     uint8
+	IdleTimeout uint16
+	HardTimeout uint16
+	Priority    uint16
+	Cookie      uint64
+}
+
+type IBsnSetPktinSuppressionRequest interface {
+	IBsnHeader
+	GetEnabled() uint8
+	GetIdleTimeout() uint16
+	GetHardTimeout() uint16
+	GetPriority() uint16
+	GetCookie() uint64
+}
+
+func (self *BsnSetPktinSuppressionRequest) GetEnabled() uint8 {
+	return self.Enabled
+}
+
+func (self *BsnSetPktinSuppressionRequest) SetEnabled(v uint8) {
+	self.Enabled = v
+}
+
+func (self *BsnSetPktinSuppressionRequest) GetIdleTimeout() uint16 {
+	return self.IdleTimeout
+}
+
+func (self *BsnSetPktinSuppressionRequest) SetIdleTimeout(v uint16) {
+	self.IdleTimeout = v
+}
+
+func (self *BsnSetPktinSuppressionRequest) GetHardTimeout() uint16 {
+	return self.HardTimeout
+}
+
+func (self *BsnSetPktinSuppressionRequest) SetHardTimeout(v uint16) {
+	self.HardTimeout = v
+}
+
+func (self *BsnSetPktinSuppressionRequest) GetPriority() uint16 {
+	return self.Priority
+}
+
+func (self *BsnSetPktinSuppressionRequest) SetPriority(v uint16) {
+	self.Priority = v
+}
+
+func (self *BsnSetPktinSuppressionRequest) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *BsnSetPktinSuppressionRequest) SetCookie(v uint64) {
+	self.Cookie = v
+}
+
+func (self *BsnSetPktinSuppressionRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Enabled))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint16(uint16(self.IdleTimeout))
+	encoder.PutUint16(uint16(self.HardTimeout))
+	encoder.PutUint16(uint16(self.Priority))
+	encoder.PutUint64(uint64(self.Cookie))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetPktinSuppressionRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetPktinSuppressionRequest, error) {
+	_bsnsetpktinsuppressionrequest := &BsnSetPktinSuppressionRequest{BsnHeader: parent}
+	if decoder.Length() < 16 {
+		return nil, fmt.Errorf("BsnSetPktinSuppressionRequest packet too short: %d < 16", decoder.Length())
+	}
+	_bsnsetpktinsuppressionrequest.Enabled = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_bsnsetpktinsuppressionrequest.IdleTimeout = uint16(decoder.ReadUint16())
+	_bsnsetpktinsuppressionrequest.HardTimeout = uint16(decoder.ReadUint16())
+	_bsnsetpktinsuppressionrequest.Priority = uint16(decoder.ReadUint16())
+	_bsnsetpktinsuppressionrequest.Cookie = uint64(decoder.ReadUint64())
+	return _bsnsetpktinsuppressionrequest, nil
+}
+
+func NewBsnSetPktinSuppressionRequest() *BsnSetPktinSuppressionRequest {
+	obj := &BsnSetPktinSuppressionRequest{
+		BsnHeader: NewBsnHeader(11),
+	}
+	return obj
+}
+
+type ExperimenterStatsReply struct {
+	*StatsReply
+	Experimenter uint32
+}
+
+type IExperimenterStatsReply interface {
+	IStatsReply
+	GetExperimenter() uint32
+}
+
+func (self *ExperimenterStatsReply) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *ExperimenterStatsReply) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *ExperimenterStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint32(uint32(self.Experimenter))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+
+	return nil
+}
+
+func DecodeExperimenterStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (IExperimenterStatsReply, error) {
+	_experimenterstatsreply := &ExperimenterStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ExperimenterStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	_experimenterstatsreply.Experimenter = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+
+	switch _experimenterstatsreply.Experimenter {
+	case 8992:
+		return DecodeNiciraStatsReply(_experimenterstatsreply, decoder)
+	case 6035143:
+		return DecodeBsnStatsReply(_experimenterstatsreply, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'ExperimenterStatsReply'", _experimenterstatsreply.Experimenter)
+	}
+}
+
+func NewExperimenterStatsReply(_experimenter uint32) *ExperimenterStatsReply {
+	obj := &ExperimenterStatsReply{
+		StatsReply: NewStatsReply(65535),
+	}
+	obj.Experimenter = _experimenter
+	return obj
+}
+
+type BsnStatsReply struct {
+	*ExperimenterStatsReply
+	Subtype uint32
+}
+
+type IBsnStatsReply interface {
+	IExperimenterStatsReply
+	GetSubtype() uint32
+}
+
+func (self *BsnStatsReply) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *BsnStatsReply) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *BsnStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeBsnStatsReply(parent *ExperimenterStatsReply, decoder *goloxi.Decoder) (IBsnStatsReply, error) {
+	_bsnstatsreply := &BsnStatsReply{ExperimenterStatsReply: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("BsnStatsReply packet too short: %d < 12", decoder.Length())
+	}
+	decoder.Skip(4)
+	_bsnstatsreply.Subtype = uint32(decoder.ReadUint32())
+	return _bsnstatsreply, nil
+}
+
+func NewBsnStatsReply(_subtype uint32) *BsnStatsReply {
+	obj := &BsnStatsReply{
+		ExperimenterStatsReply: NewExperimenterStatsReply(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type ExperimenterStatsRequest struct {
+	*StatsRequest
+	Experimenter uint32
+}
+
+type IExperimenterStatsRequest interface {
+	IStatsRequest
+	GetExperimenter() uint32
+}
+
+func (self *ExperimenterStatsRequest) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *ExperimenterStatsRequest) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *ExperimenterStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint32(uint32(self.Experimenter))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+
+	return nil
+}
+
+func DecodeExperimenterStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (IExperimenterStatsRequest, error) {
+	_experimenterstatsrequest := &ExperimenterStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ExperimenterStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	_experimenterstatsrequest.Experimenter = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+
+	switch _experimenterstatsrequest.Experimenter {
+	case 8992:
+		return DecodeNiciraFlowStatsRequest(_experimenterstatsrequest, decoder)
+	case 6035143:
+		return DecodeBsnStatsRequest(_experimenterstatsrequest, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'ExperimenterStatsRequest'", _experimenterstatsrequest.Experimenter)
+	}
+}
+
+func NewExperimenterStatsRequest(_experimenter uint32) *ExperimenterStatsRequest {
+	obj := &ExperimenterStatsRequest{
+		StatsRequest: NewStatsRequest(65535),
+	}
+	obj.Experimenter = _experimenter
+	return obj
+}
+
+type BsnStatsRequest struct {
+	*ExperimenterStatsRequest
+	Subtype uint32
+}
+
+type IBsnStatsRequest interface {
+	IExperimenterStatsRequest
+	GetSubtype() uint32
+}
+
+func (self *BsnStatsRequest) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *BsnStatsRequest) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *BsnStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeBsnStatsRequest(parent *ExperimenterStatsRequest, decoder *goloxi.Decoder) (IBsnStatsRequest, error) {
+	_bsnstatsrequest := &BsnStatsRequest{ExperimenterStatsRequest: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("BsnStatsRequest packet too short: %d < 12", decoder.Length())
+	}
+	decoder.Skip(4)
+	_bsnstatsrequest.Subtype = uint32(decoder.ReadUint32())
+	return _bsnstatsrequest, nil
+}
+
+func NewBsnStatsRequest(_subtype uint32) *BsnStatsRequest {
+	obj := &BsnStatsRequest{
+		ExperimenterStatsRequest: NewExperimenterStatsRequest(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type BsnVirtualPortCreateReply struct {
+	*BsnHeader
+	Status  uint32
+	VportNo uint32
+}
+
+type IBsnVirtualPortCreateReply interface {
+	IBsnHeader
+	GetStatus() uint32
+	GetVportNo() uint32
+}
+
+func (self *BsnVirtualPortCreateReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnVirtualPortCreateReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnVirtualPortCreateReply) GetVportNo() uint32 {
+	return self.VportNo
+}
+
+func (self *BsnVirtualPortCreateReply) SetVportNo(v uint32) {
+	self.VportNo = v
+}
+
+func (self *BsnVirtualPortCreateReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	encoder.PutUint32(uint32(self.VportNo))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVirtualPortCreateReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVirtualPortCreateReply, error) {
+	_bsnvirtualportcreatereply := &BsnVirtualPortCreateReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnVirtualPortCreateReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnvirtualportcreatereply.Status = uint32(decoder.ReadUint32())
+	_bsnvirtualportcreatereply.VportNo = uint32(decoder.ReadUint32())
+	return _bsnvirtualportcreatereply, nil
+}
+
+func NewBsnVirtualPortCreateReply() *BsnVirtualPortCreateReply {
+	obj := &BsnVirtualPortCreateReply{
+		BsnHeader: NewBsnHeader(16),
+	}
+	return obj
+}
+
+type BsnVirtualPortCreateRequest struct {
+	*BsnHeader
+	Vport BSNVport
+}
+
+type IBsnVirtualPortCreateRequest interface {
+	IBsnHeader
+	GetVport() BSNVport
+}
+
+func (self *BsnVirtualPortCreateRequest) GetVport() BSNVport {
+	return self.Vport
+}
+
+func (self *BsnVirtualPortCreateRequest) SetVport(v BSNVport) {
+	self.Vport = v
+}
+
+func (self *BsnVirtualPortCreateRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	if err := self.Vport.Serialize(encoder); err != nil {
+		return err
+	}
+
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVirtualPortCreateRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVirtualPortCreateRequest, error) {
+	_bsnvirtualportcreaterequest := &BsnVirtualPortCreateRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnVirtualPortCreateRequest packet too short: %d < 4", decoder.Length())
+	}
+	if err := _bsnvirtualportcreaterequest.Vport.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _bsnvirtualportcreaterequest, nil
+}
+
+func NewBsnVirtualPortCreateRequest() *BsnVirtualPortCreateRequest {
+	obj := &BsnVirtualPortCreateRequest{
+		BsnHeader: NewBsnHeader(15),
+	}
+	return obj
+}
+
+type BsnVirtualPortRemoveReply struct {
+	*BsnHeader
+	Status uint32
+}
+
+type IBsnVirtualPortRemoveReply interface {
+	IBsnHeader
+	GetStatus() uint32
+}
+
+func (self *BsnVirtualPortRemoveReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnVirtualPortRemoveReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnVirtualPortRemoveReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVirtualPortRemoveReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVirtualPortRemoveReply, error) {
+	_bsnvirtualportremovereply := &BsnVirtualPortRemoveReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnVirtualPortRemoveReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnvirtualportremovereply.Status = uint32(decoder.ReadUint32())
+	return _bsnvirtualportremovereply, nil
+}
+
+func NewBsnVirtualPortRemoveReply() *BsnVirtualPortRemoveReply {
+	obj := &BsnVirtualPortRemoveReply{
+		BsnHeader: NewBsnHeader(26),
+	}
+	return obj
+}
+
+type BsnVirtualPortRemoveRequest struct {
+	*BsnHeader
+	VportNo uint32
+}
+
+type IBsnVirtualPortRemoveRequest interface {
+	IBsnHeader
+	GetVportNo() uint32
+}
+
+func (self *BsnVirtualPortRemoveRequest) GetVportNo() uint32 {
+	return self.VportNo
+}
+
+func (self *BsnVirtualPortRemoveRequest) SetVportNo(v uint32) {
+	self.VportNo = v
+}
+
+func (self *BsnVirtualPortRemoveRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.VportNo))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVirtualPortRemoveRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVirtualPortRemoveRequest, error) {
+	_bsnvirtualportremoverequest := &BsnVirtualPortRemoveRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnVirtualPortRemoveRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnvirtualportremoverequest.VportNo = uint32(decoder.ReadUint32())
+	return _bsnvirtualportremoverequest, nil
+}
+
+func NewBsnVirtualPortRemoveRequest() *BsnVirtualPortRemoveRequest {
+	obj := &BsnVirtualPortRemoveRequest{
+		BsnHeader: NewBsnHeader(17),
+	}
+	return obj
+}
+
+type DescStatsReply struct {
+	*StatsReply
+	MfrDesc   string
+	HwDesc    string
+	SwDesc    string
+	SerialNum string
+	DpDesc    string
+}
+
+type IDescStatsReply interface {
+	IStatsReply
+	GetMfrDesc() string
+	GetHwDesc() string
+	GetSwDesc() string
+	GetSerialNum() string
+	GetDpDesc() string
+}
+
+func (self *DescStatsReply) GetMfrDesc() string {
+	return self.MfrDesc
+}
+
+func (self *DescStatsReply) SetMfrDesc(v string) {
+	self.MfrDesc = v
+}
+
+func (self *DescStatsReply) GetHwDesc() string {
+	return self.HwDesc
+}
+
+func (self *DescStatsReply) SetHwDesc(v string) {
+	self.HwDesc = v
+}
+
+func (self *DescStatsReply) GetSwDesc() string {
+	return self.SwDesc
+}
+
+func (self *DescStatsReply) SetSwDesc(v string) {
+	self.SwDesc = v
+}
+
+func (self *DescStatsReply) GetSerialNum() string {
+	return self.SerialNum
+}
+
+func (self *DescStatsReply) SetSerialNum(v string) {
+	self.SerialNum = v
+}
+
+func (self *DescStatsReply) GetDpDesc() string {
+	return self.DpDesc
+}
+
+func (self *DescStatsReply) SetDpDesc(v string) {
+	self.DpDesc = v
+}
+
+func (self *DescStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.Write([]byte(self.MfrDesc))
+	encoder.Write([]byte(self.HwDesc))
+	encoder.Write([]byte(self.SwDesc))
+	encoder.Write([]byte(self.SerialNum))
+	encoder.Write([]byte(self.DpDesc))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeDescStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*DescStatsReply, error) {
+	_descstatsreply := &DescStatsReply{StatsReply: parent}
+	if decoder.Length() < 1060 {
+		return nil, fmt.Errorf("DescStatsReply packet too short: %d < 1060", decoder.Length())
+	}
+	decoder.Skip(4)
+	_descstatsreply.MfrDesc = string(bytes.Trim(decoder.Read(256), "\x00"))
+	_descstatsreply.HwDesc = string(bytes.Trim(decoder.Read(256), "\x00"))
+	_descstatsreply.SwDesc = string(bytes.Trim(decoder.Read(256), "\x00"))
+	_descstatsreply.SerialNum = string(bytes.Trim(decoder.Read(32), "\x00"))
+	_descstatsreply.DpDesc = string(bytes.Trim(decoder.Read(256), "\x00"))
+	return _descstatsreply, nil
+}
+
+func NewDescStatsReply() *DescStatsReply {
+	obj := &DescStatsReply{
+		StatsReply: NewStatsReply(0),
+	}
+	return obj
+}
+
+type DescStatsRequest struct {
+	*StatsRequest
+}
+
+type IDescStatsRequest interface {
+	IStatsRequest
+}
+
+func (self *DescStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeDescStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*DescStatsRequest, error) {
+	_descstatsrequest := &DescStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("DescStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _descstatsrequest, nil
+}
+
+func NewDescStatsRequest() *DescStatsRequest {
+	obj := &DescStatsRequest{
+		StatsRequest: NewStatsRequest(0),
+	}
+	return obj
+}
+
+type EchoReply struct {
+	*Header
+	Data []byte
+}
+
+type IEchoReply interface {
+	IHeader
+	GetData() []byte
+}
+
+func (self *EchoReply) GetData() []byte {
+	return self.Data
+}
+
+func (self *EchoReply) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *EchoReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeEchoReply(parent *Header, decoder *goloxi.Decoder) (*EchoReply, error) {
+	_echoreply := &EchoReply{Header: parent}
+	_echoreply.Data = decoder.Read(int(decoder.Length()))
+	return _echoreply, nil
+}
+
+func NewEchoReply() *EchoReply {
+	obj := &EchoReply{
+		Header: NewHeader(3),
+	}
+	return obj
+}
+
+type EchoRequest struct {
+	*Header
+	Data []byte
+}
+
+type IEchoRequest interface {
+	IHeader
+	GetData() []byte
+}
+
+func (self *EchoRequest) GetData() []byte {
+	return self.Data
+}
+
+func (self *EchoRequest) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *EchoRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeEchoRequest(parent *Header, decoder *goloxi.Decoder) (*EchoRequest, error) {
+	_echorequest := &EchoRequest{Header: parent}
+	_echorequest.Data = decoder.Read(int(decoder.Length()))
+	return _echorequest, nil
+}
+
+func NewEchoRequest() *EchoRequest {
+	obj := &EchoRequest{
+		Header: NewHeader(2),
+	}
+	return obj
+}
+
+type FeaturesReply struct {
+	*Header
+	DatapathId   uint64
+	NBuffers     uint32
+	NTables      uint8
+	Capabilities Capabilities
+	Reserved     uint32
+	Ports        []*PortDesc
+}
+
+type IFeaturesReply interface {
+	IHeader
+	GetDatapathId() uint64
+	GetNBuffers() uint32
+	GetNTables() uint8
+	GetCapabilities() Capabilities
+	GetReserved() uint32
+	GetPorts() []*PortDesc
+}
+
+func (self *FeaturesReply) GetDatapathId() uint64 {
+	return self.DatapathId
+}
+
+func (self *FeaturesReply) SetDatapathId(v uint64) {
+	self.DatapathId = v
+}
+
+func (self *FeaturesReply) GetNBuffers() uint32 {
+	return self.NBuffers
+}
+
+func (self *FeaturesReply) SetNBuffers(v uint32) {
+	self.NBuffers = v
+}
+
+func (self *FeaturesReply) GetNTables() uint8 {
+	return self.NTables
+}
+
+func (self *FeaturesReply) SetNTables(v uint8) {
+	self.NTables = v
+}
+
+func (self *FeaturesReply) GetCapabilities() Capabilities {
+	return self.Capabilities
+}
+
+func (self *FeaturesReply) SetCapabilities(v Capabilities) {
+	self.Capabilities = v
+}
+
+func (self *FeaturesReply) GetReserved() uint32 {
+	return self.Reserved
+}
+
+func (self *FeaturesReply) SetReserved(v uint32) {
+	self.Reserved = v
+}
+
+func (self *FeaturesReply) GetPorts() []*PortDesc {
+	return self.Ports
+}
+
+func (self *FeaturesReply) SetPorts(v []*PortDesc) {
+	self.Ports = v
+}
+
+func (self *FeaturesReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.DatapathId))
+	encoder.PutUint32(uint32(self.NBuffers))
+	encoder.PutUint8(uint8(self.NTables))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.PutUint32(uint32(self.Capabilities))
+	encoder.PutUint32(uint32(self.Reserved))
+	for _, obj := range self.Ports {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFeaturesReply(parent *Header, decoder *goloxi.Decoder) (*FeaturesReply, error) {
+	_featuresreply := &FeaturesReply{Header: parent}
+	if decoder.Length() < 24 {
+		return nil, fmt.Errorf("FeaturesReply packet too short: %d < 24", decoder.Length())
+	}
+	_featuresreply.DatapathId = uint64(decoder.ReadUint64())
+	_featuresreply.NBuffers = uint32(decoder.ReadUint32())
+	_featuresreply.NTables = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_featuresreply.Capabilities = Capabilities(decoder.ReadUint32())
+	_featuresreply.Reserved = uint32(decoder.ReadUint32())
+
+	for decoder.Length() >= 64 {
+		item := &PortDesc{}
+		if err := item.Decode(decoder); err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_featuresreply.Ports = append(_featuresreply.Ports, item)
+		}
+	}
+	return _featuresreply, nil
+}
+
+func NewFeaturesReply() *FeaturesReply {
+	obj := &FeaturesReply{
+		Header: NewHeader(6),
+	}
+	return obj
+}
+
+type FeaturesRequest struct {
+	*Header
+}
+
+type IFeaturesRequest interface {
+	IHeader
+}
+
+func (self *FeaturesRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFeaturesRequest(parent *Header, decoder *goloxi.Decoder) (*FeaturesRequest, error) {
+	_featuresrequest := &FeaturesRequest{Header: parent}
+	return _featuresrequest, nil
+}
+
+func NewFeaturesRequest() *FeaturesRequest {
+	obj := &FeaturesRequest{
+		Header: NewHeader(5),
+	}
+	return obj
+}
+
+type FlowMod struct {
+	*Header
+	Cookie       uint64
+	CookieMask   uint64
+	TableId      uint8
+	Command      FmCmd
+	IdleTimeout  uint16
+	HardTimeout  uint16
+	Priority     uint16
+	BufferId     uint32
+	OutPort      Port
+	OutGroup     uint32
+	Flags        FlowModFlags
+	Match        Match
+	Instructions []IInstruction
+}
+
+type IFlowMod interface {
+	IHeader
+	GetCookie() uint64
+	GetCookieMask() uint64
+	GetTableId() uint8
+	GetCommand() FmCmd
+	GetIdleTimeout() uint16
+	GetHardTimeout() uint16
+	GetPriority() uint16
+	GetBufferId() uint32
+	GetOutPort() Port
+	GetOutGroup() uint32
+	GetFlags() FlowModFlags
+	GetMatch() Match
+	GetInstructions() []IInstruction
+}
+
+func (self *FlowMod) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *FlowMod) SetCookie(v uint64) {
+	self.Cookie = v
+}
+
+func (self *FlowMod) GetCookieMask() uint64 {
+	return self.CookieMask
+}
+
+func (self *FlowMod) SetCookieMask(v uint64) {
+	self.CookieMask = v
+}
+
+func (self *FlowMod) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *FlowMod) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *FlowMod) GetCommand() FmCmd {
+	return self.Command
+}
+
+func (self *FlowMod) SetCommand(v FmCmd) {
+	self.Command = v
+}
+
+func (self *FlowMod) GetIdleTimeout() uint16 {
+	return self.IdleTimeout
+}
+
+func (self *FlowMod) SetIdleTimeout(v uint16) {
+	self.IdleTimeout = v
+}
+
+func (self *FlowMod) GetHardTimeout() uint16 {
+	return self.HardTimeout
+}
+
+func (self *FlowMod) SetHardTimeout(v uint16) {
+	self.HardTimeout = v
+}
+
+func (self *FlowMod) GetPriority() uint16 {
+	return self.Priority
+}
+
+func (self *FlowMod) SetPriority(v uint16) {
+	self.Priority = v
+}
+
+func (self *FlowMod) GetBufferId() uint32 {
+	return self.BufferId
+}
+
+func (self *FlowMod) SetBufferId(v uint32) {
+	self.BufferId = v
+}
+
+func (self *FlowMod) GetOutPort() Port {
+	return self.OutPort
+}
+
+func (self *FlowMod) SetOutPort(v Port) {
+	self.OutPort = v
+}
+
+func (self *FlowMod) GetOutGroup() uint32 {
+	return self.OutGroup
+}
+
+func (self *FlowMod) SetOutGroup(v uint32) {
+	self.OutGroup = v
+}
+
+func (self *FlowMod) GetFlags() FlowModFlags {
+	return self.Flags
+}
+
+func (self *FlowMod) SetFlags(v FlowModFlags) {
+	self.Flags = v
+}
+
+func (self *FlowMod) GetMatch() Match {
+	return self.Match
+}
+
+func (self *FlowMod) SetMatch(v Match) {
+	self.Match = v
+}
+
+func (self *FlowMod) GetInstructions() []IInstruction {
+	return self.Instructions
+}
+
+func (self *FlowMod) SetInstructions(v []IInstruction) {
+	self.Instructions = v
+}
+
+func (self *FlowMod) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.Cookie))
+	encoder.PutUint64(uint64(self.CookieMask))
+	encoder.PutUint8(uint8(self.TableId))
+	self.Command.Serialize(encoder)
+	encoder.PutUint16(uint16(self.IdleTimeout))
+	encoder.PutUint16(uint16(self.HardTimeout))
+	encoder.PutUint16(uint16(self.Priority))
+	encoder.PutUint32(uint32(self.BufferId))
+	self.OutPort.Serialize(encoder)
+	encoder.PutUint32(uint32(self.OutGroup))
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	for _, obj := range self.Instructions {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func DecodeFlowMod(parent *Header, decoder *goloxi.Decoder) (IFlowMod, error) {
+	_flowmod := &FlowMod{Header: parent}
+	if decoder.Length() < 128 {
+		return nil, fmt.Errorf("FlowMod packet too short: %d < 128", decoder.Length())
+	}
+	_flowmod.Cookie = uint64(decoder.ReadUint64())
+	_flowmod.CookieMask = uint64(decoder.ReadUint64())
+	_flowmod.TableId = uint8(decoder.ReadByte())
+	_flowmod.Command.Decode(decoder)
+	_flowmod.IdleTimeout = uint16(decoder.ReadUint16())
+	_flowmod.HardTimeout = uint16(decoder.ReadUint16())
+	_flowmod.Priority = uint16(decoder.ReadUint16())
+	_flowmod.BufferId = uint32(decoder.ReadUint32())
+	_flowmod.OutPort.Decode(decoder)
+	_flowmod.OutGroup = uint32(decoder.ReadUint32())
+	_flowmod.Flags = FlowModFlags(decoder.ReadUint16())
+	decoder.Skip(2)
+	if err := _flowmod.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeInstruction(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_flowmod.Instructions = append(_flowmod.Instructions, item)
+		}
+	}
+
+	switch _flowmod.Command {
+	case 0:
+		return DecodeFlowAdd(_flowmod, decoder)
+	case 1:
+		return DecodeFlowModify(_flowmod, decoder)
+	case 2:
+		return DecodeFlowModifyStrict(_flowmod, decoder)
+	case 3:
+		return DecodeFlowDelete(_flowmod, decoder)
+	case 4:
+		return DecodeFlowDeleteStrict(_flowmod, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'FlowMod'", _flowmod.Command)
+	}
+}
+
+func NewFlowMod(__command FmCmd) *FlowMod {
+	obj := &FlowMod{
+		Header: NewHeader(14),
+	}
+	obj.Command = __command
+	return obj
+}
+
+type FlowAdd struct {
+	*FlowMod
+}
+
+type IFlowAdd interface {
+	IFlowMod
+}
+
+func (self *FlowAdd) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowAdd(parent *FlowMod, decoder *goloxi.Decoder) (*FlowAdd, error) {
+	_flowadd := &FlowAdd{FlowMod: parent}
+	return _flowadd, nil
+}
+
+func NewFlowAdd() *FlowAdd {
+	obj := &FlowAdd{
+		FlowMod: NewFlowMod(0),
+	}
+	return obj
+}
+
+type FlowDelete struct {
+	*FlowMod
+}
+
+type IFlowDelete interface {
+	IFlowMod
+}
+
+func (self *FlowDelete) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowDelete(parent *FlowMod, decoder *goloxi.Decoder) (*FlowDelete, error) {
+	_flowdelete := &FlowDelete{FlowMod: parent}
+	return _flowdelete, nil
+}
+
+func NewFlowDelete() *FlowDelete {
+	obj := &FlowDelete{
+		FlowMod: NewFlowMod(3),
+	}
+	return obj
+}
+
+type FlowDeleteStrict struct {
+	*FlowMod
+}
+
+type IFlowDeleteStrict interface {
+	IFlowMod
+}
+
+func (self *FlowDeleteStrict) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowDeleteStrict(parent *FlowMod, decoder *goloxi.Decoder) (*FlowDeleteStrict, error) {
+	_flowdeletestrict := &FlowDeleteStrict{FlowMod: parent}
+	return _flowdeletestrict, nil
+}
+
+func NewFlowDeleteStrict() *FlowDeleteStrict {
+	obj := &FlowDeleteStrict{
+		FlowMod: NewFlowMod(4),
+	}
+	return obj
+}
+
+type FlowModFailedErrorMsg struct {
+	*ErrorMsg
+	Code FlowModFailedCode
+	Data []byte
+}
+
+type IFlowModFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() FlowModFailedCode
+	GetData() []byte
+}
+
+func (self *FlowModFailedErrorMsg) GetCode() FlowModFailedCode {
+	return self.Code
+}
+
+func (self *FlowModFailedErrorMsg) SetCode(v FlowModFailedCode) {
+	self.Code = v
+}
+
+func (self *FlowModFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *FlowModFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *FlowModFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowModFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*FlowModFailedErrorMsg, error) {
+	_flowmodfailederrormsg := &FlowModFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("FlowModFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_flowmodfailederrormsg.Code = FlowModFailedCode(decoder.ReadUint16())
+	_flowmodfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _flowmodfailederrormsg, nil
+}
+
+func NewFlowModFailedErrorMsg() *FlowModFailedErrorMsg {
+	obj := &FlowModFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(5),
+	}
+	return obj
+}
+
+type FlowModify struct {
+	*FlowMod
+}
+
+type IFlowModify interface {
+	IFlowMod
+}
+
+func (self *FlowModify) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowModify(parent *FlowMod, decoder *goloxi.Decoder) (*FlowModify, error) {
+	_flowmodify := &FlowModify{FlowMod: parent}
+	return _flowmodify, nil
+}
+
+func NewFlowModify() *FlowModify {
+	obj := &FlowModify{
+		FlowMod: NewFlowMod(1),
+	}
+	return obj
+}
+
+type FlowModifyStrict struct {
+	*FlowMod
+}
+
+type IFlowModifyStrict interface {
+	IFlowMod
+}
+
+func (self *FlowModifyStrict) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowModifyStrict(parent *FlowMod, decoder *goloxi.Decoder) (*FlowModifyStrict, error) {
+	_flowmodifystrict := &FlowModifyStrict{FlowMod: parent}
+	return _flowmodifystrict, nil
+}
+
+func NewFlowModifyStrict() *FlowModifyStrict {
+	obj := &FlowModifyStrict{
+		FlowMod: NewFlowMod(2),
+	}
+	return obj
+}
+
+type FlowRemoved struct {
+	*Header
+	Cookie       uint64
+	Priority     uint16
+	Reason       FlowRemovedReason
+	TableId      uint8
+	DurationSec  uint32
+	DurationNsec uint32
+	IdleTimeout  uint16
+	PacketCount  uint64
+	ByteCount    uint64
+	Match        Match
+}
+
+type IFlowRemoved interface {
+	IHeader
+	GetCookie() uint64
+	GetPriority() uint16
+	GetReason() FlowRemovedReason
+	GetTableId() uint8
+	GetDurationSec() uint32
+	GetDurationNsec() uint32
+	GetIdleTimeout() uint16
+	GetPacketCount() uint64
+	GetByteCount() uint64
+	GetMatch() Match
+}
+
+func (self *FlowRemoved) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *FlowRemoved) SetCookie(v uint64) {
+	self.Cookie = v
+}
+
+func (self *FlowRemoved) GetPriority() uint16 {
+	return self.Priority
+}
+
+func (self *FlowRemoved) SetPriority(v uint16) {
+	self.Priority = v
+}
+
+func (self *FlowRemoved) GetReason() FlowRemovedReason {
+	return self.Reason
+}
+
+func (self *FlowRemoved) SetReason(v FlowRemovedReason) {
+	self.Reason = v
+}
+
+func (self *FlowRemoved) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *FlowRemoved) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *FlowRemoved) GetDurationSec() uint32 {
+	return self.DurationSec
+}
+
+func (self *FlowRemoved) SetDurationSec(v uint32) {
+	self.DurationSec = v
+}
+
+func (self *FlowRemoved) GetDurationNsec() uint32 {
+	return self.DurationNsec
+}
+
+func (self *FlowRemoved) SetDurationNsec(v uint32) {
+	self.DurationNsec = v
+}
+
+func (self *FlowRemoved) GetIdleTimeout() uint16 {
+	return self.IdleTimeout
+}
+
+func (self *FlowRemoved) SetIdleTimeout(v uint16) {
+	self.IdleTimeout = v
+}
+
+func (self *FlowRemoved) GetPacketCount() uint64 {
+	return self.PacketCount
+}
+
+func (self *FlowRemoved) SetPacketCount(v uint64) {
+	self.PacketCount = v
+}
+
+func (self *FlowRemoved) GetByteCount() uint64 {
+	return self.ByteCount
+}
+
+func (self *FlowRemoved) SetByteCount(v uint64) {
+	self.ByteCount = v
+}
+
+func (self *FlowRemoved) GetMatch() Match {
+	return self.Match
+}
+
+func (self *FlowRemoved) SetMatch(v Match) {
+	self.Match = v
+}
+
+func (self *FlowRemoved) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.Cookie))
+	encoder.PutUint16(uint16(self.Priority))
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.PutUint32(uint32(self.DurationSec))
+	encoder.PutUint32(uint32(self.DurationNsec))
+	encoder.PutUint16(uint16(self.IdleTimeout))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint64(uint64(self.PacketCount))
+	encoder.PutUint64(uint64(self.ByteCount))
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowRemoved(parent *Header, decoder *goloxi.Decoder) (*FlowRemoved, error) {
+	_flowremoved := &FlowRemoved{Header: parent}
+	if decoder.Length() < 128 {
+		return nil, fmt.Errorf("FlowRemoved packet too short: %d < 128", decoder.Length())
+	}
+	_flowremoved.Cookie = uint64(decoder.ReadUint64())
+	_flowremoved.Priority = uint16(decoder.ReadUint16())
+	_flowremoved.Reason = FlowRemovedReason(decoder.ReadByte())
+	_flowremoved.TableId = uint8(decoder.ReadByte())
+	_flowremoved.DurationSec = uint32(decoder.ReadUint32())
+	_flowremoved.DurationNsec = uint32(decoder.ReadUint32())
+	_flowremoved.IdleTimeout = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_flowremoved.PacketCount = uint64(decoder.ReadUint64())
+	_flowremoved.ByteCount = uint64(decoder.ReadUint64())
+	if err := _flowremoved.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _flowremoved, nil
+}
+
+func NewFlowRemoved() *FlowRemoved {
+	obj := &FlowRemoved{
+		Header: NewHeader(11),
+	}
+	return obj
+}
+
+type FlowStatsReply struct {
+	*StatsReply
+	Entries []*FlowStatsEntry
+}
+
+type IFlowStatsReply interface {
+	IStatsReply
+	GetEntries() []*FlowStatsEntry
+}
+
+func (self *FlowStatsReply) GetEntries() []*FlowStatsEntry {
+	return self.Entries
+}
+
+func (self *FlowStatsReply) SetEntries(v []*FlowStatsEntry) {
+	self.Entries = v
+}
+
+func (self *FlowStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*FlowStatsReply, error) {
+	_flowstatsreply := &FlowStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("FlowStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 136 {
+		item, err := DecodeFlowStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_flowstatsreply.Entries = append(_flowstatsreply.Entries, item)
+		}
+	}
+	return _flowstatsreply, nil
+}
+
+func NewFlowStatsReply() *FlowStatsReply {
+	obj := &FlowStatsReply{
+		StatsReply: NewStatsReply(1),
+	}
+	return obj
+}
+
+type FlowStatsRequest struct {
+	*StatsRequest
+	TableId    uint8
+	OutPort    Port
+	OutGroup   uint32
+	Cookie     uint64
+	CookieMask uint64
+	Match      Match
+}
+
+type IFlowStatsRequest interface {
+	IStatsRequest
+	GetTableId() uint8
+	GetOutPort() Port
+	GetOutGroup() uint32
+	GetCookie() uint64
+	GetCookieMask() uint64
+	GetMatch() Match
+}
+
+func (self *FlowStatsRequest) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *FlowStatsRequest) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *FlowStatsRequest) GetOutPort() Port {
+	return self.OutPort
+}
+
+func (self *FlowStatsRequest) SetOutPort(v Port) {
+	self.OutPort = v
+}
+
+func (self *FlowStatsRequest) GetOutGroup() uint32 {
+	return self.OutGroup
+}
+
+func (self *FlowStatsRequest) SetOutGroup(v uint32) {
+	self.OutGroup = v
+}
+
+func (self *FlowStatsRequest) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *FlowStatsRequest) SetCookie(v uint64) {
+	self.Cookie = v
+}
+
+func (self *FlowStatsRequest) GetCookieMask() uint64 {
+	return self.CookieMask
+}
+
+func (self *FlowStatsRequest) SetCookieMask(v uint64) {
+	self.CookieMask = v
+}
+
+func (self *FlowStatsRequest) GetMatch() Match {
+	return self.Match
+}
+
+func (self *FlowStatsRequest) SetMatch(v Match) {
+	self.Match = v
+}
+
+func (self *FlowStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	self.OutPort.Serialize(encoder)
+	encoder.PutUint32(uint32(self.OutGroup))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint64(uint64(self.Cookie))
+	encoder.PutUint64(uint64(self.CookieMask))
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*FlowStatsRequest, error) {
+	_flowstatsrequest := &FlowStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 108 {
+		return nil, fmt.Errorf("FlowStatsRequest packet too short: %d < 108", decoder.Length())
+	}
+	decoder.Skip(4)
+	_flowstatsrequest.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_flowstatsrequest.OutPort.Decode(decoder)
+	_flowstatsrequest.OutGroup = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+	_flowstatsrequest.Cookie = uint64(decoder.ReadUint64())
+	_flowstatsrequest.CookieMask = uint64(decoder.ReadUint64())
+	if err := _flowstatsrequest.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _flowstatsrequest, nil
+}
+
+func NewFlowStatsRequest() *FlowStatsRequest {
+	obj := &FlowStatsRequest{
+		StatsRequest: NewStatsRequest(1),
+	}
+	return obj
+}
+
+type GetConfigReply struct {
+	*Header
+	Flags       ConfigFlags
+	MissSendLen uint16
+}
+
+type IGetConfigReply interface {
+	IHeader
+	GetFlags() ConfigFlags
+	GetMissSendLen() uint16
+}
+
+func (self *GetConfigReply) GetFlags() ConfigFlags {
+	return self.Flags
+}
+
+func (self *GetConfigReply) SetFlags(v ConfigFlags) {
+	self.Flags = v
+}
+
+func (self *GetConfigReply) GetMissSendLen() uint16 {
+	return self.MissSendLen
+}
+
+func (self *GetConfigReply) SetMissSendLen(v uint16) {
+	self.MissSendLen = v
+}
+
+func (self *GetConfigReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.PutUint16(uint16(self.MissSendLen))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGetConfigReply(parent *Header, decoder *goloxi.Decoder) (*GetConfigReply, error) {
+	_getconfigreply := &GetConfigReply{Header: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("GetConfigReply packet too short: %d < 4", decoder.Length())
+	}
+	_getconfigreply.Flags = ConfigFlags(decoder.ReadUint16())
+	_getconfigreply.MissSendLen = uint16(decoder.ReadUint16())
+	return _getconfigreply, nil
+}
+
+func NewGetConfigReply() *GetConfigReply {
+	obj := &GetConfigReply{
+		Header: NewHeader(8),
+	}
+	return obj
+}
+
+type GetConfigRequest struct {
+	*Header
+}
+
+type IGetConfigRequest interface {
+	IHeader
+}
+
+func (self *GetConfigRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGetConfigRequest(parent *Header, decoder *goloxi.Decoder) (*GetConfigRequest, error) {
+	_getconfigrequest := &GetConfigRequest{Header: parent}
+	return _getconfigrequest, nil
+}
+
+func NewGetConfigRequest() *GetConfigRequest {
+	obj := &GetConfigRequest{
+		Header: NewHeader(7),
+	}
+	return obj
+}
+
+type GroupMod struct {
+	*Header
+	Command   GroupModCommand
+	GroupType GroupType
+	GroupId   uint32
+	Buckets   []*Bucket
+}
+
+type IGroupMod interface {
+	IHeader
+	GetCommand() GroupModCommand
+	GetGroupType() GroupType
+	GetGroupId() uint32
+	GetBuckets() []*Bucket
+}
+
+func (self *GroupMod) GetCommand() GroupModCommand {
+	return self.Command
+}
+
+func (self *GroupMod) SetCommand(v GroupModCommand) {
+	self.Command = v
+}
+
+func (self *GroupMod) GetGroupType() GroupType {
+	return self.GroupType
+}
+
+func (self *GroupMod) SetGroupType(v GroupType) {
+	self.GroupType = v
+}
+
+func (self *GroupMod) GetGroupId() uint32 {
+	return self.GroupId
+}
+
+func (self *GroupMod) SetGroupId(v uint32) {
+	self.GroupId = v
+}
+
+func (self *GroupMod) GetBuckets() []*Bucket {
+	return self.Buckets
+}
+
+func (self *GroupMod) SetBuckets(v []*Bucket) {
+	self.Buckets = v
+}
+
+func (self *GroupMod) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Command))
+	encoder.PutUint8(uint8(self.GroupType))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint32(uint32(self.GroupId))
+	for _, obj := range self.Buckets {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func DecodeGroupMod(parent *Header, decoder *goloxi.Decoder) (IGroupMod, error) {
+	_groupmod := &GroupMod{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("GroupMod packet too short: %d < 8", decoder.Length())
+	}
+	_groupmod.Command = GroupModCommand(decoder.ReadUint16())
+	_groupmod.GroupType = GroupType(decoder.ReadByte())
+	decoder.Skip(1)
+	_groupmod.GroupId = uint32(decoder.ReadUint32())
+
+	for decoder.Length() >= 16 {
+		item, err := DecodeBucket(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_groupmod.Buckets = append(_groupmod.Buckets, item)
+		}
+	}
+
+	switch _groupmod.Command {
+	case 0:
+		return DecodeGroupAdd(_groupmod, decoder)
+	case 1:
+		return DecodeGroupModify(_groupmod, decoder)
+	case 2:
+		return DecodeGroupDelete(_groupmod, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'GroupMod'", _groupmod.Command)
+	}
+}
+
+func NewGroupMod(_command GroupModCommand) *GroupMod {
+	obj := &GroupMod{
+		Header: NewHeader(15),
+	}
+	obj.Command = _command
+	return obj
+}
+
+type GroupAdd struct {
+	*GroupMod
+}
+
+type IGroupAdd interface {
+	IGroupMod
+}
+
+func (self *GroupAdd) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.GroupMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupAdd(parent *GroupMod, decoder *goloxi.Decoder) (*GroupAdd, error) {
+	_groupadd := &GroupAdd{GroupMod: parent}
+	return _groupadd, nil
+}
+
+func NewGroupAdd() *GroupAdd {
+	obj := &GroupAdd{
+		GroupMod: NewGroupMod(0),
+	}
+	return obj
+}
+
+type GroupDelete struct {
+	*GroupMod
+}
+
+type IGroupDelete interface {
+	IGroupMod
+}
+
+func (self *GroupDelete) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.GroupMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupDelete(parent *GroupMod, decoder *goloxi.Decoder) (*GroupDelete, error) {
+	_groupdelete := &GroupDelete{GroupMod: parent}
+	return _groupdelete, nil
+}
+
+func NewGroupDelete() *GroupDelete {
+	obj := &GroupDelete{
+		GroupMod: NewGroupMod(2),
+	}
+	return obj
+}
+
+type GroupDescStatsReply struct {
+	*StatsReply
+	Entries []*GroupDescStatsEntry
+}
+
+type IGroupDescStatsReply interface {
+	IStatsReply
+	GetEntries() []*GroupDescStatsEntry
+}
+
+func (self *GroupDescStatsReply) GetEntries() []*GroupDescStatsEntry {
+	return self.Entries
+}
+
+func (self *GroupDescStatsReply) SetEntries(v []*GroupDescStatsEntry) {
+	self.Entries = v
+}
+
+func (self *GroupDescStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupDescStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*GroupDescStatsReply, error) {
+	_groupdescstatsreply := &GroupDescStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("GroupDescStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeGroupDescStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_groupdescstatsreply.Entries = append(_groupdescstatsreply.Entries, item)
+		}
+	}
+	return _groupdescstatsreply, nil
+}
+
+func NewGroupDescStatsReply() *GroupDescStatsReply {
+	obj := &GroupDescStatsReply{
+		StatsReply: NewStatsReply(7),
+	}
+	return obj
+}
+
+type GroupDescStatsRequest struct {
+	*StatsRequest
+}
+
+type IGroupDescStatsRequest interface {
+	IStatsRequest
+}
+
+func (self *GroupDescStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupDescStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*GroupDescStatsRequest, error) {
+	_groupdescstatsrequest := &GroupDescStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("GroupDescStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _groupdescstatsrequest, nil
+}
+
+func NewGroupDescStatsRequest() *GroupDescStatsRequest {
+	obj := &GroupDescStatsRequest{
+		StatsRequest: NewStatsRequest(7),
+	}
+	return obj
+}
+
+type GroupModFailedErrorMsg struct {
+	*ErrorMsg
+	Code GroupModFailedCode
+	Data []byte
+}
+
+type IGroupModFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() GroupModFailedCode
+	GetData() []byte
+}
+
+func (self *GroupModFailedErrorMsg) GetCode() GroupModFailedCode {
+	return self.Code
+}
+
+func (self *GroupModFailedErrorMsg) SetCode(v GroupModFailedCode) {
+	self.Code = v
+}
+
+func (self *GroupModFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *GroupModFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *GroupModFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupModFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*GroupModFailedErrorMsg, error) {
+	_groupmodfailederrormsg := &GroupModFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("GroupModFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_groupmodfailederrormsg.Code = GroupModFailedCode(decoder.ReadUint16())
+	_groupmodfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _groupmodfailederrormsg, nil
+}
+
+func NewGroupModFailedErrorMsg() *GroupModFailedErrorMsg {
+	obj := &GroupModFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(6),
+	}
+	return obj
+}
+
+type GroupModify struct {
+	*GroupMod
+}
+
+type IGroupModify interface {
+	IGroupMod
+}
+
+func (self *GroupModify) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.GroupMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupModify(parent *GroupMod, decoder *goloxi.Decoder) (*GroupModify, error) {
+	_groupmodify := &GroupModify{GroupMod: parent}
+	return _groupmodify, nil
+}
+
+func NewGroupModify() *GroupModify {
+	obj := &GroupModify{
+		GroupMod: NewGroupMod(1),
+	}
+	return obj
+}
+
+type GroupStatsReply struct {
+	*StatsReply
+	Entries []*GroupStatsEntry
+}
+
+type IGroupStatsReply interface {
+	IStatsReply
+	GetEntries() []*GroupStatsEntry
+}
+
+func (self *GroupStatsReply) GetEntries() []*GroupStatsEntry {
+	return self.Entries
+}
+
+func (self *GroupStatsReply) SetEntries(v []*GroupStatsEntry) {
+	self.Entries = v
+}
+
+func (self *GroupStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*GroupStatsReply, error) {
+	_groupstatsreply := &GroupStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("GroupStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 32 {
+		item, err := DecodeGroupStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_groupstatsreply.Entries = append(_groupstatsreply.Entries, item)
+		}
+	}
+	return _groupstatsreply, nil
+}
+
+func NewGroupStatsReply() *GroupStatsReply {
+	obj := &GroupStatsReply{
+		StatsReply: NewStatsReply(6),
+	}
+	return obj
+}
+
+type GroupStatsRequest struct {
+	*StatsRequest
+	GroupId uint32
+}
+
+type IGroupStatsRequest interface {
+	IStatsRequest
+	GetGroupId() uint32
+}
+
+func (self *GroupStatsRequest) GetGroupId() uint32 {
+	return self.GroupId
+}
+
+func (self *GroupStatsRequest) SetGroupId(v uint32) {
+	self.GroupId = v
+}
+
+func (self *GroupStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint32(uint32(self.GroupId))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*GroupStatsRequest, error) {
+	_groupstatsrequest := &GroupStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("GroupStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	_groupstatsrequest.GroupId = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+	return _groupstatsrequest, nil
+}
+
+func NewGroupStatsRequest() *GroupStatsRequest {
+	obj := &GroupStatsRequest{
+		StatsRequest: NewStatsRequest(6),
+	}
+	return obj
+}
+
+type Hello struct {
+	*Header
+}
+
+type IHello interface {
+	IHeader
+}
+
+func (self *Hello) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeHello(parent *Header, decoder *goloxi.Decoder) (*Hello, error) {
+	_hello := &Hello{Header: parent}
+	return _hello, nil
+}
+
+func NewHello() *Hello {
+	obj := &Hello{
+		Header: NewHeader(0),
+	}
+	return obj
+}
+
+type HelloFailedErrorMsg struct {
+	*ErrorMsg
+	Code HelloFailedCode
+	Data []byte
+}
+
+type IHelloFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() HelloFailedCode
+	GetData() []byte
+}
+
+func (self *HelloFailedErrorMsg) GetCode() HelloFailedCode {
+	return self.Code
+}
+
+func (self *HelloFailedErrorMsg) SetCode(v HelloFailedCode) {
+	self.Code = v
+}
+
+func (self *HelloFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *HelloFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *HelloFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeHelloFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*HelloFailedErrorMsg, error) {
+	_hellofailederrormsg := &HelloFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("HelloFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_hellofailederrormsg.Code = HelloFailedCode(decoder.ReadUint16())
+	_hellofailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _hellofailederrormsg, nil
+}
+
+func NewHelloFailedErrorMsg() *HelloFailedErrorMsg {
+	obj := &HelloFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(0),
+	}
+	return obj
+}
+
+type NiciraStatsReply struct {
+	*ExperimenterStatsReply
+	Subtype uint32
+}
+
+type INiciraStatsReply interface {
+	IExperimenterStatsReply
+	GetSubtype() uint32
+}
+
+func (self *NiciraStatsReply) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *NiciraStatsReply) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *NiciraStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeNiciraStatsReply(parent *ExperimenterStatsReply, decoder *goloxi.Decoder) (INiciraStatsReply, error) {
+	_nicirastatsreply := &NiciraStatsReply{ExperimenterStatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	_nicirastatsreply.Subtype = uint32(decoder.ReadUint32())
+
+	switch _nicirastatsreply.Subtype {
+	case 0:
+		return DecodeNiciraFlowStatsReply(_nicirastatsreply, decoder)
+	case 2:
+		return DecodeNiciraFlowMonitorReply(_nicirastatsreply, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'NiciraStatsReply'", _nicirastatsreply.Subtype)
+	}
+}
+
+func NewNiciraStatsReply(_subtype uint32) *NiciraStatsReply {
+	obj := &NiciraStatsReply{
+		ExperimenterStatsReply: NewExperimenterStatsReply(8992),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type NiciraFlowMonitorReply struct {
+	*NiciraStatsReply
+	Updates []INiciraFlowUpdateEvent
+}
+
+type INiciraFlowMonitorReply interface {
+	INiciraStatsReply
+	GetUpdates() []INiciraFlowUpdateEvent
+}
+
+func (self *NiciraFlowMonitorReply) GetUpdates() []INiciraFlowUpdateEvent {
+	return self.Updates
+}
+
+func (self *NiciraFlowMonitorReply) SetUpdates(v []INiciraFlowUpdateEvent) {
+	self.Updates = v
+}
+
+func (self *NiciraFlowMonitorReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.NiciraStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Updates {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeNiciraFlowMonitorReply(parent *NiciraStatsReply, decoder *goloxi.Decoder) (*NiciraFlowMonitorReply, error) {
+	_niciraflowmonitorreply := &NiciraFlowMonitorReply{NiciraStatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraFlowMonitorReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeNiciraFlowUpdateEvent(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_niciraflowmonitorreply.Updates = append(_niciraflowmonitorreply.Updates, item)
+		}
+	}
+	return _niciraflowmonitorreply, nil
+}
+
+func NewNiciraFlowMonitorReply() *NiciraFlowMonitorReply {
+	obj := &NiciraFlowMonitorReply{
+		NiciraStatsReply: NewNiciraStatsReply(2),
+	}
+	return obj
+}
+
+type NiciraFlowMonitorRequest struct {
+	*ExperimenterStatsRequest
+	Subtype      uint32
+	MonitorId    uint32
+	MonitorFlags NxFlowMonitorFlags
+	OutPort      Port
+	MatchLen     uint16
+	TableId      uint8
+	Match        NiciraMatch
+}
+
+type INiciraFlowMonitorRequest interface {
+	IExperimenterStatsRequest
+	GetSubtype() uint32
+	GetMonitorId() uint32
+	GetMonitorFlags() NxFlowMonitorFlags
+	GetOutPort() Port
+	GetMatchLen() uint16
+	GetTableId() uint8
+	GetMatch() NiciraMatch
+}
+
+func (self *NiciraFlowMonitorRequest) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *NiciraFlowMonitorRequest) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetMonitorId() uint32 {
+	return self.MonitorId
+}
+
+func (self *NiciraFlowMonitorRequest) SetMonitorId(v uint32) {
+	self.MonitorId = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetMonitorFlags() NxFlowMonitorFlags {
+	return self.MonitorFlags
+}
+
+func (self *NiciraFlowMonitorRequest) SetMonitorFlags(v NxFlowMonitorFlags) {
+	self.MonitorFlags = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetOutPort() Port {
+	return self.OutPort
+}
+
+func (self *NiciraFlowMonitorRequest) SetOutPort(v Port) {
+	self.OutPort = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetMatchLen() uint16 {
+	return self.MatchLen
+}
+
+func (self *NiciraFlowMonitorRequest) SetMatchLen(v uint16) {
+	self.MatchLen = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *NiciraFlowMonitorRequest) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetMatch() NiciraMatch {
+	return self.Match
+}
+
+func (self *NiciraFlowMonitorRequest) SetMatch(v NiciraMatch) {
+	self.Match = v
+}
+
+func (self *NiciraFlowMonitorRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ExperimenterStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+	encoder.PutUint32(uint32(self.MonitorId))
+	encoder.PutUint16(uint16(self.MonitorFlags))
+	self.OutPort.Serialize(encoder)
+	encoder.PutUint16(uint16(self.MatchLen))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 5))
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeNiciraFlowMonitorRequest(parent *ExperimenterStatsRequest, decoder *goloxi.Decoder) (*NiciraFlowMonitorRequest, error) {
+	_niciraflowmonitorrequest := &NiciraFlowMonitorRequest{ExperimenterStatsRequest: parent}
+	if decoder.Length() < 26 {
+		return nil, fmt.Errorf("NiciraFlowMonitorRequest packet too short: %d < 26", decoder.Length())
+	}
+	_niciraflowmonitorrequest.Subtype = uint32(decoder.ReadUint32())
+	_niciraflowmonitorrequest.MonitorId = uint32(decoder.ReadUint32())
+	_niciraflowmonitorrequest.MonitorFlags = NxFlowMonitorFlags(decoder.ReadUint16())
+	_niciraflowmonitorrequest.OutPort.Decode(decoder)
+	_niciraflowmonitorrequest.MatchLen = uint16(decoder.ReadUint16())
+	_niciraflowmonitorrequest.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(5)
+	if err := _niciraflowmonitorrequest.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	decoder.SkipAlign()
+	return _niciraflowmonitorrequest, nil
+}
+
+func NewNiciraFlowMonitorRequest() *NiciraFlowMonitorRequest {
+	obj := &NiciraFlowMonitorRequest{
+		ExperimenterStatsRequest: NewExperimenterStatsRequest(8992),
+	}
+	return obj
+}
+
+type NiciraFlowStatsReply struct {
+	*NiciraStatsReply
+	Stats []*NiciraFlowStats
+}
+
+type INiciraFlowStatsReply interface {
+	INiciraStatsReply
+	GetStats() []*NiciraFlowStats
+}
+
+func (self *NiciraFlowStatsReply) GetStats() []*NiciraFlowStats {
+	return self.Stats
+}
+
+func (self *NiciraFlowStatsReply) SetStats(v []*NiciraFlowStats) {
+	self.Stats = v
+}
+
+func (self *NiciraFlowStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.NiciraStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Stats {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeNiciraFlowStatsReply(parent *NiciraStatsReply, decoder *goloxi.Decoder) (*NiciraFlowStatsReply, error) {
+	_niciraflowstatsreply := &NiciraFlowStatsReply{NiciraStatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraFlowStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 48 {
+		item, err := DecodeNiciraFlowStats(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_niciraflowstatsreply.Stats = append(_niciraflowstatsreply.Stats, item)
+		}
+	}
+	return _niciraflowstatsreply, nil
+}
+
+func NewNiciraFlowStatsReply() *NiciraFlowStatsReply {
+	obj := &NiciraFlowStatsReply{
+		NiciraStatsReply: NewNiciraStatsReply(0),
+	}
+	return obj
+}
+
+type NiciraFlowStatsRequest struct {
+	*ExperimenterStatsRequest
+	Subtype  uint32
+	OutPort  Port
+	MatchLen uint16
+	TableId  uint8
+}
+
+type INiciraFlowStatsRequest interface {
+	IExperimenterStatsRequest
+	GetSubtype() uint32
+	GetOutPort() Port
+	GetMatchLen() uint16
+	GetTableId() uint8
+}
+
+func (self *NiciraFlowStatsRequest) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *NiciraFlowStatsRequest) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *NiciraFlowStatsRequest) GetOutPort() Port {
+	return self.OutPort
+}
+
+func (self *NiciraFlowStatsRequest) SetOutPort(v Port) {
+	self.OutPort = v
+}
+
+func (self *NiciraFlowStatsRequest) GetMatchLen() uint16 {
+	return self.MatchLen
+}
+
+func (self *NiciraFlowStatsRequest) SetMatchLen(v uint16) {
+	self.MatchLen = v
+}
+
+func (self *NiciraFlowStatsRequest) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *NiciraFlowStatsRequest) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *NiciraFlowStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ExperimenterStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+	self.OutPort.Serialize(encoder)
+	encoder.PutUint16(uint16(self.MatchLen))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeNiciraFlowStatsRequest(parent *ExperimenterStatsRequest, decoder *goloxi.Decoder) (*NiciraFlowStatsRequest, error) {
+	_niciraflowstatsrequest := &NiciraFlowStatsRequest{ExperimenterStatsRequest: parent}
+	if decoder.Length() < 18 {
+		return nil, fmt.Errorf("NiciraFlowStatsRequest packet too short: %d < 18", decoder.Length())
+	}
+	_niciraflowstatsrequest.Subtype = uint32(decoder.ReadUint32())
+	_niciraflowstatsrequest.OutPort.Decode(decoder)
+	_niciraflowstatsrequest.MatchLen = uint16(decoder.ReadUint16())
+	_niciraflowstatsrequest.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _niciraflowstatsrequest, nil
+}
+
+func NewNiciraFlowStatsRequest() *NiciraFlowStatsRequest {
+	obj := &NiciraFlowStatsRequest{
+		ExperimenterStatsRequest: NewExperimenterStatsRequest(8992),
+	}
+	return obj
+}
+
+type NiciraHeader struct {
+	*Experimenter
+	Subtype uint32
+}
+
+type INiciraHeader interface {
+	IExperimenter
+	GetSubtype() uint32
+}
+
+func (self *NiciraHeader) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *NiciraHeader) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *NiciraHeader) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Experimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeNiciraHeader(parent *Experimenter, decoder *goloxi.Decoder) (INiciraHeader, error) {
+	_niciraheader := &NiciraHeader{Experimenter: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraHeader packet too short: %d < 4", decoder.Length())
+	}
+	_niciraheader.Subtype = uint32(decoder.ReadUint32())
+	return _niciraheader, nil
+}
+
+func NewNiciraHeader(_subtype uint32) *NiciraHeader {
+	obj := &NiciraHeader{
+		Experimenter: NewExperimenter(8992),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type PacketIn struct {
+	*Header
+	BufferId  uint32
+	InPort    Port
+	InPhyPort Port
+	TotalLen  uint16
+	Reason    uint8
+	TableId   uint8
+	Data      []byte
+}
+
+type IPacketIn interface {
+	IHeader
+	GetBufferId() uint32
+	GetInPort() Port
+	GetInPhyPort() Port
+	GetTotalLen() uint16
+	GetReason() uint8
+	GetTableId() uint8
+	GetData() []byte
+}
+
+func (self *PacketIn) GetBufferId() uint32 {
+	return self.BufferId
+}
+
+func (self *PacketIn) SetBufferId(v uint32) {
+	self.BufferId = v
+}
+
+func (self *PacketIn) GetInPort() Port {
+	return self.InPort
+}
+
+func (self *PacketIn) SetInPort(v Port) {
+	self.InPort = v
+}
+
+func (self *PacketIn) GetInPhyPort() Port {
+	return self.InPhyPort
+}
+
+func (self *PacketIn) SetInPhyPort(v Port) {
+	self.InPhyPort = v
+}
+
+func (self *PacketIn) GetTotalLen() uint16 {
+	return self.TotalLen
+}
+
+func (self *PacketIn) SetTotalLen(v uint16) {
+	self.TotalLen = v
+}
+
+func (self *PacketIn) GetReason() uint8 {
+	return self.Reason
+}
+
+func (self *PacketIn) SetReason(v uint8) {
+	self.Reason = v
+}
+
+func (self *PacketIn) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *PacketIn) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *PacketIn) GetData() []byte {
+	return self.Data
+}
+
+func (self *PacketIn) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *PacketIn) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.BufferId))
+	self.InPort.Serialize(encoder)
+	self.InPhyPort.Serialize(encoder)
+	encoder.PutUint16(uint16(self.TotalLen))
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePacketIn(parent *Header, decoder *goloxi.Decoder) (*PacketIn, error) {
+	_packetin := &PacketIn{Header: parent}
+	if decoder.Length() < 16 {
+		return nil, fmt.Errorf("PacketIn packet too short: %d < 16", decoder.Length())
+	}
+	_packetin.BufferId = uint32(decoder.ReadUint32())
+	_packetin.InPort.Decode(decoder)
+	_packetin.InPhyPort.Decode(decoder)
+	_packetin.TotalLen = uint16(decoder.ReadUint16())
+	_packetin.Reason = uint8(decoder.ReadByte())
+	_packetin.TableId = uint8(decoder.ReadByte())
+	_packetin.Data = decoder.Read(int(decoder.Length()))
+	return _packetin, nil
+}
+
+func NewPacketIn() *PacketIn {
+	obj := &PacketIn{
+		Header: NewHeader(10),
+	}
+	return obj
+}
+
+type PacketOut struct {
+	*Header
+	BufferId   uint32
+	InPort     Port
+	ActionsLen uint16
+	Actions    []goloxi.IAction
+	Data       []byte
+}
+
+type IPacketOut interface {
+	IHeader
+	GetBufferId() uint32
+	GetInPort() Port
+	GetActionsLen() uint16
+	GetActions() []goloxi.IAction
+	GetData() []byte
+}
+
+func (self *PacketOut) GetBufferId() uint32 {
+	return self.BufferId
+}
+
+func (self *PacketOut) SetBufferId(v uint32) {
+	self.BufferId = v
+}
+
+func (self *PacketOut) GetInPort() Port {
+	return self.InPort
+}
+
+func (self *PacketOut) SetInPort(v Port) {
+	self.InPort = v
+}
+
+func (self *PacketOut) GetActionsLen() uint16 {
+	return self.ActionsLen
+}
+
+func (self *PacketOut) SetActionsLen(v uint16) {
+	self.ActionsLen = v
+}
+
+func (self *PacketOut) GetActions() []goloxi.IAction {
+	return self.Actions
+}
+
+func (self *PacketOut) SetActions(v []goloxi.IAction) {
+	self.Actions = v
+}
+
+func (self *PacketOut) GetData() []byte {
+	return self.Data
+}
+
+func (self *PacketOut) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *PacketOut) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.BufferId))
+	self.InPort.Serialize(encoder)
+	encoder.PutUint16(uint16(self.ActionsLen))
+	encoder.Write(bytes.Repeat([]byte{0}, 6))
+	for _, obj := range self.Actions {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePacketOut(parent *Header, decoder *goloxi.Decoder) (*PacketOut, error) {
+	_packetout := &PacketOut{Header: parent}
+	if decoder.Length() < 16 {
+		return nil, fmt.Errorf("PacketOut packet too short: %d < 16", decoder.Length())
+	}
+	_packetout.BufferId = uint32(decoder.ReadUint32())
+	_packetout.InPort.Decode(decoder)
+	_packetout.ActionsLen = uint16(decoder.ReadUint16())
+	decoder.Skip(6)
+
+	end := decoder.Offset() + int(_packetout.ActionsLen)
+	for decoder.Offset() < end {
+		item, err := DecodeAction(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_packetout.Actions = append(_packetout.Actions, item)
+		}
+	}
+	_packetout.Data = decoder.Read(int(decoder.Length()))
+	return _packetout, nil
+}
+
+func NewPacketOut() *PacketOut {
+	obj := &PacketOut{
+		Header: NewHeader(13),
+	}
+	return obj
+}
+
+type PortMod struct {
+	*Header
+	PortNo    Port
+	HwAddr    net.HardwareAddr
+	Config    PortConfig
+	Mask      PortConfig
+	Advertise uint32
+}
+
+type IPortMod interface {
+	IHeader
+	GetPortNo() Port
+	GetHwAddr() net.HardwareAddr
+	GetConfig() PortConfig
+	GetMask() PortConfig
+	GetAdvertise() uint32
+}
+
+func (self *PortMod) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *PortMod) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *PortMod) GetHwAddr() net.HardwareAddr {
+	return self.HwAddr
+}
+
+func (self *PortMod) SetHwAddr(v net.HardwareAddr) {
+	self.HwAddr = v
+}
+
+func (self *PortMod) GetConfig() PortConfig {
+	return self.Config
+}
+
+func (self *PortMod) SetConfig(v PortConfig) {
+	self.Config = v
+}
+
+func (self *PortMod) GetMask() PortConfig {
+	return self.Mask
+}
+
+func (self *PortMod) SetMask(v PortConfig) {
+	self.Mask = v
+}
+
+func (self *PortMod) GetAdvertise() uint32 {
+	return self.Advertise
+}
+
+func (self *PortMod) SetAdvertise(v uint32) {
+	self.Advertise = v
+}
+
+func (self *PortMod) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.PortNo.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.Write(self.HwAddr)
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint32(uint32(self.Config))
+	encoder.PutUint32(uint32(self.Mask))
+	encoder.PutUint32(uint32(self.Advertise))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortMod(parent *Header, decoder *goloxi.Decoder) (*PortMod, error) {
+	_portmod := &PortMod{Header: parent}
+	if decoder.Length() < 32 {
+		return nil, fmt.Errorf("PortMod packet too short: %d < 32", decoder.Length())
+	}
+	_portmod.PortNo.Decode(decoder)
+	decoder.Skip(4)
+	_portmod.HwAddr = net.HardwareAddr(decoder.Read(6))
+	decoder.Skip(2)
+	_portmod.Config = PortConfig(decoder.ReadUint32())
+	_portmod.Mask = PortConfig(decoder.ReadUint32())
+	_portmod.Advertise = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+	return _portmod, nil
+}
+
+func NewPortMod() *PortMod {
+	obj := &PortMod{
+		Header: NewHeader(16),
+	}
+	return obj
+}
+
+type PortModFailedErrorMsg struct {
+	*ErrorMsg
+	Code PortModFailedCode
+	Data []byte
+}
+
+type IPortModFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() PortModFailedCode
+	GetData() []byte
+}
+
+func (self *PortModFailedErrorMsg) GetCode() PortModFailedCode {
+	return self.Code
+}
+
+func (self *PortModFailedErrorMsg) SetCode(v PortModFailedCode) {
+	self.Code = v
+}
+
+func (self *PortModFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *PortModFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *PortModFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortModFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*PortModFailedErrorMsg, error) {
+	_portmodfailederrormsg := &PortModFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("PortModFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_portmodfailederrormsg.Code = PortModFailedCode(decoder.ReadUint16())
+	_portmodfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _portmodfailederrormsg, nil
+}
+
+func NewPortModFailedErrorMsg() *PortModFailedErrorMsg {
+	obj := &PortModFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(7),
+	}
+	return obj
+}
+
+type PortStatsReply struct {
+	*StatsReply
+	Entries []*PortStatsEntry
+}
+
+type IPortStatsReply interface {
+	IStatsReply
+	GetEntries() []*PortStatsEntry
+}
+
+func (self *PortStatsReply) GetEntries() []*PortStatsEntry {
+	return self.Entries
+}
+
+func (self *PortStatsReply) SetEntries(v []*PortStatsEntry) {
+	self.Entries = v
+}
+
+func (self *PortStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*PortStatsReply, error) {
+	_portstatsreply := &PortStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("PortStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 104 {
+		item, err := DecodePortStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_portstatsreply.Entries = append(_portstatsreply.Entries, item)
+		}
+	}
+	return _portstatsreply, nil
+}
+
+func NewPortStatsReply() *PortStatsReply {
+	obj := &PortStatsReply{
+		StatsReply: NewStatsReply(4),
+	}
+	return obj
+}
+
+type PortStatsRequest struct {
+	*StatsRequest
+	PortNo Port
+}
+
+type IPortStatsRequest interface {
+	IStatsRequest
+	GetPortNo() Port
+}
+
+func (self *PortStatsRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *PortStatsRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *PortStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	self.PortNo.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*PortStatsRequest, error) {
+	_portstatsrequest := &PortStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("PortStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	_portstatsrequest.PortNo.Decode(decoder)
+	decoder.Skip(4)
+	return _portstatsrequest, nil
+}
+
+func NewPortStatsRequest() *PortStatsRequest {
+	obj := &PortStatsRequest{
+		StatsRequest: NewStatsRequest(4),
+	}
+	return obj
+}
+
+type PortStatus struct {
+	*Header
+	Reason PortReason
+	Desc   PortDesc
+}
+
+type IPortStatus interface {
+	IHeader
+	GetReason() PortReason
+	GetDesc() PortDesc
+}
+
+func (self *PortStatus) GetReason() PortReason {
+	return self.Reason
+}
+
+func (self *PortStatus) SetReason(v PortReason) {
+	self.Reason = v
+}
+
+func (self *PortStatus) GetDesc() PortDesc {
+	return self.Desc
+}
+
+func (self *PortStatus) SetDesc(v PortDesc) {
+	self.Desc = v
+}
+
+func (self *PortStatus) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.Write(bytes.Repeat([]byte{0}, 7))
+	if err := self.Desc.Serialize(encoder); err != nil {
+		return err
+	}
+
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortStatus(parent *Header, decoder *goloxi.Decoder) (*PortStatus, error) {
+	_portstatus := &PortStatus{Header: parent}
+	if decoder.Length() < 72 {
+		return nil, fmt.Errorf("PortStatus packet too short: %d < 72", decoder.Length())
+	}
+	_portstatus.Reason = PortReason(decoder.ReadByte())
+	decoder.Skip(7)
+	if err := _portstatus.Desc.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _portstatus, nil
+}
+
+func NewPortStatus() *PortStatus {
+	obj := &PortStatus{
+		Header: NewHeader(12),
+	}
+	return obj
+}
+
+type QueueGetConfigReply struct {
+	*Header
+	Port   Port
+	Queues []*PacketQueue
+}
+
+type IQueueGetConfigReply interface {
+	IHeader
+	GetPort() Port
+	GetQueues() []*PacketQueue
+}
+
+func (self *QueueGetConfigReply) GetPort() Port {
+	return self.Port
+}
+
+func (self *QueueGetConfigReply) SetPort(v Port) {
+	self.Port = v
+}
+
+func (self *QueueGetConfigReply) GetQueues() []*PacketQueue {
+	return self.Queues
+}
+
+func (self *QueueGetConfigReply) SetQueues(v []*PacketQueue) {
+	self.Queues = v
+}
+
+func (self *QueueGetConfigReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.Port.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Queues {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueGetConfigReply(parent *Header, decoder *goloxi.Decoder) (*QueueGetConfigReply, error) {
+	_queuegetconfigreply := &QueueGetConfigReply{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("QueueGetConfigReply packet too short: %d < 8", decoder.Length())
+	}
+	_queuegetconfigreply.Port.Decode(decoder)
+	decoder.Skip(4)
+
+	for decoder.Length() >= 8 {
+		item, err := DecodePacketQueue(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_queuegetconfigreply.Queues = append(_queuegetconfigreply.Queues, item)
+		}
+	}
+	return _queuegetconfigreply, nil
+}
+
+func NewQueueGetConfigReply() *QueueGetConfigReply {
+	obj := &QueueGetConfigReply{
+		Header: NewHeader(23),
+	}
+	return obj
+}
+
+type QueueGetConfigRequest struct {
+	*Header
+	Port Port
+}
+
+type IQueueGetConfigRequest interface {
+	IHeader
+	GetPort() Port
+}
+
+func (self *QueueGetConfigRequest) GetPort() Port {
+	return self.Port
+}
+
+func (self *QueueGetConfigRequest) SetPort(v Port) {
+	self.Port = v
+}
+
+func (self *QueueGetConfigRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.Port.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueGetConfigRequest(parent *Header, decoder *goloxi.Decoder) (*QueueGetConfigRequest, error) {
+	_queuegetconfigrequest := &QueueGetConfigRequest{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("QueueGetConfigRequest packet too short: %d < 8", decoder.Length())
+	}
+	_queuegetconfigrequest.Port.Decode(decoder)
+	decoder.Skip(4)
+	return _queuegetconfigrequest, nil
+}
+
+func NewQueueGetConfigRequest() *QueueGetConfigRequest {
+	obj := &QueueGetConfigRequest{
+		Header: NewHeader(22),
+	}
+	return obj
+}
+
+type QueueOpFailedErrorMsg struct {
+	*ErrorMsg
+	Code QueueOpFailedCode
+	Data []byte
+}
+
+type IQueueOpFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() QueueOpFailedCode
+	GetData() []byte
+}
+
+func (self *QueueOpFailedErrorMsg) GetCode() QueueOpFailedCode {
+	return self.Code
+}
+
+func (self *QueueOpFailedErrorMsg) SetCode(v QueueOpFailedCode) {
+	self.Code = v
+}
+
+func (self *QueueOpFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *QueueOpFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *QueueOpFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueOpFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*QueueOpFailedErrorMsg, error) {
+	_queueopfailederrormsg := &QueueOpFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("QueueOpFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_queueopfailederrormsg.Code = QueueOpFailedCode(decoder.ReadUint16())
+	_queueopfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _queueopfailederrormsg, nil
+}
+
+func NewQueueOpFailedErrorMsg() *QueueOpFailedErrorMsg {
+	obj := &QueueOpFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(9),
+	}
+	return obj
+}
+
+type QueueStatsReply struct {
+	*StatsReply
+	Entries []*QueueStatsEntry
+}
+
+type IQueueStatsReply interface {
+	IStatsReply
+	GetEntries() []*QueueStatsEntry
+}
+
+func (self *QueueStatsReply) GetEntries() []*QueueStatsEntry {
+	return self.Entries
+}
+
+func (self *QueueStatsReply) SetEntries(v []*QueueStatsEntry) {
+	self.Entries = v
+}
+
+func (self *QueueStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*QueueStatsReply, error) {
+	_queuestatsreply := &QueueStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("QueueStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 32 {
+		item, err := DecodeQueueStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_queuestatsreply.Entries = append(_queuestatsreply.Entries, item)
+		}
+	}
+	return _queuestatsreply, nil
+}
+
+func NewQueueStatsReply() *QueueStatsReply {
+	obj := &QueueStatsReply{
+		StatsReply: NewStatsReply(5),
+	}
+	return obj
+}
+
+type QueueStatsRequest struct {
+	*StatsRequest
+	PortNo  Port
+	QueueId uint32
+}
+
+type IQueueStatsRequest interface {
+	IStatsRequest
+	GetPortNo() Port
+	GetQueueId() uint32
+}
+
+func (self *QueueStatsRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *QueueStatsRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *QueueStatsRequest) GetQueueId() uint32 {
+	return self.QueueId
+}
+
+func (self *QueueStatsRequest) SetQueueId(v uint32) {
+	self.QueueId = v
+}
+
+func (self *QueueStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	self.PortNo.Serialize(encoder)
+	encoder.PutUint32(uint32(self.QueueId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*QueueStatsRequest, error) {
+	_queuestatsrequest := &QueueStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("QueueStatsRequest packet too short: %d < 12", decoder.Length())
+	}
+	decoder.Skip(4)
+	_queuestatsrequest.PortNo.Decode(decoder)
+	_queuestatsrequest.QueueId = uint32(decoder.ReadUint32())
+	return _queuestatsrequest, nil
+}
+
+func NewQueueStatsRequest() *QueueStatsRequest {
+	obj := &QueueStatsRequest{
+		StatsRequest: NewStatsRequest(5),
+	}
+	return obj
+}
+
+type SetConfig struct {
+	*Header
+	Flags       ConfigFlags
+	MissSendLen uint16
+}
+
+type ISetConfig interface {
+	IHeader
+	GetFlags() ConfigFlags
+	GetMissSendLen() uint16
+}
+
+func (self *SetConfig) GetFlags() ConfigFlags {
+	return self.Flags
+}
+
+func (self *SetConfig) SetFlags(v ConfigFlags) {
+	self.Flags = v
+}
+
+func (self *SetConfig) GetMissSendLen() uint16 {
+	return self.MissSendLen
+}
+
+func (self *SetConfig) SetMissSendLen(v uint16) {
+	self.MissSendLen = v
+}
+
+func (self *SetConfig) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.PutUint16(uint16(self.MissSendLen))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeSetConfig(parent *Header, decoder *goloxi.Decoder) (*SetConfig, error) {
+	_setconfig := &SetConfig{Header: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("SetConfig packet too short: %d < 4", decoder.Length())
+	}
+	_setconfig.Flags = ConfigFlags(decoder.ReadUint16())
+	_setconfig.MissSendLen = uint16(decoder.ReadUint16())
+	return _setconfig, nil
+}
+
+func NewSetConfig() *SetConfig {
+	obj := &SetConfig{
+		Header: NewHeader(9),
+	}
+	return obj
+}
+
+type SwitchConfigFailedErrorMsg struct {
+	*ErrorMsg
+	Code SwitchConfigFailedCode
+	Data []byte
+}
+
+type ISwitchConfigFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() SwitchConfigFailedCode
+	GetData() []byte
+}
+
+func (self *SwitchConfigFailedErrorMsg) GetCode() SwitchConfigFailedCode {
+	return self.Code
+}
+
+func (self *SwitchConfigFailedErrorMsg) SetCode(v SwitchConfigFailedCode) {
+	self.Code = v
+}
+
+func (self *SwitchConfigFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *SwitchConfigFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *SwitchConfigFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeSwitchConfigFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*SwitchConfigFailedErrorMsg, error) {
+	_switchconfigfailederrormsg := &SwitchConfigFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("SwitchConfigFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_switchconfigfailederrormsg.Code = SwitchConfigFailedCode(decoder.ReadUint16())
+	_switchconfigfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _switchconfigfailederrormsg, nil
+}
+
+func NewSwitchConfigFailedErrorMsg() *SwitchConfigFailedErrorMsg {
+	obj := &SwitchConfigFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(10),
+	}
+	return obj
+}
+
+type TableMod struct {
+	*Header
+	TableId uint8
+	Config  uint32
+}
+
+type ITableMod interface {
+	IHeader
+	GetTableId() uint8
+	GetConfig() uint32
+}
+
+func (self *TableMod) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *TableMod) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *TableMod) GetConfig() uint32 {
+	return self.Config
+}
+
+func (self *TableMod) SetConfig(v uint32) {
+	self.Config = v
+}
+
+func (self *TableMod) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.PutUint32(uint32(self.Config))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeTableMod(parent *Header, decoder *goloxi.Decoder) (*TableMod, error) {
+	_tablemod := &TableMod{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("TableMod packet too short: %d < 8", decoder.Length())
+	}
+	_tablemod.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_tablemod.Config = uint32(decoder.ReadUint32())
+	return _tablemod, nil
+}
+
+func NewTableMod() *TableMod {
+	obj := &TableMod{
+		Header: NewHeader(17),
+	}
+	return obj
+}
+
+type TableModFailedErrorMsg struct {
+	*ErrorMsg
+	Code TableModFailedCode
+	Data []byte
+}
+
+type ITableModFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() TableModFailedCode
+	GetData() []byte
+}
+
+func (self *TableModFailedErrorMsg) GetCode() TableModFailedCode {
+	return self.Code
+}
+
+func (self *TableModFailedErrorMsg) SetCode(v TableModFailedCode) {
+	self.Code = v
+}
+
+func (self *TableModFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *TableModFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *TableModFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeTableModFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*TableModFailedErrorMsg, error) {
+	_tablemodfailederrormsg := &TableModFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("TableModFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_tablemodfailederrormsg.Code = TableModFailedCode(decoder.ReadUint16())
+	_tablemodfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _tablemodfailederrormsg, nil
+}
+
+func NewTableModFailedErrorMsg() *TableModFailedErrorMsg {
+	obj := &TableModFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(8),
+	}
+	return obj
+}
+
+type TableStatsReply struct {
+	*StatsReply
+	Entries []*TableStatsEntry
+}
+
+type ITableStatsReply interface {
+	IStatsReply
+	GetEntries() []*TableStatsEntry
+}
+
+func (self *TableStatsReply) GetEntries() []*TableStatsEntry {
+	return self.Entries
+}
+
+func (self *TableStatsReply) SetEntries(v []*TableStatsEntry) {
+	self.Entries = v
+}
+
+func (self *TableStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeTableStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*TableStatsReply, error) {
+	_tablestatsreply := &TableStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("TableStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 88 {
+		item, err := DecodeTableStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_tablestatsreply.Entries = append(_tablestatsreply.Entries, item)
+		}
+	}
+	return _tablestatsreply, nil
+}
+
+func NewTableStatsReply() *TableStatsReply {
+	obj := &TableStatsReply{
+		StatsReply: NewStatsReply(3),
+	}
+	return obj
+}
+
+type TableStatsRequest struct {
+	*StatsRequest
+}
+
+type ITableStatsRequest interface {
+	IStatsRequest
+}
+
+func (self *TableStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeTableStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*TableStatsRequest, error) {
+	_tablestatsrequest := &TableStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("TableStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _tablestatsrequest, nil
+}
+
+func NewTableStatsRequest() *TableStatsRequest {
+	obj := &TableStatsRequest{
+		StatsRequest: NewStatsRequest(3),
+	}
+	return obj
+}
