diff --git a/of14/message.go b/of14/message.go
new file mode 100644
index 0000000..f5fd6fb
--- /dev/null
+++ b/of14/message.go
@@ -0,0 +1,12453 @@
+/*
+ * 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 of14
+
+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(5))
+	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 24:
+		return DecodeRoleRequest(_header, decoder)
+	case 25:
+		return DecodeRoleReply(_header, decoder)
+	case 26:
+		return DecodeAsyncGetRequest(_header, decoder)
+	case 27:
+		return DecodeAsyncGetReply(_header, decoder)
+	case 28:
+		return DecodeAsyncSet(_header, decoder)
+	case 29:
+		return DecodeMeterMod(_header, decoder)
+	case 30:
+		return DecodeRoleStatus(_header, decoder)
+	case 31:
+		return DecodeTableStatus(_header, decoder)
+	case 32:
+		return DecodeRequestforward(_header, decoder)
+	case 33:
+		return DecodeBundleCtrlMsg(_header, decoder)
+	case 34:
+		return DecodeBundleAddMsg(_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 8:
+		return DecodeGroupFeaturesStatsReply(_statsreply, decoder)
+	case 9:
+		return DecodeMeterStatsReply(_statsreply, decoder)
+	case 10:
+		return DecodeMeterConfigStatsReply(_statsreply, decoder)
+	case 11:
+		return DecodeMeterFeaturesStatsReply(_statsreply, decoder)
+	case 12:
+		return DecodeTableFeaturesStatsReply(_statsreply, decoder)
+	case 13:
+		return DecodePortDescStatsReply(_statsreply, decoder)
+	case 14:
+		return DecodeTableDescStatsReply(_statsreply, decoder)
+	case 15:
+		return DecodeQueueDescStatsReply(_statsreply, decoder)
+	case 16:
+		return DecodeFlowMonitorReply(_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 8:
+		return DecodeGroupFeaturesStatsRequest(_statsrequest, decoder)
+	case 9:
+		return DecodeMeterStatsRequest(_statsrequest, decoder)
+	case 10:
+		return DecodeMeterConfigStatsRequest(_statsrequest, decoder)
+	case 11:
+		return DecodeMeterFeaturesStatsRequest(_statsrequest, decoder)
+	case 12:
+		return DecodeTableFeaturesStatsRequest(_statsrequest, decoder)
+	case 13:
+		return DecodePortDescStatsRequest(_statsrequest, decoder)
+	case 14:
+		return DecodeTableDescStatsRequest(_statsrequest, decoder)
+	case 15:
+		return DecodeQueueDescStatsRequest(_statsrequest, decoder)
+	case 16:
+		return DecodeFlowMonitorRequest(_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() < 28 {
+		return nil, fmt.Errorf("AggregateStatsRequest packet too short: %d < 28", 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
+	}
+
+	decoder.SkipAlign()
+	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)
+	case 11:
+		return DecodeRoleRequestFailedErrorMsg(_errormsg, decoder)
+	case 12:
+		return DecodeMeterModFailedErrorMsg(_errormsg, decoder)
+	case 13:
+		return DecodeTableFeaturesFailedErrorMsg(_errormsg, decoder)
+	case 14:
+		return DecodeBadPropertyErrorMsg(_errormsg, decoder)
+	case 15:
+		return DecodeAsyncConfigFailedErrorMsg(_errormsg, decoder)
+	case 16:
+		return DecodeFlowMonitorFailedErrorMsg(_errormsg, decoder)
+	case 17:
+		return DecodeBundleFailedErrorMsg(_errormsg, decoder)
+	case 65535:
+		return DecodeExperimenterErrorMsg(_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 AsyncConfigFailedErrorMsg struct {
+	*ErrorMsg
+	Code AsyncConfigFailedCode
+	Data []byte
+}
+
+type IAsyncConfigFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() AsyncConfigFailedCode
+	GetData() []byte
+}
+
+func (self *AsyncConfigFailedErrorMsg) GetCode() AsyncConfigFailedCode {
+	return self.Code
+}
+
+func (self *AsyncConfigFailedErrorMsg) SetCode(v AsyncConfigFailedCode) {
+	self.Code = v
+}
+
+func (self *AsyncConfigFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *AsyncConfigFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *AsyncConfigFailedErrorMsg) 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 DecodeAsyncConfigFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*AsyncConfigFailedErrorMsg, error) {
+	_asyncconfigfailederrormsg := &AsyncConfigFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("AsyncConfigFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_asyncconfigfailederrormsg.Code = AsyncConfigFailedCode(decoder.ReadUint16())
+	_asyncconfigfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _asyncconfigfailederrormsg, nil
+}
+
+func NewAsyncConfigFailedErrorMsg() *AsyncConfigFailedErrorMsg {
+	obj := &AsyncConfigFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(15),
+	}
+	return obj
+}
+
+type AsyncGetReply struct {
+	*Header
+	Properties []IAsyncConfigProp
+}
+
+type IAsyncGetReply interface {
+	IHeader
+	GetProperties() []IAsyncConfigProp
+}
+
+func (self *AsyncGetReply) GetProperties() []IAsyncConfigProp {
+	return self.Properties
+}
+
+func (self *AsyncGetReply) SetProperties(v []IAsyncConfigProp) {
+	self.Properties = v
+}
+
+func (self *AsyncGetReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	for _, obj := range self.Properties {
+		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 DecodeAsyncGetReply(parent *Header, decoder *goloxi.Decoder) (*AsyncGetReply, error) {
+	_asyncgetreply := &AsyncGetReply{Header: parent}
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeAsyncConfigProp(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_asyncgetreply.Properties = append(_asyncgetreply.Properties, item)
+		}
+	}
+	return _asyncgetreply, nil
+}
+
+func NewAsyncGetReply() *AsyncGetReply {
+	obj := &AsyncGetReply{
+		Header: NewHeader(27),
+	}
+	return obj
+}
+
+type AsyncGetRequest struct {
+	*Header
+	Properties []IAsyncConfigProp
+}
+
+type IAsyncGetRequest interface {
+	IHeader
+	GetProperties() []IAsyncConfigProp
+}
+
+func (self *AsyncGetRequest) GetProperties() []IAsyncConfigProp {
+	return self.Properties
+}
+
+func (self *AsyncGetRequest) SetProperties(v []IAsyncConfigProp) {
+	self.Properties = v
+}
+
+func (self *AsyncGetRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	for _, obj := range self.Properties {
+		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 DecodeAsyncGetRequest(parent *Header, decoder *goloxi.Decoder) (*AsyncGetRequest, error) {
+	_asyncgetrequest := &AsyncGetRequest{Header: parent}
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeAsyncConfigProp(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_asyncgetrequest.Properties = append(_asyncgetrequest.Properties, item)
+		}
+	}
+	return _asyncgetrequest, nil
+}
+
+func NewAsyncGetRequest() *AsyncGetRequest {
+	obj := &AsyncGetRequest{
+		Header: NewHeader(26),
+	}
+	return obj
+}
+
+type AsyncSet struct {
+	*Header
+	Properties []IAsyncConfigProp
+}
+
+type IAsyncSet interface {
+	IHeader
+	GetProperties() []IAsyncConfigProp
+}
+
+func (self *AsyncSet) GetProperties() []IAsyncConfigProp {
+	return self.Properties
+}
+
+func (self *AsyncSet) SetProperties(v []IAsyncConfigProp) {
+	self.Properties = v
+}
+
+func (self *AsyncSet) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	for _, obj := range self.Properties {
+		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 DecodeAsyncSet(parent *Header, decoder *goloxi.Decoder) (*AsyncSet, error) {
+	_asyncset := &AsyncSet{Header: parent}
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeAsyncConfigProp(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_asyncset.Properties = append(_asyncset.Properties, item)
+		}
+	}
+	return _asyncset, nil
+}
+
+func NewAsyncSet() *AsyncSet {
+	obj := &AsyncSet{
+		Header: NewHeader(28),
+	}
+	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 BadPropertyErrorMsg struct {
+	*ErrorMsg
+	Code BadPropertyCode
+	Data []byte
+}
+
+type IBadPropertyErrorMsg interface {
+	IErrorMsg
+	GetCode() BadPropertyCode
+	GetData() []byte
+}
+
+func (self *BadPropertyErrorMsg) GetCode() BadPropertyCode {
+	return self.Code
+}
+
+func (self *BadPropertyErrorMsg) SetCode(v BadPropertyCode) {
+	self.Code = v
+}
+
+func (self *BadPropertyErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadPropertyErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadPropertyErrorMsg) 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 DecodeBadPropertyErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadPropertyErrorMsg, error) {
+	_badpropertyerrormsg := &BadPropertyErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadPropertyErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badpropertyerrormsg.Code = BadPropertyCode(decoder.ReadUint16())
+	_badpropertyerrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badpropertyerrormsg, nil
+}
+
+func NewBadPropertyErrorMsg() *BadPropertyErrorMsg {
+	obj := &BadPropertyErrorMsg{
+		ErrorMsg: NewErrorMsg(14),
+	}
+	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
+	Subtype      uint32
+}
+
+type IExperimenter interface {
+	IHeader
+	GetExperimenter() uint32
+	GetSubtype() uint32
+}
+
+func (self *Experimenter) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *Experimenter) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *Experimenter) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *Experimenter) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *Experimenter) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Experimenter))
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeExperimenter(parent *Header, decoder *goloxi.Decoder) (IExperimenter, error) {
+	_experimenter := &Experimenter{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("Experimenter packet too short: %d < 8", decoder.Length())
+	}
+	_experimenter.Experimenter = uint32(decoder.ReadUint32())
+	_experimenter.Subtype = 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
+}
+
+type IBsnHeader interface {
+	IExperimenter
+}
+
+func (self *BsnHeader) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Experimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func DecodeBsnHeader(parent *Experimenter, decoder *goloxi.Decoder) (IBsnHeader, error) {
+	_bsnheader := &BsnHeader{Experimenter: parent}
+
+	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)
+	case 36:
+		return DecodeBsnFlowIdleEnableSetRequest(_bsnheader, decoder)
+	case 37:
+		return DecodeBsnFlowIdleEnableSetReply(_bsnheader, decoder)
+	case 38:
+		return DecodeBsnFlowIdleEnableGetRequest(_bsnheader, decoder)
+	case 39:
+		return DecodeBsnFlowIdleEnableGetReply(_bsnheader, decoder)
+	case 40:
+		return DecodeBsnFlowIdle(_bsnheader, decoder)
+	case 41:
+		return DecodeBsnSetLacpRequest(_bsnheader, decoder)
+	case 42:
+		return DecodeBsnSetLacpReply(_bsnheader, decoder)
+	case 43:
+		return DecodeBsnLacpConvergenceNotif(_bsnheader, decoder)
+	case 44:
+		return DecodeBsnTimeRequest(_bsnheader, decoder)
+	case 45:
+		return DecodeBsnTimeReply(_bsnheader, decoder)
+	case 46:
+		return DecodeBsnGentableEntryAdd(_bsnheader, decoder)
+	case 47:
+		return DecodeBsnGentableEntryDelete(_bsnheader, decoder)
+	case 48:
+		return DecodeBsnGentableClearRequest(_bsnheader, decoder)
+	case 49:
+		return DecodeBsnGentableClearReply(_bsnheader, decoder)
+	case 50:
+		return DecodeBsnGentableSetBucketsSize(_bsnheader, decoder)
+	case 51:
+		return DecodeBsnGetSwitchPipelineRequest(_bsnheader, decoder)
+	case 52:
+		return DecodeBsnGetSwitchPipelineReply(_bsnheader, decoder)
+	case 53:
+		return DecodeBsnSetSwitchPipelineRequest(_bsnheader, decoder)
+	case 54:
+		return DecodeBsnSetSwitchPipelineReply(_bsnheader, decoder)
+	case 56:
+		return DecodeBsnControllerConnectionsRequest(_bsnheader, decoder)
+	case 57:
+		return DecodeBsnControllerConnectionsReply(_bsnheader, decoder)
+	case 58:
+		return DecodeBsnSetAuxCxnsRequest(_bsnheader, decoder)
+	case 59:
+		return DecodeBsnSetAuxCxnsReply(_bsnheader, decoder)
+	case 60:
+		return DecodeBsnArpIdle(_bsnheader, decoder)
+	case 61:
+		return DecodeBsnTableSetBucketsSize(_bsnheader, decoder)
+	case 63:
+		return DecodeBsnLog(_bsnheader, decoder)
+	case 64:
+		return DecodeBsnLuaUpload(_bsnheader, decoder)
+	case 65:
+		return DecodeBsnLuaCommandRequest(_bsnheader, decoder)
+	case 66:
+		return DecodeBsnLuaCommandReply(_bsnheader, decoder)
+	case 67:
+		return DecodeBsnLuaNotification(_bsnheader, decoder)
+	case 68:
+		return DecodeBsnGenericAsync(_bsnheader, decoder)
+	case 69:
+		return DecodeBsnTakeover(_bsnheader, decoder)
+	case 70:
+		return DecodeBsnVlanCounterClear(_bsnheader, decoder)
+	case 71:
+		return DecodeBsnGenericCommand(_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 BsnArpIdle struct {
+	*BsnHeader
+	VlanVid  uint16
+	Ipv4Addr net.IP
+}
+
+type IBsnArpIdle interface {
+	IBsnHeader
+	GetVlanVid() uint16
+	GetIpv4Addr() net.IP
+}
+
+func (self *BsnArpIdle) GetVlanVid() uint16 {
+	return self.VlanVid
+}
+
+func (self *BsnArpIdle) SetVlanVid(v uint16) {
+	self.VlanVid = v
+}
+
+func (self *BsnArpIdle) GetIpv4Addr() net.IP {
+	return self.Ipv4Addr
+}
+
+func (self *BsnArpIdle) SetIpv4Addr(v net.IP) {
+	self.Ipv4Addr = v
+}
+
+func (self *BsnArpIdle) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.VlanVid))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.Write(self.Ipv4Addr.To4())
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnArpIdle(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnArpIdle, error) {
+	_bsnarpidle := &BsnArpIdle{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnArpIdle packet too short: %d < 8", decoder.Length())
+	}
+	_bsnarpidle.VlanVid = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_bsnarpidle.Ipv4Addr = net.IP(decoder.Read(4))
+	return _bsnarpidle, nil
+}
+
+func NewBsnArpIdle() *BsnArpIdle {
+	obj := &BsnArpIdle{
+		BsnHeader: NewBsnHeader(60),
+	}
+	return obj
+}
+
+type ExperimenterErrorMsg struct {
+	*ErrorMsg
+	Subtype      uint16
+	Experimenter uint32
+}
+
+type IExperimenterErrorMsg interface {
+	IErrorMsg
+	GetSubtype() uint16
+	GetExperimenter() uint32
+}
+
+func (self *ExperimenterErrorMsg) GetSubtype() uint16 {
+	return self.Subtype
+}
+
+func (self *ExperimenterErrorMsg) SetSubtype(v uint16) {
+	self.Subtype = v
+}
+
+func (self *ExperimenterErrorMsg) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *ExperimenterErrorMsg) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *ExperimenterErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Subtype))
+	encoder.PutUint32(uint32(self.Experimenter))
+
+	return nil
+}
+
+func DecodeExperimenterErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (IExperimenterErrorMsg, error) {
+	_experimentererrormsg := &ExperimenterErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ExperimenterErrorMsg packet too short: %d < 6", decoder.Length())
+	}
+	_experimentererrormsg.Subtype = uint16(decoder.ReadUint16())
+	_experimentererrormsg.Experimenter = uint32(decoder.ReadUint32())
+
+	switch _experimentererrormsg.Experimenter {
+	case 6035143:
+		return DecodeBsnBaseError(_experimentererrormsg, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'ExperimenterErrorMsg'", _experimentererrormsg.Experimenter)
+	}
+}
+
+func NewExperimenterErrorMsg(_experimenter uint32) *ExperimenterErrorMsg {
+	obj := &ExperimenterErrorMsg{
+		ErrorMsg: NewErrorMsg(65535),
+	}
+	obj.Experimenter = _experimenter
+	return obj
+}
+
+type BsnBaseError struct {
+	*ExperimenterErrorMsg
+	ErrMsg string
+}
+
+type IBsnBaseError interface {
+	IExperimenterErrorMsg
+	GetErrMsg() string
+}
+
+func (self *BsnBaseError) GetErrMsg() string {
+	return self.ErrMsg
+}
+
+func (self *BsnBaseError) SetErrMsg(v string) {
+	self.ErrMsg = v
+}
+
+func (self *BsnBaseError) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write([]byte(self.ErrMsg))
+
+	return nil
+}
+
+func DecodeBsnBaseError(parent *ExperimenterErrorMsg, decoder *goloxi.Decoder) (IBsnBaseError, error) {
+	_bsnbaseerror := &BsnBaseError{ExperimenterErrorMsg: parent}
+	if decoder.Length() < 256 {
+		return nil, fmt.Errorf("BsnBaseError packet too short: %d < 256", decoder.Length())
+	}
+	_bsnbaseerror.ErrMsg = string(bytes.Trim(decoder.Read(256), "\x00"))
+
+	switch _bsnbaseerror.Subtype {
+	case 1:
+		return DecodeBsnError(_bsnbaseerror, decoder)
+	case 2:
+		return DecodeBsnGentableError(_bsnbaseerror, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'BsnBaseError'", _bsnbaseerror.Subtype)
+	}
+}
+
+func NewBsnBaseError(_subtype uint16) *BsnBaseError {
+	obj := &BsnBaseError{
+		ExperimenterErrorMsg: NewExperimenterErrorMsg(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 BsnControllerConnectionsReply struct {
+	*BsnHeader
+	Connections []*BsnControllerConnection
+}
+
+type IBsnControllerConnectionsReply interface {
+	IBsnHeader
+	GetConnections() []*BsnControllerConnection
+}
+
+func (self *BsnControllerConnectionsReply) GetConnections() []*BsnControllerConnection {
+	return self.Connections
+}
+
+func (self *BsnControllerConnectionsReply) SetConnections(v []*BsnControllerConnection) {
+	self.Connections = v
+}
+
+func (self *BsnControllerConnectionsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	for _, obj := range self.Connections {
+		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 DecodeBsnControllerConnectionsReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnControllerConnectionsReply, error) {
+	_bsncontrollerconnectionsreply := &BsnControllerConnectionsReply{BsnHeader: parent}
+
+	for decoder.Length() >= 264 {
+		item, err := DecodeBsnControllerConnection(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsncontrollerconnectionsreply.Connections = append(_bsncontrollerconnectionsreply.Connections, item)
+		}
+	}
+	return _bsncontrollerconnectionsreply, nil
+}
+
+func NewBsnControllerConnectionsReply() *BsnControllerConnectionsReply {
+	obj := &BsnControllerConnectionsReply{
+		BsnHeader: NewBsnHeader(57),
+	}
+	return obj
+}
+
+type BsnControllerConnectionsRequest struct {
+	*BsnHeader
+}
+
+type IBsnControllerConnectionsRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnControllerConnectionsRequest) 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 DecodeBsnControllerConnectionsRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnControllerConnectionsRequest, error) {
+	_bsncontrollerconnectionsrequest := &BsnControllerConnectionsRequest{BsnHeader: parent}
+	return _bsncontrollerconnectionsrequest, nil
+}
+
+func NewBsnControllerConnectionsRequest() *BsnControllerConnectionsRequest {
+	obj := &BsnControllerConnectionsRequest{
+		BsnHeader: NewBsnHeader(56),
+	}
+	return obj
+}
+
+type ExperimenterStatsReply struct {
+	*StatsReply
+	Experimenter uint32
+	Subtype      uint32
+}
+
+type IExperimenterStatsReply interface {
+	IStatsReply
+	GetExperimenter() uint32
+	GetSubtype() uint32
+}
+
+func (self *ExperimenterStatsReply) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *ExperimenterStatsReply) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *ExperimenterStatsReply) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *ExperimenterStatsReply) SetSubtype(v uint32) {
+	self.Subtype = 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.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeExperimenterStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (IExperimenterStatsReply, error) {
+	_experimenterstatsreply := &ExperimenterStatsReply{StatsReply: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("ExperimenterStatsReply packet too short: %d < 12", decoder.Length())
+	}
+	decoder.Skip(4)
+	_experimenterstatsreply.Experimenter = uint32(decoder.ReadUint32())
+	_experimenterstatsreply.Subtype = uint32(decoder.ReadUint32())
+
+	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
+}
+
+type IBsnStatsReply interface {
+	IExperimenterStatsReply
+}
+
+func (self *BsnStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func DecodeBsnStatsReply(parent *ExperimenterStatsReply, decoder *goloxi.Decoder) (IBsnStatsReply, error) {
+	_bsnstatsreply := &BsnStatsReply{ExperimenterStatsReply: parent}
+
+	switch _bsnstatsreply.Subtype {
+	case 1:
+		return DecodeBsnLacpStatsReply(_bsnstatsreply, decoder)
+	case 2:
+		return DecodeBsnGentableEntryDescStatsReply(_bsnstatsreply, decoder)
+	case 3:
+		return DecodeBsnGentableEntryStatsReply(_bsnstatsreply, decoder)
+	case 4:
+		return DecodeBsnGentableDescStatsReply(_bsnstatsreply, decoder)
+	case 5:
+		return DecodeBsnGentableBucketStatsReply(_bsnstatsreply, decoder)
+	case 6:
+		return DecodeBsnSwitchPipelineStatsReply(_bsnstatsreply, decoder)
+	case 7:
+		return DecodeBsnGentableStatsReply(_bsnstatsreply, decoder)
+	case 8:
+		return DecodeBsnPortCounterStatsReply(_bsnstatsreply, decoder)
+	case 9:
+		return DecodeBsnVlanCounterStatsReply(_bsnstatsreply, decoder)
+	case 10:
+		return DecodeBsnFlowChecksumBucketStatsReply(_bsnstatsreply, decoder)
+	case 11:
+		return DecodeBsnTableChecksumStatsReply(_bsnstatsreply, decoder)
+	case 12:
+		return DecodeBsnDebugCounterStatsReply(_bsnstatsreply, decoder)
+	case 13:
+		return DecodeBsnDebugCounterDescStatsReply(_bsnstatsreply, decoder)
+	case 14:
+		return DecodeBsnImageDescStatsReply(_bsnstatsreply, decoder)
+	case 15:
+		return DecodeBsnVrfCounterStatsReply(_bsnstatsreply, decoder)
+	case 16:
+		return DecodeBsnGenericStatsReply(_bsnstatsreply, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'BsnStatsReply'", _bsnstatsreply.Subtype)
+	}
+}
+
+func NewBsnStatsReply(_subtype uint32) *BsnStatsReply {
+	obj := &BsnStatsReply{
+		ExperimenterStatsReply: NewExperimenterStatsReply(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type BsnDebugCounterDescStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnDebugCounterDescStatsEntry
+}
+
+type IBsnDebugCounterDescStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnDebugCounterDescStatsEntry
+}
+
+func (self *BsnDebugCounterDescStatsReply) GetEntries() []*BsnDebugCounterDescStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnDebugCounterDescStatsReply) SetEntries(v []*BsnDebugCounterDescStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnDebugCounterDescStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnDebugCounterDescStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnDebugCounterDescStatsReply, error) {
+	_bsndebugcounterdescstatsreply := &BsnDebugCounterDescStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 328 {
+		item, err := DecodeBsnDebugCounterDescStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsndebugcounterdescstatsreply.Entries = append(_bsndebugcounterdescstatsreply.Entries, item)
+		}
+	}
+	return _bsndebugcounterdescstatsreply, nil
+}
+
+func NewBsnDebugCounterDescStatsReply() *BsnDebugCounterDescStatsReply {
+	obj := &BsnDebugCounterDescStatsReply{
+		BsnStatsReply: NewBsnStatsReply(13),
+	}
+	return obj
+}
+
+type ExperimenterStatsRequest struct {
+	*StatsRequest
+	Experimenter uint32
+	Subtype      uint32
+}
+
+type IExperimenterStatsRequest interface {
+	IStatsRequest
+	GetExperimenter() uint32
+	GetSubtype() uint32
+}
+
+func (self *ExperimenterStatsRequest) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *ExperimenterStatsRequest) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *ExperimenterStatsRequest) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *ExperimenterStatsRequest) SetSubtype(v uint32) {
+	self.Subtype = 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.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeExperimenterStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (IExperimenterStatsRequest, error) {
+	_experimenterstatsrequest := &ExperimenterStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("ExperimenterStatsRequest packet too short: %d < 12", decoder.Length())
+	}
+	decoder.Skip(4)
+	_experimenterstatsrequest.Experimenter = uint32(decoder.ReadUint32())
+	_experimenterstatsrequest.Subtype = uint32(decoder.ReadUint32())
+
+	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
+}
+
+type IBsnStatsRequest interface {
+	IExperimenterStatsRequest
+}
+
+func (self *BsnStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func DecodeBsnStatsRequest(parent *ExperimenterStatsRequest, decoder *goloxi.Decoder) (IBsnStatsRequest, error) {
+	_bsnstatsrequest := &BsnStatsRequest{ExperimenterStatsRequest: parent}
+
+	switch _bsnstatsrequest.Subtype {
+	case 1:
+		return DecodeBsnLacpStatsRequest(_bsnstatsrequest, decoder)
+	case 2:
+		return DecodeBsnGentableEntryDescStatsRequest(_bsnstatsrequest, decoder)
+	case 3:
+		return DecodeBsnGentableEntryStatsRequest(_bsnstatsrequest, decoder)
+	case 4:
+		return DecodeBsnGentableDescStatsRequest(_bsnstatsrequest, decoder)
+	case 5:
+		return DecodeBsnGentableBucketStatsRequest(_bsnstatsrequest, decoder)
+	case 6:
+		return DecodeBsnSwitchPipelineStatsRequest(_bsnstatsrequest, decoder)
+	case 7:
+		return DecodeBsnGentableStatsRequest(_bsnstatsrequest, decoder)
+	case 8:
+		return DecodeBsnPortCounterStatsRequest(_bsnstatsrequest, decoder)
+	case 9:
+		return DecodeBsnVlanCounterStatsRequest(_bsnstatsrequest, decoder)
+	case 10:
+		return DecodeBsnFlowChecksumBucketStatsRequest(_bsnstatsrequest, decoder)
+	case 11:
+		return DecodeBsnTableChecksumStatsRequest(_bsnstatsrequest, decoder)
+	case 12:
+		return DecodeBsnDebugCounterStatsRequest(_bsnstatsrequest, decoder)
+	case 13:
+		return DecodeBsnDebugCounterDescStatsRequest(_bsnstatsrequest, decoder)
+	case 14:
+		return DecodeBsnImageDescStatsRequest(_bsnstatsrequest, decoder)
+	case 15:
+		return DecodeBsnVrfCounterStatsRequest(_bsnstatsrequest, decoder)
+	case 16:
+		return DecodeBsnGenericStatsRequest(_bsnstatsrequest, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'BsnStatsRequest'", _bsnstatsrequest.Subtype)
+	}
+}
+
+func NewBsnStatsRequest(_subtype uint32) *BsnStatsRequest {
+	obj := &BsnStatsRequest{
+		ExperimenterStatsRequest: NewExperimenterStatsRequest(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type BsnDebugCounterDescStatsRequest struct {
+	*BsnStatsRequest
+}
+
+type IBsnDebugCounterDescStatsRequest interface {
+	IBsnStatsRequest
+}
+
+func (self *BsnDebugCounterDescStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.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 DecodeBsnDebugCounterDescStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnDebugCounterDescStatsRequest, error) {
+	_bsndebugcounterdescstatsrequest := &BsnDebugCounterDescStatsRequest{BsnStatsRequest: parent}
+	return _bsndebugcounterdescstatsrequest, nil
+}
+
+func NewBsnDebugCounterDescStatsRequest() *BsnDebugCounterDescStatsRequest {
+	obj := &BsnDebugCounterDescStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(13),
+	}
+	return obj
+}
+
+type BsnDebugCounterStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnDebugCounterStatsEntry
+}
+
+type IBsnDebugCounterStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnDebugCounterStatsEntry
+}
+
+func (self *BsnDebugCounterStatsReply) GetEntries() []*BsnDebugCounterStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnDebugCounterStatsReply) SetEntries(v []*BsnDebugCounterStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnDebugCounterStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnDebugCounterStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnDebugCounterStatsReply, error) {
+	_bsndebugcounterstatsreply := &BsnDebugCounterStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 16 {
+		item, err := DecodeBsnDebugCounterStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsndebugcounterstatsreply.Entries = append(_bsndebugcounterstatsreply.Entries, item)
+		}
+	}
+	return _bsndebugcounterstatsreply, nil
+}
+
+func NewBsnDebugCounterStatsReply() *BsnDebugCounterStatsReply {
+	obj := &BsnDebugCounterStatsReply{
+		BsnStatsReply: NewBsnStatsReply(12),
+	}
+	return obj
+}
+
+type BsnDebugCounterStatsRequest struct {
+	*BsnStatsRequest
+}
+
+type IBsnDebugCounterStatsRequest interface {
+	IBsnStatsRequest
+}
+
+func (self *BsnDebugCounterStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.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 DecodeBsnDebugCounterStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnDebugCounterStatsRequest, error) {
+	_bsndebugcounterstatsrequest := &BsnDebugCounterStatsRequest{BsnStatsRequest: parent}
+	return _bsndebugcounterstatsrequest, nil
+}
+
+func NewBsnDebugCounterStatsRequest() *BsnDebugCounterStatsRequest {
+	obj := &BsnDebugCounterStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(12),
+	}
+	return obj
+}
+
+type BsnError struct {
+	*BsnBaseError
+}
+
+type IBsnError interface {
+	IBsnBaseError
+}
+
+func (self *BsnError) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnBaseError.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 DecodeBsnError(parent *BsnBaseError, decoder *goloxi.Decoder) (*BsnError, error) {
+	_bsnerror := &BsnError{BsnBaseError: parent}
+	return _bsnerror, nil
+}
+
+func NewBsnError() *BsnError {
+	obj := &BsnError{
+		BsnBaseError: NewBsnBaseError(1),
+	}
+	return obj
+}
+
+type BsnFlowChecksumBucketStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnFlowChecksumBucketStatsEntry
+}
+
+type IBsnFlowChecksumBucketStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnFlowChecksumBucketStatsEntry
+}
+
+func (self *BsnFlowChecksumBucketStatsReply) GetEntries() []*BsnFlowChecksumBucketStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnFlowChecksumBucketStatsReply) SetEntries(v []*BsnFlowChecksumBucketStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnFlowChecksumBucketStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnFlowChecksumBucketStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnFlowChecksumBucketStatsReply, error) {
+	_bsnflowchecksumbucketstatsreply := &BsnFlowChecksumBucketStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeBsnFlowChecksumBucketStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsnflowchecksumbucketstatsreply.Entries = append(_bsnflowchecksumbucketstatsreply.Entries, item)
+		}
+	}
+	return _bsnflowchecksumbucketstatsreply, nil
+}
+
+func NewBsnFlowChecksumBucketStatsReply() *BsnFlowChecksumBucketStatsReply {
+	obj := &BsnFlowChecksumBucketStatsReply{
+		BsnStatsReply: NewBsnStatsReply(10),
+	}
+	return obj
+}
+
+type BsnFlowChecksumBucketStatsRequest struct {
+	*BsnStatsRequest
+	TableId uint8
+}
+
+type IBsnFlowChecksumBucketStatsRequest interface {
+	IBsnStatsRequest
+	GetTableId() uint8
+}
+
+func (self *BsnFlowChecksumBucketStatsRequest) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *BsnFlowChecksumBucketStatsRequest) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *BsnFlowChecksumBucketStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.TableId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnFlowChecksumBucketStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnFlowChecksumBucketStatsRequest, error) {
+	_bsnflowchecksumbucketstatsrequest := &BsnFlowChecksumBucketStatsRequest{BsnStatsRequest: parent}
+	if decoder.Length() < 1 {
+		return nil, fmt.Errorf("BsnFlowChecksumBucketStatsRequest packet too short: %d < 1", decoder.Length())
+	}
+	_bsnflowchecksumbucketstatsrequest.TableId = uint8(decoder.ReadByte())
+	return _bsnflowchecksumbucketstatsrequest, nil
+}
+
+func NewBsnFlowChecksumBucketStatsRequest() *BsnFlowChecksumBucketStatsRequest {
+	obj := &BsnFlowChecksumBucketStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(10),
+	}
+	return obj
+}
+
+type BsnFlowIdle struct {
+	*BsnHeader
+	Cookie   uint64
+	Priority uint16
+	TableId  uint8
+	Match    Match
+}
+
+type IBsnFlowIdle interface {
+	IBsnHeader
+	GetCookie() uint64
+	GetPriority() uint16
+	GetTableId() uint8
+	GetMatch() Match
+}
+
+func (self *BsnFlowIdle) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *BsnFlowIdle) SetCookie(v uint64) {
+	self.Cookie = v
+}
+
+func (self *BsnFlowIdle) GetPriority() uint16 {
+	return self.Priority
+}
+
+func (self *BsnFlowIdle) SetPriority(v uint16) {
+	self.Priority = v
+}
+
+func (self *BsnFlowIdle) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *BsnFlowIdle) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *BsnFlowIdle) GetMatch() Match {
+	return self.Match
+}
+
+func (self *BsnFlowIdle) SetMatch(v Match) {
+	self.Match = v
+}
+
+func (self *BsnFlowIdle) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.Cookie))
+	encoder.PutUint16(uint16(self.Priority))
+	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 DecodeBsnFlowIdle(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnFlowIdle, error) {
+	_bsnflowidle := &BsnFlowIdle{BsnHeader: parent}
+	if decoder.Length() < 24 {
+		return nil, fmt.Errorf("BsnFlowIdle packet too short: %d < 24", decoder.Length())
+	}
+	_bsnflowidle.Cookie = uint64(decoder.ReadUint64())
+	_bsnflowidle.Priority = uint16(decoder.ReadUint16())
+	_bsnflowidle.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(5)
+	if err := _bsnflowidle.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	decoder.SkipAlign()
+	return _bsnflowidle, nil
+}
+
+func NewBsnFlowIdle() *BsnFlowIdle {
+	obj := &BsnFlowIdle{
+		BsnHeader: NewBsnHeader(40),
+	}
+	return obj
+}
+
+type BsnFlowIdleEnableGetReply struct {
+	*BsnHeader
+	Enabled uint32
+}
+
+type IBsnFlowIdleEnableGetReply interface {
+	IBsnHeader
+	GetEnabled() uint32
+}
+
+func (self *BsnFlowIdleEnableGetReply) GetEnabled() uint32 {
+	return self.Enabled
+}
+
+func (self *BsnFlowIdleEnableGetReply) SetEnabled(v uint32) {
+	self.Enabled = v
+}
+
+func (self *BsnFlowIdleEnableGetReply) 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 DecodeBsnFlowIdleEnableGetReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnFlowIdleEnableGetReply, error) {
+	_bsnflowidleenablegetreply := &BsnFlowIdleEnableGetReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnFlowIdleEnableGetReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnflowidleenablegetreply.Enabled = uint32(decoder.ReadUint32())
+	return _bsnflowidleenablegetreply, nil
+}
+
+func NewBsnFlowIdleEnableGetReply() *BsnFlowIdleEnableGetReply {
+	obj := &BsnFlowIdleEnableGetReply{
+		BsnHeader: NewBsnHeader(39),
+	}
+	return obj
+}
+
+type BsnFlowIdleEnableGetRequest struct {
+	*BsnHeader
+}
+
+type IBsnFlowIdleEnableGetRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnFlowIdleEnableGetRequest) 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 DecodeBsnFlowIdleEnableGetRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnFlowIdleEnableGetRequest, error) {
+	_bsnflowidleenablegetrequest := &BsnFlowIdleEnableGetRequest{BsnHeader: parent}
+	return _bsnflowidleenablegetrequest, nil
+}
+
+func NewBsnFlowIdleEnableGetRequest() *BsnFlowIdleEnableGetRequest {
+	obj := &BsnFlowIdleEnableGetRequest{
+		BsnHeader: NewBsnHeader(38),
+	}
+	return obj
+}
+
+type BsnFlowIdleEnableSetReply struct {
+	*BsnHeader
+	Enable uint32
+	Status uint32
+}
+
+type IBsnFlowIdleEnableSetReply interface {
+	IBsnHeader
+	GetEnable() uint32
+	GetStatus() uint32
+}
+
+func (self *BsnFlowIdleEnableSetReply) GetEnable() uint32 {
+	return self.Enable
+}
+
+func (self *BsnFlowIdleEnableSetReply) SetEnable(v uint32) {
+	self.Enable = v
+}
+
+func (self *BsnFlowIdleEnableSetReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnFlowIdleEnableSetReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnFlowIdleEnableSetReply) 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 DecodeBsnFlowIdleEnableSetReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnFlowIdleEnableSetReply, error) {
+	_bsnflowidleenablesetreply := &BsnFlowIdleEnableSetReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnFlowIdleEnableSetReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnflowidleenablesetreply.Enable = uint32(decoder.ReadUint32())
+	_bsnflowidleenablesetreply.Status = uint32(decoder.ReadUint32())
+	return _bsnflowidleenablesetreply, nil
+}
+
+func NewBsnFlowIdleEnableSetReply() *BsnFlowIdleEnableSetReply {
+	obj := &BsnFlowIdleEnableSetReply{
+		BsnHeader: NewBsnHeader(37),
+	}
+	return obj
+}
+
+type BsnFlowIdleEnableSetRequest struct {
+	*BsnHeader
+	Enable uint32
+}
+
+type IBsnFlowIdleEnableSetRequest interface {
+	IBsnHeader
+	GetEnable() uint32
+}
+
+func (self *BsnFlowIdleEnableSetRequest) GetEnable() uint32 {
+	return self.Enable
+}
+
+func (self *BsnFlowIdleEnableSetRequest) SetEnable(v uint32) {
+	self.Enable = v
+}
+
+func (self *BsnFlowIdleEnableSetRequest) 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 DecodeBsnFlowIdleEnableSetRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnFlowIdleEnableSetRequest, error) {
+	_bsnflowidleenablesetrequest := &BsnFlowIdleEnableSetRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnFlowIdleEnableSetRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnflowidleenablesetrequest.Enable = uint32(decoder.ReadUint32())
+	return _bsnflowidleenablesetrequest, nil
+}
+
+func NewBsnFlowIdleEnableSetRequest() *BsnFlowIdleEnableSetRequest {
+	obj := &BsnFlowIdleEnableSetRequest{
+		BsnHeader: NewBsnHeader(36),
+	}
+	return obj
+}
+
+type BsnGenericAsync struct {
+	*BsnHeader
+	Name string
+	Tlvs []IBsnTlv
+}
+
+type IBsnGenericAsync interface {
+	IBsnHeader
+	GetName() string
+	GetTlvs() []IBsnTlv
+}
+
+func (self *BsnGenericAsync) GetName() string {
+	return self.Name
+}
+
+func (self *BsnGenericAsync) SetName(v string) {
+	self.Name = v
+}
+
+func (self *BsnGenericAsync) GetTlvs() []IBsnTlv {
+	return self.Tlvs
+}
+
+func (self *BsnGenericAsync) SetTlvs(v []IBsnTlv) {
+	self.Tlvs = v
+}
+
+func (self *BsnGenericAsync) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write([]byte(self.Name))
+	for _, obj := range self.Tlvs {
+		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 DecodeBsnGenericAsync(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGenericAsync, error) {
+	_bsngenericasync := &BsnGenericAsync{BsnHeader: parent}
+	if decoder.Length() < 64 {
+		return nil, fmt.Errorf("BsnGenericAsync packet too short: %d < 64", decoder.Length())
+	}
+	_bsngenericasync.Name = string(bytes.Trim(decoder.Read(64), "\x00"))
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeBsnTlv(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngenericasync.Tlvs = append(_bsngenericasync.Tlvs, item)
+		}
+	}
+	return _bsngenericasync, nil
+}
+
+func NewBsnGenericAsync() *BsnGenericAsync {
+	obj := &BsnGenericAsync{
+		BsnHeader: NewBsnHeader(68),
+	}
+	return obj
+}
+
+type BsnGenericCommand struct {
+	*BsnHeader
+	Name string
+	Tlvs []IBsnTlv
+}
+
+type IBsnGenericCommand interface {
+	IBsnHeader
+	GetName() string
+	GetTlvs() []IBsnTlv
+}
+
+func (self *BsnGenericCommand) GetName() string {
+	return self.Name
+}
+
+func (self *BsnGenericCommand) SetName(v string) {
+	self.Name = v
+}
+
+func (self *BsnGenericCommand) GetTlvs() []IBsnTlv {
+	return self.Tlvs
+}
+
+func (self *BsnGenericCommand) SetTlvs(v []IBsnTlv) {
+	self.Tlvs = v
+}
+
+func (self *BsnGenericCommand) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write([]byte(self.Name))
+	for _, obj := range self.Tlvs {
+		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 DecodeBsnGenericCommand(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGenericCommand, error) {
+	_bsngenericcommand := &BsnGenericCommand{BsnHeader: parent}
+	if decoder.Length() < 64 {
+		return nil, fmt.Errorf("BsnGenericCommand packet too short: %d < 64", decoder.Length())
+	}
+	_bsngenericcommand.Name = string(bytes.Trim(decoder.Read(64), "\x00"))
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeBsnTlv(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngenericcommand.Tlvs = append(_bsngenericcommand.Tlvs, item)
+		}
+	}
+	return _bsngenericcommand, nil
+}
+
+func NewBsnGenericCommand() *BsnGenericCommand {
+	obj := &BsnGenericCommand{
+		BsnHeader: NewBsnHeader(71),
+	}
+	return obj
+}
+
+type BsnGenericStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnGenericStatsEntry
+}
+
+type IBsnGenericStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnGenericStatsEntry
+}
+
+func (self *BsnGenericStatsReply) GetEntries() []*BsnGenericStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnGenericStatsReply) SetEntries(v []*BsnGenericStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnGenericStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnGenericStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnGenericStatsReply, error) {
+	_bsngenericstatsreply := &BsnGenericStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 2 {
+		item, err := DecodeBsnGenericStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngenericstatsreply.Entries = append(_bsngenericstatsreply.Entries, item)
+		}
+	}
+	return _bsngenericstatsreply, nil
+}
+
+func NewBsnGenericStatsReply() *BsnGenericStatsReply {
+	obj := &BsnGenericStatsReply{
+		BsnStatsReply: NewBsnStatsReply(16),
+	}
+	return obj
+}
+
+type BsnGenericStatsRequest struct {
+	*BsnStatsRequest
+	Name string
+	Tlvs []IBsnTlv
+}
+
+type IBsnGenericStatsRequest interface {
+	IBsnStatsRequest
+	GetName() string
+	GetTlvs() []IBsnTlv
+}
+
+func (self *BsnGenericStatsRequest) GetName() string {
+	return self.Name
+}
+
+func (self *BsnGenericStatsRequest) SetName(v string) {
+	self.Name = v
+}
+
+func (self *BsnGenericStatsRequest) GetTlvs() []IBsnTlv {
+	return self.Tlvs
+}
+
+func (self *BsnGenericStatsRequest) SetTlvs(v []IBsnTlv) {
+	self.Tlvs = v
+}
+
+func (self *BsnGenericStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write([]byte(self.Name))
+	for _, obj := range self.Tlvs {
+		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 DecodeBsnGenericStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnGenericStatsRequest, error) {
+	_bsngenericstatsrequest := &BsnGenericStatsRequest{BsnStatsRequest: parent}
+	if decoder.Length() < 64 {
+		return nil, fmt.Errorf("BsnGenericStatsRequest packet too short: %d < 64", decoder.Length())
+	}
+	_bsngenericstatsrequest.Name = string(bytes.Trim(decoder.Read(64), "\x00"))
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeBsnTlv(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngenericstatsrequest.Tlvs = append(_bsngenericstatsrequest.Tlvs, item)
+		}
+	}
+	return _bsngenericstatsrequest, nil
+}
+
+func NewBsnGenericStatsRequest() *BsnGenericStatsRequest {
+	obj := &BsnGenericStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(16),
+	}
+	return obj
+}
+
+type BsnGentableBucketStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnGentableBucketStatsEntry
+}
+
+type IBsnGentableBucketStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnGentableBucketStatsEntry
+}
+
+func (self *BsnGentableBucketStatsReply) GetEntries() []*BsnGentableBucketStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnGentableBucketStatsReply) SetEntries(v []*BsnGentableBucketStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnGentableBucketStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnGentableBucketStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnGentableBucketStatsReply, error) {
+	_bsngentablebucketstatsreply := &BsnGentableBucketStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 16 {
+		item, err := DecodeBsnGentableBucketStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngentablebucketstatsreply.Entries = append(_bsngentablebucketstatsreply.Entries, item)
+		}
+	}
+	return _bsngentablebucketstatsreply, nil
+}
+
+func NewBsnGentableBucketStatsReply() *BsnGentableBucketStatsReply {
+	obj := &BsnGentableBucketStatsReply{
+		BsnStatsReply: NewBsnStatsReply(5),
+	}
+	return obj
+}
+
+type BsnGentableBucketStatsRequest struct {
+	*BsnStatsRequest
+	TableId uint16
+}
+
+type IBsnGentableBucketStatsRequest interface {
+	IBsnStatsRequest
+	GetTableId() uint16
+}
+
+func (self *BsnGentableBucketStatsRequest) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableBucketStatsRequest) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableBucketStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.TableId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGentableBucketStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnGentableBucketStatsRequest, error) {
+	_bsngentablebucketstatsrequest := &BsnGentableBucketStatsRequest{BsnStatsRequest: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BsnGentableBucketStatsRequest packet too short: %d < 2", decoder.Length())
+	}
+	_bsngentablebucketstatsrequest.TableId = uint16(decoder.ReadUint16())
+	return _bsngentablebucketstatsrequest, nil
+}
+
+func NewBsnGentableBucketStatsRequest() *BsnGentableBucketStatsRequest {
+	obj := &BsnGentableBucketStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(5),
+	}
+	return obj
+}
+
+type BsnGentableClearReply struct {
+	*BsnHeader
+	TableId      uint16
+	DeletedCount uint32
+	ErrorCount   uint32
+}
+
+type IBsnGentableClearReply interface {
+	IBsnHeader
+	GetTableId() uint16
+	GetDeletedCount() uint32
+	GetErrorCount() uint32
+}
+
+func (self *BsnGentableClearReply) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableClearReply) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableClearReply) GetDeletedCount() uint32 {
+	return self.DeletedCount
+}
+
+func (self *BsnGentableClearReply) SetDeletedCount(v uint32) {
+	self.DeletedCount = v
+}
+
+func (self *BsnGentableClearReply) GetErrorCount() uint32 {
+	return self.ErrorCount
+}
+
+func (self *BsnGentableClearReply) SetErrorCount(v uint32) {
+	self.ErrorCount = v
+}
+
+func (self *BsnGentableClearReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint32(uint32(self.DeletedCount))
+	encoder.PutUint32(uint32(self.ErrorCount))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGentableClearReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGentableClearReply, error) {
+	_bsngentableclearreply := &BsnGentableClearReply{BsnHeader: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("BsnGentableClearReply packet too short: %d < 12", decoder.Length())
+	}
+	_bsngentableclearreply.TableId = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_bsngentableclearreply.DeletedCount = uint32(decoder.ReadUint32())
+	_bsngentableclearreply.ErrorCount = uint32(decoder.ReadUint32())
+	return _bsngentableclearreply, nil
+}
+
+func NewBsnGentableClearReply() *BsnGentableClearReply {
+	obj := &BsnGentableClearReply{
+		BsnHeader: NewBsnHeader(49),
+	}
+	return obj
+}
+
+type BsnGentableClearRequest struct {
+	*BsnHeader
+	TableId      uint16
+	Checksum     Checksum128
+	ChecksumMask Checksum128
+}
+
+type IBsnGentableClearRequest interface {
+	IBsnHeader
+	GetTableId() uint16
+	GetChecksum() Checksum128
+	GetChecksumMask() Checksum128
+}
+
+func (self *BsnGentableClearRequest) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableClearRequest) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableClearRequest) GetChecksum() Checksum128 {
+	return self.Checksum
+}
+
+func (self *BsnGentableClearRequest) SetChecksum(v Checksum128) {
+	self.Checksum = v
+}
+
+func (self *BsnGentableClearRequest) GetChecksumMask() Checksum128 {
+	return self.ChecksumMask
+}
+
+func (self *BsnGentableClearRequest) SetChecksumMask(v Checksum128) {
+	self.ChecksumMask = v
+}
+
+func (self *BsnGentableClearRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	self.Checksum.Serialize(encoder)
+	self.ChecksumMask.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGentableClearRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGentableClearRequest, error) {
+	_bsngentableclearrequest := &BsnGentableClearRequest{BsnHeader: parent}
+	if decoder.Length() < 36 {
+		return nil, fmt.Errorf("BsnGentableClearRequest packet too short: %d < 36", decoder.Length())
+	}
+	_bsngentableclearrequest.TableId = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_bsngentableclearrequest.Checksum.Decode(decoder)
+	_bsngentableclearrequest.ChecksumMask.Decode(decoder)
+	return _bsngentableclearrequest, nil
+}
+
+func NewBsnGentableClearRequest() *BsnGentableClearRequest {
+	obj := &BsnGentableClearRequest{
+		BsnHeader: NewBsnHeader(48),
+	}
+	return obj
+}
+
+type BsnGentableDescStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnGentableDescStatsEntry
+}
+
+type IBsnGentableDescStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnGentableDescStatsEntry
+}
+
+func (self *BsnGentableDescStatsReply) GetEntries() []*BsnGentableDescStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnGentableDescStatsReply) SetEntries(v []*BsnGentableDescStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnGentableDescStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnGentableDescStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnGentableDescStatsReply, error) {
+	_bsngentabledescstatsreply := &BsnGentableDescStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 48 {
+		item, err := DecodeBsnGentableDescStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngentabledescstatsreply.Entries = append(_bsngentabledescstatsreply.Entries, item)
+		}
+	}
+	return _bsngentabledescstatsreply, nil
+}
+
+func NewBsnGentableDescStatsReply() *BsnGentableDescStatsReply {
+	obj := &BsnGentableDescStatsReply{
+		BsnStatsReply: NewBsnStatsReply(4),
+	}
+	return obj
+}
+
+type BsnGentableDescStatsRequest struct {
+	*BsnStatsRequest
+}
+
+type IBsnGentableDescStatsRequest interface {
+	IBsnStatsRequest
+}
+
+func (self *BsnGentableDescStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.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 DecodeBsnGentableDescStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnGentableDescStatsRequest, error) {
+	_bsngentabledescstatsrequest := &BsnGentableDescStatsRequest{BsnStatsRequest: parent}
+	return _bsngentabledescstatsrequest, nil
+}
+
+func NewBsnGentableDescStatsRequest() *BsnGentableDescStatsRequest {
+	obj := &BsnGentableDescStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(4),
+	}
+	return obj
+}
+
+type BsnGentableEntryAdd struct {
+	*BsnHeader
+	TableId   uint16
+	KeyLength uint16
+	Checksum  Checksum128
+	Key       []IBsnTlv
+	Value     []IBsnTlv
+}
+
+type IBsnGentableEntryAdd interface {
+	IBsnHeader
+	GetTableId() uint16
+	GetKeyLength() uint16
+	GetChecksum() Checksum128
+	GetKey() []IBsnTlv
+	GetValue() []IBsnTlv
+}
+
+func (self *BsnGentableEntryAdd) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableEntryAdd) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableEntryAdd) GetKeyLength() uint16 {
+	return self.KeyLength
+}
+
+func (self *BsnGentableEntryAdd) SetKeyLength(v uint16) {
+	self.KeyLength = v
+}
+
+func (self *BsnGentableEntryAdd) GetChecksum() Checksum128 {
+	return self.Checksum
+}
+
+func (self *BsnGentableEntryAdd) SetChecksum(v Checksum128) {
+	self.Checksum = v
+}
+
+func (self *BsnGentableEntryAdd) GetKey() []IBsnTlv {
+	return self.Key
+}
+
+func (self *BsnGentableEntryAdd) SetKey(v []IBsnTlv) {
+	self.Key = v
+}
+
+func (self *BsnGentableEntryAdd) GetValue() []IBsnTlv {
+	return self.Value
+}
+
+func (self *BsnGentableEntryAdd) SetValue(v []IBsnTlv) {
+	self.Value = v
+}
+
+func (self *BsnGentableEntryAdd) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.TableId))
+	encoder.PutUint16(uint16(self.KeyLength))
+	self.Checksum.Serialize(encoder)
+	for _, obj := range self.Key {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	for _, obj := range self.Value {
+		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 DecodeBsnGentableEntryAdd(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGentableEntryAdd, error) {
+	_bsngentableentryadd := &BsnGentableEntryAdd{BsnHeader: parent}
+	if decoder.Length() < 20 {
+		return nil, fmt.Errorf("BsnGentableEntryAdd packet too short: %d < 20", decoder.Length())
+	}
+	_bsngentableentryadd.TableId = uint16(decoder.ReadUint16())
+	_bsngentableentryadd.KeyLength = uint16(decoder.ReadUint16())
+	_bsngentableentryadd.Checksum.Decode(decoder)
+
+	end := decoder.Offset() + int(_bsngentableentryadd.KeyLength)
+	for decoder.Offset() < end {
+		item, err := DecodeBsnTlv(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngentableentryadd.Key = append(_bsngentableentryadd.Key, item)
+		}
+	}
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeBsnTlv(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngentableentryadd.Value = append(_bsngentableentryadd.Value, item)
+		}
+	}
+	return _bsngentableentryadd, nil
+}
+
+func NewBsnGentableEntryAdd() *BsnGentableEntryAdd {
+	obj := &BsnGentableEntryAdd{
+		BsnHeader: NewBsnHeader(46),
+	}
+	return obj
+}
+
+type BsnGentableEntryDelete struct {
+	*BsnHeader
+	TableId uint16
+	Key     []IBsnTlv
+}
+
+type IBsnGentableEntryDelete interface {
+	IBsnHeader
+	GetTableId() uint16
+	GetKey() []IBsnTlv
+}
+
+func (self *BsnGentableEntryDelete) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableEntryDelete) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableEntryDelete) GetKey() []IBsnTlv {
+	return self.Key
+}
+
+func (self *BsnGentableEntryDelete) SetKey(v []IBsnTlv) {
+	self.Key = v
+}
+
+func (self *BsnGentableEntryDelete) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.TableId))
+	for _, obj := range self.Key {
+		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 DecodeBsnGentableEntryDelete(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGentableEntryDelete, error) {
+	_bsngentableentrydelete := &BsnGentableEntryDelete{BsnHeader: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BsnGentableEntryDelete packet too short: %d < 2", decoder.Length())
+	}
+	_bsngentableentrydelete.TableId = uint16(decoder.ReadUint16())
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeBsnTlv(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngentableentrydelete.Key = append(_bsngentableentrydelete.Key, item)
+		}
+	}
+	return _bsngentableentrydelete, nil
+}
+
+func NewBsnGentableEntryDelete() *BsnGentableEntryDelete {
+	obj := &BsnGentableEntryDelete{
+		BsnHeader: NewBsnHeader(47),
+	}
+	return obj
+}
+
+type BsnGentableEntryDescStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnGentableEntryDescStatsEntry
+}
+
+type IBsnGentableEntryDescStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnGentableEntryDescStatsEntry
+}
+
+func (self *BsnGentableEntryDescStatsReply) GetEntries() []*BsnGentableEntryDescStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnGentableEntryDescStatsReply) SetEntries(v []*BsnGentableEntryDescStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnGentableEntryDescStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnGentableEntryDescStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnGentableEntryDescStatsReply, error) {
+	_bsngentableentrydescstatsreply := &BsnGentableEntryDescStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 20 {
+		item, err := DecodeBsnGentableEntryDescStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngentableentrydescstatsreply.Entries = append(_bsngentableentrydescstatsreply.Entries, item)
+		}
+	}
+	return _bsngentableentrydescstatsreply, nil
+}
+
+func NewBsnGentableEntryDescStatsReply() *BsnGentableEntryDescStatsReply {
+	obj := &BsnGentableEntryDescStatsReply{
+		BsnStatsReply: NewBsnStatsReply(2),
+	}
+	return obj
+}
+
+type BsnGentableEntryDescStatsRequest struct {
+	*BsnStatsRequest
+	TableId      uint16
+	Checksum     Checksum128
+	ChecksumMask Checksum128
+}
+
+type IBsnGentableEntryDescStatsRequest interface {
+	IBsnStatsRequest
+	GetTableId() uint16
+	GetChecksum() Checksum128
+	GetChecksumMask() Checksum128
+}
+
+func (self *BsnGentableEntryDescStatsRequest) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableEntryDescStatsRequest) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableEntryDescStatsRequest) GetChecksum() Checksum128 {
+	return self.Checksum
+}
+
+func (self *BsnGentableEntryDescStatsRequest) SetChecksum(v Checksum128) {
+	self.Checksum = v
+}
+
+func (self *BsnGentableEntryDescStatsRequest) GetChecksumMask() Checksum128 {
+	return self.ChecksumMask
+}
+
+func (self *BsnGentableEntryDescStatsRequest) SetChecksumMask(v Checksum128) {
+	self.ChecksumMask = v
+}
+
+func (self *BsnGentableEntryDescStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	self.Checksum.Serialize(encoder)
+	self.ChecksumMask.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGentableEntryDescStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnGentableEntryDescStatsRequest, error) {
+	_bsngentableentrydescstatsrequest := &BsnGentableEntryDescStatsRequest{BsnStatsRequest: parent}
+	if decoder.Length() < 36 {
+		return nil, fmt.Errorf("BsnGentableEntryDescStatsRequest packet too short: %d < 36", decoder.Length())
+	}
+	_bsngentableentrydescstatsrequest.TableId = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_bsngentableentrydescstatsrequest.Checksum.Decode(decoder)
+	_bsngentableentrydescstatsrequest.ChecksumMask.Decode(decoder)
+	return _bsngentableentrydescstatsrequest, nil
+}
+
+func NewBsnGentableEntryDescStatsRequest() *BsnGentableEntryDescStatsRequest {
+	obj := &BsnGentableEntryDescStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(2),
+	}
+	return obj
+}
+
+type BsnGentableEntryStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnGentableEntryStatsEntry
+}
+
+type IBsnGentableEntryStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnGentableEntryStatsEntry
+}
+
+func (self *BsnGentableEntryStatsReply) GetEntries() []*BsnGentableEntryStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnGentableEntryStatsReply) SetEntries(v []*BsnGentableEntryStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnGentableEntryStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnGentableEntryStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnGentableEntryStatsReply, error) {
+	_bsngentableentrystatsreply := &BsnGentableEntryStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeBsnGentableEntryStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngentableentrystatsreply.Entries = append(_bsngentableentrystatsreply.Entries, item)
+		}
+	}
+	return _bsngentableentrystatsreply, nil
+}
+
+func NewBsnGentableEntryStatsReply() *BsnGentableEntryStatsReply {
+	obj := &BsnGentableEntryStatsReply{
+		BsnStatsReply: NewBsnStatsReply(3),
+	}
+	return obj
+}
+
+type BsnGentableEntryStatsRequest struct {
+	*BsnStatsRequest
+	TableId      uint16
+	Checksum     Checksum128
+	ChecksumMask Checksum128
+}
+
+type IBsnGentableEntryStatsRequest interface {
+	IBsnStatsRequest
+	GetTableId() uint16
+	GetChecksum() Checksum128
+	GetChecksumMask() Checksum128
+}
+
+func (self *BsnGentableEntryStatsRequest) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableEntryStatsRequest) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableEntryStatsRequest) GetChecksum() Checksum128 {
+	return self.Checksum
+}
+
+func (self *BsnGentableEntryStatsRequest) SetChecksum(v Checksum128) {
+	self.Checksum = v
+}
+
+func (self *BsnGentableEntryStatsRequest) GetChecksumMask() Checksum128 {
+	return self.ChecksumMask
+}
+
+func (self *BsnGentableEntryStatsRequest) SetChecksumMask(v Checksum128) {
+	self.ChecksumMask = v
+}
+
+func (self *BsnGentableEntryStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	self.Checksum.Serialize(encoder)
+	self.ChecksumMask.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGentableEntryStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnGentableEntryStatsRequest, error) {
+	_bsngentableentrystatsrequest := &BsnGentableEntryStatsRequest{BsnStatsRequest: parent}
+	if decoder.Length() < 36 {
+		return nil, fmt.Errorf("BsnGentableEntryStatsRequest packet too short: %d < 36", decoder.Length())
+	}
+	_bsngentableentrystatsrequest.TableId = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_bsngentableentrystatsrequest.Checksum.Decode(decoder)
+	_bsngentableentrystatsrequest.ChecksumMask.Decode(decoder)
+	return _bsngentableentrystatsrequest, nil
+}
+
+func NewBsnGentableEntryStatsRequest() *BsnGentableEntryStatsRequest {
+	obj := &BsnGentableEntryStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(3),
+	}
+	return obj
+}
+
+type BsnGentableError struct {
+	*BsnBaseError
+	ErrorCode BsnGentableErrorCode
+	TableId   uint16
+}
+
+type IBsnGentableError interface {
+	IBsnBaseError
+	GetErrorCode() BsnGentableErrorCode
+	GetTableId() uint16
+}
+
+func (self *BsnGentableError) GetErrorCode() BsnGentableErrorCode {
+	return self.ErrorCode
+}
+
+func (self *BsnGentableError) SetErrorCode(v BsnGentableErrorCode) {
+	self.ErrorCode = v
+}
+
+func (self *BsnGentableError) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableError) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableError) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnBaseError.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.ErrorCode))
+	encoder.PutUint16(uint16(self.TableId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGentableError(parent *BsnBaseError, decoder *goloxi.Decoder) (*BsnGentableError, error) {
+	_bsngentableerror := &BsnGentableError{BsnBaseError: parent}
+	if decoder.Length() < 260 {
+		return nil, fmt.Errorf("BsnGentableError packet too short: %d < 260", decoder.Length())
+	}
+	_bsngentableerror.ErrorCode = BsnGentableErrorCode(decoder.ReadUint16())
+	_bsngentableerror.TableId = uint16(decoder.ReadUint16())
+	return _bsngentableerror, nil
+}
+
+func NewBsnGentableError() *BsnGentableError {
+	obj := &BsnGentableError{
+		BsnBaseError: NewBsnBaseError(2),
+	}
+	return obj
+}
+
+type BsnGentableSetBucketsSize struct {
+	*BsnHeader
+	TableId     uint16
+	BucketsSize uint32
+}
+
+type IBsnGentableSetBucketsSize interface {
+	IBsnHeader
+	GetTableId() uint16
+	GetBucketsSize() uint32
+}
+
+func (self *BsnGentableSetBucketsSize) GetTableId() uint16 {
+	return self.TableId
+}
+
+func (self *BsnGentableSetBucketsSize) SetTableId(v uint16) {
+	self.TableId = v
+}
+
+func (self *BsnGentableSetBucketsSize) GetBucketsSize() uint32 {
+	return self.BucketsSize
+}
+
+func (self *BsnGentableSetBucketsSize) SetBucketsSize(v uint32) {
+	self.BucketsSize = v
+}
+
+func (self *BsnGentableSetBucketsSize) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint32(uint32(self.BucketsSize))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGentableSetBucketsSize(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGentableSetBucketsSize, error) {
+	_bsngentablesetbucketssize := &BsnGentableSetBucketsSize{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnGentableSetBucketsSize packet too short: %d < 8", decoder.Length())
+	}
+	_bsngentablesetbucketssize.TableId = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_bsngentablesetbucketssize.BucketsSize = uint32(decoder.ReadUint32())
+	return _bsngentablesetbucketssize, nil
+}
+
+func NewBsnGentableSetBucketsSize() *BsnGentableSetBucketsSize {
+	obj := &BsnGentableSetBucketsSize{
+		BsnHeader: NewBsnHeader(50),
+	}
+	return obj
+}
+
+type BsnGentableStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnGentableStatsEntry
+}
+
+type IBsnGentableStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnGentableStatsEntry
+}
+
+func (self *BsnGentableStatsReply) GetEntries() []*BsnGentableStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnGentableStatsReply) SetEntries(v []*BsnGentableStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnGentableStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnGentableStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnGentableStatsReply, error) {
+	_bsngentablestatsreply := &BsnGentableStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 24 {
+		item, err := DecodeBsnGentableStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngentablestatsreply.Entries = append(_bsngentablestatsreply.Entries, item)
+		}
+	}
+	return _bsngentablestatsreply, nil
+}
+
+func NewBsnGentableStatsReply() *BsnGentableStatsReply {
+	obj := &BsnGentableStatsReply{
+		BsnStatsReply: NewBsnStatsReply(7),
+	}
+	return obj
+}
+
+type BsnGentableStatsRequest struct {
+	*BsnStatsRequest
+}
+
+type IBsnGentableStatsRequest interface {
+	IBsnStatsRequest
+}
+
+func (self *BsnGentableStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.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 DecodeBsnGentableStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnGentableStatsRequest, error) {
+	_bsngentablestatsrequest := &BsnGentableStatsRequest{BsnStatsRequest: parent}
+	return _bsngentablestatsrequest, nil
+}
+
+func NewBsnGentableStatsRequest() *BsnGentableStatsRequest {
+	obj := &BsnGentableStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(7),
+	}
+	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 BsnGetSwitchPipelineReply struct {
+	*BsnHeader
+	Pipeline string
+}
+
+type IBsnGetSwitchPipelineReply interface {
+	IBsnHeader
+	GetPipeline() string
+}
+
+func (self *BsnGetSwitchPipelineReply) GetPipeline() string {
+	return self.Pipeline
+}
+
+func (self *BsnGetSwitchPipelineReply) SetPipeline(v string) {
+	self.Pipeline = v
+}
+
+func (self *BsnGetSwitchPipelineReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write([]byte(self.Pipeline))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetSwitchPipelineReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetSwitchPipelineReply, error) {
+	_bsngetswitchpipelinereply := &BsnGetSwitchPipelineReply{BsnHeader: parent}
+	if decoder.Length() < 256 {
+		return nil, fmt.Errorf("BsnGetSwitchPipelineReply packet too short: %d < 256", decoder.Length())
+	}
+	_bsngetswitchpipelinereply.Pipeline = string(bytes.Trim(decoder.Read(256), "\x00"))
+	return _bsngetswitchpipelinereply, nil
+}
+
+func NewBsnGetSwitchPipelineReply() *BsnGetSwitchPipelineReply {
+	obj := &BsnGetSwitchPipelineReply{
+		BsnHeader: NewBsnHeader(52),
+	}
+	return obj
+}
+
+type BsnGetSwitchPipelineRequest struct {
+	*BsnHeader
+}
+
+type IBsnGetSwitchPipelineRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnGetSwitchPipelineRequest) 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 DecodeBsnGetSwitchPipelineRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetSwitchPipelineRequest, error) {
+	_bsngetswitchpipelinerequest := &BsnGetSwitchPipelineRequest{BsnHeader: parent}
+	return _bsngetswitchpipelinerequest, nil
+}
+
+func NewBsnGetSwitchPipelineRequest() *BsnGetSwitchPipelineRequest {
+	obj := &BsnGetSwitchPipelineRequest{
+		BsnHeader: NewBsnHeader(51),
+	}
+	return obj
+}
+
+type BsnImageDescStatsReply struct {
+	*BsnStatsReply
+	ImageChecksum         string
+	StartupConfigChecksum string
+}
+
+type IBsnImageDescStatsReply interface {
+	IBsnStatsReply
+	GetImageChecksum() string
+	GetStartupConfigChecksum() string
+}
+
+func (self *BsnImageDescStatsReply) GetImageChecksum() string {
+	return self.ImageChecksum
+}
+
+func (self *BsnImageDescStatsReply) SetImageChecksum(v string) {
+	self.ImageChecksum = v
+}
+
+func (self *BsnImageDescStatsReply) GetStartupConfigChecksum() string {
+	return self.StartupConfigChecksum
+}
+
+func (self *BsnImageDescStatsReply) SetStartupConfigChecksum(v string) {
+	self.StartupConfigChecksum = v
+}
+
+func (self *BsnImageDescStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write([]byte(self.ImageChecksum))
+	encoder.Write([]byte(self.StartupConfigChecksum))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnImageDescStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnImageDescStatsReply, error) {
+	_bsnimagedescstatsreply := &BsnImageDescStatsReply{BsnStatsReply: parent}
+	if decoder.Length() < 512 {
+		return nil, fmt.Errorf("BsnImageDescStatsReply packet too short: %d < 512", decoder.Length())
+	}
+	_bsnimagedescstatsreply.ImageChecksum = string(bytes.Trim(decoder.Read(256), "\x00"))
+	_bsnimagedescstatsreply.StartupConfigChecksum = string(bytes.Trim(decoder.Read(256), "\x00"))
+	return _bsnimagedescstatsreply, nil
+}
+
+func NewBsnImageDescStatsReply() *BsnImageDescStatsReply {
+	obj := &BsnImageDescStatsReply{
+		BsnStatsReply: NewBsnStatsReply(14),
+	}
+	return obj
+}
+
+type BsnImageDescStatsRequest struct {
+	*BsnStatsRequest
+}
+
+type IBsnImageDescStatsRequest interface {
+	IBsnStatsRequest
+}
+
+func (self *BsnImageDescStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.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 DecodeBsnImageDescStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnImageDescStatsRequest, error) {
+	_bsnimagedescstatsrequest := &BsnImageDescStatsRequest{BsnStatsRequest: parent}
+	return _bsnimagedescstatsrequest, nil
+}
+
+func NewBsnImageDescStatsRequest() *BsnImageDescStatsRequest {
+	obj := &BsnImageDescStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(14),
+	}
+	return obj
+}
+
+type BsnLacpConvergenceNotif struct {
+	*BsnHeader
+	ConvergenceStatus   uint8
+	PortNo              Port
+	ActorSysPriority    uint16
+	ActorSysMac         net.HardwareAddr
+	ActorPortPriority   uint16
+	ActorPortNum        uint16
+	ActorKey            uint16
+	PartnerSysPriority  uint16
+	PartnerSysMac       net.HardwareAddr
+	PartnerPortPriority uint16
+	PartnerPortNum      uint16
+	PartnerKey          uint16
+}
+
+type IBsnLacpConvergenceNotif interface {
+	IBsnHeader
+	GetConvergenceStatus() uint8
+	GetPortNo() Port
+	GetActorSysPriority() uint16
+	GetActorSysMac() net.HardwareAddr
+	GetActorPortPriority() uint16
+	GetActorPortNum() uint16
+	GetActorKey() uint16
+	GetPartnerSysPriority() uint16
+	GetPartnerSysMac() net.HardwareAddr
+	GetPartnerPortPriority() uint16
+	GetPartnerPortNum() uint16
+	GetPartnerKey() uint16
+}
+
+func (self *BsnLacpConvergenceNotif) GetConvergenceStatus() uint8 {
+	return self.ConvergenceStatus
+}
+
+func (self *BsnLacpConvergenceNotif) SetConvergenceStatus(v uint8) {
+	self.ConvergenceStatus = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnLacpConvergenceNotif) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetActorSysPriority() uint16 {
+	return self.ActorSysPriority
+}
+
+func (self *BsnLacpConvergenceNotif) SetActorSysPriority(v uint16) {
+	self.ActorSysPriority = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetActorSysMac() net.HardwareAddr {
+	return self.ActorSysMac
+}
+
+func (self *BsnLacpConvergenceNotif) SetActorSysMac(v net.HardwareAddr) {
+	self.ActorSysMac = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetActorPortPriority() uint16 {
+	return self.ActorPortPriority
+}
+
+func (self *BsnLacpConvergenceNotif) SetActorPortPriority(v uint16) {
+	self.ActorPortPriority = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetActorPortNum() uint16 {
+	return self.ActorPortNum
+}
+
+func (self *BsnLacpConvergenceNotif) SetActorPortNum(v uint16) {
+	self.ActorPortNum = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetActorKey() uint16 {
+	return self.ActorKey
+}
+
+func (self *BsnLacpConvergenceNotif) SetActorKey(v uint16) {
+	self.ActorKey = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetPartnerSysPriority() uint16 {
+	return self.PartnerSysPriority
+}
+
+func (self *BsnLacpConvergenceNotif) SetPartnerSysPriority(v uint16) {
+	self.PartnerSysPriority = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetPartnerSysMac() net.HardwareAddr {
+	return self.PartnerSysMac
+}
+
+func (self *BsnLacpConvergenceNotif) SetPartnerSysMac(v net.HardwareAddr) {
+	self.PartnerSysMac = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetPartnerPortPriority() uint16 {
+	return self.PartnerPortPriority
+}
+
+func (self *BsnLacpConvergenceNotif) SetPartnerPortPriority(v uint16) {
+	self.PartnerPortPriority = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetPartnerPortNum() uint16 {
+	return self.PartnerPortNum
+}
+
+func (self *BsnLacpConvergenceNotif) SetPartnerPortNum(v uint16) {
+	self.PartnerPortNum = v
+}
+
+func (self *BsnLacpConvergenceNotif) GetPartnerKey() uint16 {
+	return self.PartnerKey
+}
+
+func (self *BsnLacpConvergenceNotif) SetPartnerKey(v uint16) {
+	self.PartnerKey = v
+}
+
+func (self *BsnLacpConvergenceNotif) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.ConvergenceStatus))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	self.PortNo.Serialize(encoder)
+	encoder.PutUint16(uint16(self.ActorSysPriority))
+	encoder.Write(self.ActorSysMac)
+	encoder.PutUint16(uint16(self.ActorPortPriority))
+	encoder.PutUint16(uint16(self.ActorPortNum))
+	encoder.PutUint16(uint16(self.ActorKey))
+	encoder.PutUint16(uint16(self.PartnerSysPriority))
+	encoder.Write(self.PartnerSysMac)
+	encoder.PutUint16(uint16(self.PartnerPortPriority))
+	encoder.PutUint16(uint16(self.PartnerPortNum))
+	encoder.PutUint16(uint16(self.PartnerKey))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnLacpConvergenceNotif(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnLacpConvergenceNotif, error) {
+	_bsnlacpconvergencenotif := &BsnLacpConvergenceNotif{BsnHeader: parent}
+	if decoder.Length() < 36 {
+		return nil, fmt.Errorf("BsnLacpConvergenceNotif packet too short: %d < 36", decoder.Length())
+	}
+	_bsnlacpconvergencenotif.ConvergenceStatus = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_bsnlacpconvergencenotif.PortNo.Decode(decoder)
+	_bsnlacpconvergencenotif.ActorSysPriority = uint16(decoder.ReadUint16())
+	_bsnlacpconvergencenotif.ActorSysMac = net.HardwareAddr(decoder.Read(6))
+	_bsnlacpconvergencenotif.ActorPortPriority = uint16(decoder.ReadUint16())
+	_bsnlacpconvergencenotif.ActorPortNum = uint16(decoder.ReadUint16())
+	_bsnlacpconvergencenotif.ActorKey = uint16(decoder.ReadUint16())
+	_bsnlacpconvergencenotif.PartnerSysPriority = uint16(decoder.ReadUint16())
+	_bsnlacpconvergencenotif.PartnerSysMac = net.HardwareAddr(decoder.Read(6))
+	_bsnlacpconvergencenotif.PartnerPortPriority = uint16(decoder.ReadUint16())
+	_bsnlacpconvergencenotif.PartnerPortNum = uint16(decoder.ReadUint16())
+	_bsnlacpconvergencenotif.PartnerKey = uint16(decoder.ReadUint16())
+	return _bsnlacpconvergencenotif, nil
+}
+
+func NewBsnLacpConvergenceNotif() *BsnLacpConvergenceNotif {
+	obj := &BsnLacpConvergenceNotif{
+		BsnHeader: NewBsnHeader(43),
+	}
+	return obj
+}
+
+type BsnLacpStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnLacpStatsEntry
+}
+
+type IBsnLacpStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnLacpStatsEntry
+}
+
+func (self *BsnLacpStatsReply) GetEntries() []*BsnLacpStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnLacpStatsReply) SetEntries(v []*BsnLacpStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnLacpStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnLacpStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnLacpStatsReply, error) {
+	_bsnlacpstatsreply := &BsnLacpStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 36 {
+		item, err := DecodeBsnLacpStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsnlacpstatsreply.Entries = append(_bsnlacpstatsreply.Entries, item)
+		}
+	}
+	return _bsnlacpstatsreply, nil
+}
+
+func NewBsnLacpStatsReply() *BsnLacpStatsReply {
+	obj := &BsnLacpStatsReply{
+		BsnStatsReply: NewBsnStatsReply(1),
+	}
+	return obj
+}
+
+type BsnLacpStatsRequest struct {
+	*BsnStatsRequest
+}
+
+type IBsnLacpStatsRequest interface {
+	IBsnStatsRequest
+}
+
+func (self *BsnLacpStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.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 DecodeBsnLacpStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnLacpStatsRequest, error) {
+	_bsnlacpstatsrequest := &BsnLacpStatsRequest{BsnStatsRequest: parent}
+	return _bsnlacpstatsrequest, nil
+}
+
+func NewBsnLacpStatsRequest() *BsnLacpStatsRequest {
+	obj := &BsnLacpStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(1),
+	}
+	return obj
+}
+
+type BsnLog struct {
+	*BsnHeader
+	Loglevel BsnLoglevel
+	Data     []byte
+}
+
+type IBsnLog interface {
+	IBsnHeader
+	GetLoglevel() BsnLoglevel
+	GetData() []byte
+}
+
+func (self *BsnLog) GetLoglevel() BsnLoglevel {
+	return self.Loglevel
+}
+
+func (self *BsnLog) SetLoglevel(v BsnLoglevel) {
+	self.Loglevel = v
+}
+
+func (self *BsnLog) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnLog) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnLog) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Loglevel))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnLog(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnLog, error) {
+	_bsnlog := &BsnLog{BsnHeader: parent}
+	if decoder.Length() < 1 {
+		return nil, fmt.Errorf("BsnLog packet too short: %d < 1", decoder.Length())
+	}
+	_bsnlog.Loglevel = BsnLoglevel(decoder.ReadByte())
+	_bsnlog.Data = decoder.Read(int(decoder.Length()))
+	return _bsnlog, nil
+}
+
+func NewBsnLog() *BsnLog {
+	obj := &BsnLog{
+		BsnHeader: NewBsnHeader(63),
+	}
+	return obj
+}
+
+type BsnLuaCommandReply struct {
+	*BsnHeader
+	Data []byte
+}
+
+type IBsnLuaCommandReply interface {
+	IBsnHeader
+	GetData() []byte
+}
+
+func (self *BsnLuaCommandReply) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnLuaCommandReply) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnLuaCommandReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.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 DecodeBsnLuaCommandReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnLuaCommandReply, error) {
+	_bsnluacommandreply := &BsnLuaCommandReply{BsnHeader: parent}
+	_bsnluacommandreply.Data = decoder.Read(int(decoder.Length()))
+	return _bsnluacommandreply, nil
+}
+
+func NewBsnLuaCommandReply() *BsnLuaCommandReply {
+	obj := &BsnLuaCommandReply{
+		BsnHeader: NewBsnHeader(66),
+	}
+	return obj
+}
+
+type BsnLuaCommandRequest struct {
+	*BsnHeader
+	Data []byte
+}
+
+type IBsnLuaCommandRequest interface {
+	IBsnHeader
+	GetData() []byte
+}
+
+func (self *BsnLuaCommandRequest) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnLuaCommandRequest) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnLuaCommandRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.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 DecodeBsnLuaCommandRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnLuaCommandRequest, error) {
+	_bsnluacommandrequest := &BsnLuaCommandRequest{BsnHeader: parent}
+	_bsnluacommandrequest.Data = decoder.Read(int(decoder.Length()))
+	return _bsnluacommandrequest, nil
+}
+
+func NewBsnLuaCommandRequest() *BsnLuaCommandRequest {
+	obj := &BsnLuaCommandRequest{
+		BsnHeader: NewBsnHeader(65),
+	}
+	return obj
+}
+
+type BsnLuaNotification struct {
+	*BsnHeader
+	Data []byte
+}
+
+type IBsnLuaNotification interface {
+	IBsnHeader
+	GetData() []byte
+}
+
+func (self *BsnLuaNotification) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnLuaNotification) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnLuaNotification) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.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 DecodeBsnLuaNotification(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnLuaNotification, error) {
+	_bsnluanotification := &BsnLuaNotification{BsnHeader: parent}
+	_bsnluanotification.Data = decoder.Read(int(decoder.Length()))
+	return _bsnluanotification, nil
+}
+
+func NewBsnLuaNotification() *BsnLuaNotification {
+	obj := &BsnLuaNotification{
+		BsnHeader: NewBsnHeader(67),
+	}
+	return obj
+}
+
+type BsnLuaUpload struct {
+	*BsnHeader
+	Flags    BsnLuaUploadFlags
+	Filename string
+	Data     []byte
+}
+
+type IBsnLuaUpload interface {
+	IBsnHeader
+	GetFlags() BsnLuaUploadFlags
+	GetFilename() string
+	GetData() []byte
+}
+
+func (self *BsnLuaUpload) GetFlags() BsnLuaUploadFlags {
+	return self.Flags
+}
+
+func (self *BsnLuaUpload) SetFlags(v BsnLuaUploadFlags) {
+	self.Flags = v
+}
+
+func (self *BsnLuaUpload) GetFilename() string {
+	return self.Filename
+}
+
+func (self *BsnLuaUpload) SetFilename(v string) {
+	self.Filename = v
+}
+
+func (self *BsnLuaUpload) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnLuaUpload) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnLuaUpload) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.Write([]byte(self.Filename))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnLuaUpload(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnLuaUpload, error) {
+	_bsnluaupload := &BsnLuaUpload{BsnHeader: parent}
+	if decoder.Length() < 66 {
+		return nil, fmt.Errorf("BsnLuaUpload packet too short: %d < 66", decoder.Length())
+	}
+	_bsnluaupload.Flags = BsnLuaUploadFlags(decoder.ReadUint16())
+	_bsnluaupload.Filename = string(bytes.Trim(decoder.Read(64), "\x00"))
+	_bsnluaupload.Data = decoder.Read(int(decoder.Length()))
+	return _bsnluaupload, nil
+}
+
+func NewBsnLuaUpload() *BsnLuaUpload {
+	obj := &BsnLuaUpload{
+		BsnHeader: NewBsnHeader(64),
+	}
+	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 BsnPortCounterStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnPortCounterStatsEntry
+}
+
+type IBsnPortCounterStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnPortCounterStatsEntry
+}
+
+func (self *BsnPortCounterStatsReply) GetEntries() []*BsnPortCounterStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnPortCounterStatsReply) SetEntries(v []*BsnPortCounterStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnPortCounterStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnPortCounterStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnPortCounterStatsReply, error) {
+	_bsnportcounterstatsreply := &BsnPortCounterStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeBsnPortCounterStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsnportcounterstatsreply.Entries = append(_bsnportcounterstatsreply.Entries, item)
+		}
+	}
+	return _bsnportcounterstatsreply, nil
+}
+
+func NewBsnPortCounterStatsReply() *BsnPortCounterStatsReply {
+	obj := &BsnPortCounterStatsReply{
+		BsnStatsReply: NewBsnStatsReply(8),
+	}
+	return obj
+}
+
+type BsnPortCounterStatsRequest struct {
+	*BsnStatsRequest
+	PortNo Port
+}
+
+type IBsnPortCounterStatsRequest interface {
+	IBsnStatsRequest
+	GetPortNo() Port
+}
+
+func (self *BsnPortCounterStatsRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnPortCounterStatsRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnPortCounterStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.PortNo.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnPortCounterStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnPortCounterStatsRequest, error) {
+	_bsnportcounterstatsrequest := &BsnPortCounterStatsRequest{BsnStatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnPortCounterStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnportcounterstatsrequest.PortNo.Decode(decoder)
+	return _bsnportcounterstatsrequest, nil
+}
+
+func NewBsnPortCounterStatsRequest() *BsnPortCounterStatsRequest {
+	obj := &BsnPortCounterStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(8),
+	}
+	return obj
+}
+
+type BsnSetAuxCxnsReply struct {
+	*BsnHeader
+	NumAux uint32
+	Status uint32
+}
+
+type IBsnSetAuxCxnsReply interface {
+	IBsnHeader
+	GetNumAux() uint32
+	GetStatus() uint32
+}
+
+func (self *BsnSetAuxCxnsReply) GetNumAux() uint32 {
+	return self.NumAux
+}
+
+func (self *BsnSetAuxCxnsReply) SetNumAux(v uint32) {
+	self.NumAux = v
+}
+
+func (self *BsnSetAuxCxnsReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnSetAuxCxnsReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnSetAuxCxnsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.NumAux))
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetAuxCxnsReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetAuxCxnsReply, error) {
+	_bsnsetauxcxnsreply := &BsnSetAuxCxnsReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnSetAuxCxnsReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnsetauxcxnsreply.NumAux = uint32(decoder.ReadUint32())
+	_bsnsetauxcxnsreply.Status = uint32(decoder.ReadUint32())
+	return _bsnsetauxcxnsreply, nil
+}
+
+func NewBsnSetAuxCxnsReply() *BsnSetAuxCxnsReply {
+	obj := &BsnSetAuxCxnsReply{
+		BsnHeader: NewBsnHeader(59),
+	}
+	return obj
+}
+
+type BsnSetAuxCxnsRequest struct {
+	*BsnHeader
+	NumAux uint32
+}
+
+type IBsnSetAuxCxnsRequest interface {
+	IBsnHeader
+	GetNumAux() uint32
+}
+
+func (self *BsnSetAuxCxnsRequest) GetNumAux() uint32 {
+	return self.NumAux
+}
+
+func (self *BsnSetAuxCxnsRequest) SetNumAux(v uint32) {
+	self.NumAux = v
+}
+
+func (self *BsnSetAuxCxnsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.NumAux))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetAuxCxnsRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetAuxCxnsRequest, error) {
+	_bsnsetauxcxnsrequest := &BsnSetAuxCxnsRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnSetAuxCxnsRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnsetauxcxnsrequest.NumAux = uint32(decoder.ReadUint32())
+	return _bsnsetauxcxnsrequest, nil
+}
+
+func NewBsnSetAuxCxnsRequest() *BsnSetAuxCxnsRequest {
+	obj := &BsnSetAuxCxnsRequest{
+		BsnHeader: NewBsnHeader(58),
+	}
+	return obj
+}
+
+type BsnSetLacpReply struct {
+	*BsnHeader
+	Status uint32
+	PortNo Port
+}
+
+type IBsnSetLacpReply interface {
+	IBsnHeader
+	GetStatus() uint32
+	GetPortNo() Port
+}
+
+func (self *BsnSetLacpReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnSetLacpReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnSetLacpReply) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnSetLacpReply) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnSetLacpReply) 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)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetLacpReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetLacpReply, error) {
+	_bsnsetlacpreply := &BsnSetLacpReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnSetLacpReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnsetlacpreply.Status = uint32(decoder.ReadUint32())
+	_bsnsetlacpreply.PortNo.Decode(decoder)
+	return _bsnsetlacpreply, nil
+}
+
+func NewBsnSetLacpReply() *BsnSetLacpReply {
+	obj := &BsnSetLacpReply{
+		BsnHeader: NewBsnHeader(42),
+	}
+	return obj
+}
+
+type BsnSetLacpRequest struct {
+	*BsnHeader
+	Enabled           uint8
+	PortNo            Port
+	ActorSysPriority  uint16
+	ActorSysMac       net.HardwareAddr
+	ActorPortPriority uint16
+	ActorPortNum      uint16
+	ActorKey          uint16
+}
+
+type IBsnSetLacpRequest interface {
+	IBsnHeader
+	GetEnabled() uint8
+	GetPortNo() Port
+	GetActorSysPriority() uint16
+	GetActorSysMac() net.HardwareAddr
+	GetActorPortPriority() uint16
+	GetActorPortNum() uint16
+	GetActorKey() uint16
+}
+
+func (self *BsnSetLacpRequest) GetEnabled() uint8 {
+	return self.Enabled
+}
+
+func (self *BsnSetLacpRequest) SetEnabled(v uint8) {
+	self.Enabled = v
+}
+
+func (self *BsnSetLacpRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *BsnSetLacpRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *BsnSetLacpRequest) GetActorSysPriority() uint16 {
+	return self.ActorSysPriority
+}
+
+func (self *BsnSetLacpRequest) SetActorSysPriority(v uint16) {
+	self.ActorSysPriority = v
+}
+
+func (self *BsnSetLacpRequest) GetActorSysMac() net.HardwareAddr {
+	return self.ActorSysMac
+}
+
+func (self *BsnSetLacpRequest) SetActorSysMac(v net.HardwareAddr) {
+	self.ActorSysMac = v
+}
+
+func (self *BsnSetLacpRequest) GetActorPortPriority() uint16 {
+	return self.ActorPortPriority
+}
+
+func (self *BsnSetLacpRequest) SetActorPortPriority(v uint16) {
+	self.ActorPortPriority = v
+}
+
+func (self *BsnSetLacpRequest) GetActorPortNum() uint16 {
+	return self.ActorPortNum
+}
+
+func (self *BsnSetLacpRequest) SetActorPortNum(v uint16) {
+	self.ActorPortNum = v
+}
+
+func (self *BsnSetLacpRequest) GetActorKey() uint16 {
+	return self.ActorKey
+}
+
+func (self *BsnSetLacpRequest) SetActorKey(v uint16) {
+	self.ActorKey = v
+}
+
+func (self *BsnSetLacpRequest) 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}, 3))
+	self.PortNo.Serialize(encoder)
+	encoder.PutUint16(uint16(self.ActorSysPriority))
+	encoder.Write(self.ActorSysMac)
+	encoder.PutUint16(uint16(self.ActorPortPriority))
+	encoder.PutUint16(uint16(self.ActorPortNum))
+	encoder.PutUint16(uint16(self.ActorKey))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetLacpRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetLacpRequest, error) {
+	_bsnsetlacprequest := &BsnSetLacpRequest{BsnHeader: parent}
+	if decoder.Length() < 22 {
+		return nil, fmt.Errorf("BsnSetLacpRequest packet too short: %d < 22", decoder.Length())
+	}
+	_bsnsetlacprequest.Enabled = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_bsnsetlacprequest.PortNo.Decode(decoder)
+	_bsnsetlacprequest.ActorSysPriority = uint16(decoder.ReadUint16())
+	_bsnsetlacprequest.ActorSysMac = net.HardwareAddr(decoder.Read(6))
+	_bsnsetlacprequest.ActorPortPriority = uint16(decoder.ReadUint16())
+	_bsnsetlacprequest.ActorPortNum = uint16(decoder.ReadUint16())
+	_bsnsetlacprequest.ActorKey = uint16(decoder.ReadUint16())
+	return _bsnsetlacprequest, nil
+}
+
+func NewBsnSetLacpRequest() *BsnSetLacpRequest {
+	obj := &BsnSetLacpRequest{
+		BsnHeader: NewBsnHeader(41),
+	}
+	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 BsnSetSwitchPipelineReply struct {
+	*BsnHeader
+	Status uint32
+}
+
+type IBsnSetSwitchPipelineReply interface {
+	IBsnHeader
+	GetStatus() uint32
+}
+
+func (self *BsnSetSwitchPipelineReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnSetSwitchPipelineReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnSetSwitchPipelineReply) 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 DecodeBsnSetSwitchPipelineReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetSwitchPipelineReply, error) {
+	_bsnsetswitchpipelinereply := &BsnSetSwitchPipelineReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnSetSwitchPipelineReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnsetswitchpipelinereply.Status = uint32(decoder.ReadUint32())
+	return _bsnsetswitchpipelinereply, nil
+}
+
+func NewBsnSetSwitchPipelineReply() *BsnSetSwitchPipelineReply {
+	obj := &BsnSetSwitchPipelineReply{
+		BsnHeader: NewBsnHeader(54),
+	}
+	return obj
+}
+
+type BsnSetSwitchPipelineRequest struct {
+	*BsnHeader
+	Pipeline string
+}
+
+type IBsnSetSwitchPipelineRequest interface {
+	IBsnHeader
+	GetPipeline() string
+}
+
+func (self *BsnSetSwitchPipelineRequest) GetPipeline() string {
+	return self.Pipeline
+}
+
+func (self *BsnSetSwitchPipelineRequest) SetPipeline(v string) {
+	self.Pipeline = v
+}
+
+func (self *BsnSetSwitchPipelineRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write([]byte(self.Pipeline))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetSwitchPipelineRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetSwitchPipelineRequest, error) {
+	_bsnsetswitchpipelinerequest := &BsnSetSwitchPipelineRequest{BsnHeader: parent}
+	if decoder.Length() < 256 {
+		return nil, fmt.Errorf("BsnSetSwitchPipelineRequest packet too short: %d < 256", decoder.Length())
+	}
+	_bsnsetswitchpipelinerequest.Pipeline = string(bytes.Trim(decoder.Read(256), "\x00"))
+	return _bsnsetswitchpipelinerequest, nil
+}
+
+func NewBsnSetSwitchPipelineRequest() *BsnSetSwitchPipelineRequest {
+	obj := &BsnSetSwitchPipelineRequest{
+		BsnHeader: NewBsnHeader(53),
+	}
+	return obj
+}
+
+type BsnSwitchPipelineStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnSwitchPipelineStatsEntry
+}
+
+type IBsnSwitchPipelineStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnSwitchPipelineStatsEntry
+}
+
+func (self *BsnSwitchPipelineStatsReply) GetEntries() []*BsnSwitchPipelineStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnSwitchPipelineStatsReply) SetEntries(v []*BsnSwitchPipelineStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnSwitchPipelineStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnSwitchPipelineStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnSwitchPipelineStatsReply, error) {
+	_bsnswitchpipelinestatsreply := &BsnSwitchPipelineStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 256 {
+		item, err := DecodeBsnSwitchPipelineStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsnswitchpipelinestatsreply.Entries = append(_bsnswitchpipelinestatsreply.Entries, item)
+		}
+	}
+	return _bsnswitchpipelinestatsreply, nil
+}
+
+func NewBsnSwitchPipelineStatsReply() *BsnSwitchPipelineStatsReply {
+	obj := &BsnSwitchPipelineStatsReply{
+		BsnStatsReply: NewBsnStatsReply(6),
+	}
+	return obj
+}
+
+type BsnSwitchPipelineStatsRequest struct {
+	*BsnStatsRequest
+}
+
+type IBsnSwitchPipelineStatsRequest interface {
+	IBsnStatsRequest
+}
+
+func (self *BsnSwitchPipelineStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.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 DecodeBsnSwitchPipelineStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnSwitchPipelineStatsRequest, error) {
+	_bsnswitchpipelinestatsrequest := &BsnSwitchPipelineStatsRequest{BsnStatsRequest: parent}
+	return _bsnswitchpipelinestatsrequest, nil
+}
+
+func NewBsnSwitchPipelineStatsRequest() *BsnSwitchPipelineStatsRequest {
+	obj := &BsnSwitchPipelineStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(6),
+	}
+	return obj
+}
+
+type BsnTableChecksumStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnTableChecksumStatsEntry
+}
+
+type IBsnTableChecksumStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnTableChecksumStatsEntry
+}
+
+func (self *BsnTableChecksumStatsReply) GetEntries() []*BsnTableChecksumStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnTableChecksumStatsReply) SetEntries(v []*BsnTableChecksumStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnTableChecksumStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnTableChecksumStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnTableChecksumStatsReply, error) {
+	_bsntablechecksumstatsreply := &BsnTableChecksumStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 9 {
+		item, err := DecodeBsnTableChecksumStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsntablechecksumstatsreply.Entries = append(_bsntablechecksumstatsreply.Entries, item)
+		}
+	}
+	return _bsntablechecksumstatsreply, nil
+}
+
+func NewBsnTableChecksumStatsReply() *BsnTableChecksumStatsReply {
+	obj := &BsnTableChecksumStatsReply{
+		BsnStatsReply: NewBsnStatsReply(11),
+	}
+	return obj
+}
+
+type BsnTableChecksumStatsRequest struct {
+	*BsnStatsRequest
+}
+
+type IBsnTableChecksumStatsRequest interface {
+	IBsnStatsRequest
+}
+
+func (self *BsnTableChecksumStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.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 DecodeBsnTableChecksumStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnTableChecksumStatsRequest, error) {
+	_bsntablechecksumstatsrequest := &BsnTableChecksumStatsRequest{BsnStatsRequest: parent}
+	return _bsntablechecksumstatsrequest, nil
+}
+
+func NewBsnTableChecksumStatsRequest() *BsnTableChecksumStatsRequest {
+	obj := &BsnTableChecksumStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(11),
+	}
+	return obj
+}
+
+type BsnTableSetBucketsSize struct {
+	*BsnHeader
+	TableId     uint8
+	BucketsSize uint32
+}
+
+type IBsnTableSetBucketsSize interface {
+	IBsnHeader
+	GetTableId() uint8
+	GetBucketsSize() uint32
+}
+
+func (self *BsnTableSetBucketsSize) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *BsnTableSetBucketsSize) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *BsnTableSetBucketsSize) GetBucketsSize() uint32 {
+	return self.BucketsSize
+}
+
+func (self *BsnTableSetBucketsSize) SetBucketsSize(v uint32) {
+	self.BucketsSize = v
+}
+
+func (self *BsnTableSetBucketsSize) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint32(uint32(self.BucketsSize))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnTableSetBucketsSize(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnTableSetBucketsSize, error) {
+	_bsntablesetbucketssize := &BsnTableSetBucketsSize{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnTableSetBucketsSize packet too short: %d < 8", decoder.Length())
+	}
+	decoder.Skip(1)
+	_bsntablesetbucketssize.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(2)
+	_bsntablesetbucketssize.BucketsSize = uint32(decoder.ReadUint32())
+	return _bsntablesetbucketssize, nil
+}
+
+func NewBsnTableSetBucketsSize() *BsnTableSetBucketsSize {
+	obj := &BsnTableSetBucketsSize{
+		BsnHeader: NewBsnHeader(61),
+	}
+	return obj
+}
+
+type BsnTakeover struct {
+	*BsnHeader
+}
+
+type IBsnTakeover interface {
+	IBsnHeader
+}
+
+func (self *BsnTakeover) 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 DecodeBsnTakeover(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnTakeover, error) {
+	_bsntakeover := &BsnTakeover{BsnHeader: parent}
+	return _bsntakeover, nil
+}
+
+func NewBsnTakeover() *BsnTakeover {
+	obj := &BsnTakeover{
+		BsnHeader: NewBsnHeader(69),
+	}
+	return obj
+}
+
+type BsnTimeReply struct {
+	*BsnHeader
+	TimeMs uint64
+}
+
+type IBsnTimeReply interface {
+	IBsnHeader
+	GetTimeMs() uint64
+}
+
+func (self *BsnTimeReply) GetTimeMs() uint64 {
+	return self.TimeMs
+}
+
+func (self *BsnTimeReply) SetTimeMs(v uint64) {
+	self.TimeMs = v
+}
+
+func (self *BsnTimeReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.TimeMs))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnTimeReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnTimeReply, error) {
+	_bsntimereply := &BsnTimeReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnTimeReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsntimereply.TimeMs = uint64(decoder.ReadUint64())
+	return _bsntimereply, nil
+}
+
+func NewBsnTimeReply() *BsnTimeReply {
+	obj := &BsnTimeReply{
+		BsnHeader: NewBsnHeader(45),
+	}
+	return obj
+}
+
+type BsnTimeRequest struct {
+	*BsnHeader
+}
+
+type IBsnTimeRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnTimeRequest) 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 DecodeBsnTimeRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnTimeRequest, error) {
+	_bsntimerequest := &BsnTimeRequest{BsnHeader: parent}
+	return _bsntimerequest, nil
+}
+
+func NewBsnTimeRequest() *BsnTimeRequest {
+	obj := &BsnTimeRequest{
+		BsnHeader: NewBsnHeader(44),
+	}
+	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 BsnVlanCounterClear struct {
+	*BsnHeader
+	VlanVid uint16
+}
+
+type IBsnVlanCounterClear interface {
+	IBsnHeader
+	GetVlanVid() uint16
+}
+
+func (self *BsnVlanCounterClear) GetVlanVid() uint16 {
+	return self.VlanVid
+}
+
+func (self *BsnVlanCounterClear) SetVlanVid(v uint16) {
+	self.VlanVid = v
+}
+
+func (self *BsnVlanCounterClear) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.VlanVid))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVlanCounterClear(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVlanCounterClear, error) {
+	_bsnvlancounterclear := &BsnVlanCounterClear{BsnHeader: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BsnVlanCounterClear packet too short: %d < 2", decoder.Length())
+	}
+	_bsnvlancounterclear.VlanVid = uint16(decoder.ReadUint16())
+	return _bsnvlancounterclear, nil
+}
+
+func NewBsnVlanCounterClear() *BsnVlanCounterClear {
+	obj := &BsnVlanCounterClear{
+		BsnHeader: NewBsnHeader(70),
+	}
+	return obj
+}
+
+type BsnVlanCounterStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnVlanCounterStatsEntry
+}
+
+type IBsnVlanCounterStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnVlanCounterStatsEntry
+}
+
+func (self *BsnVlanCounterStatsReply) GetEntries() []*BsnVlanCounterStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnVlanCounterStatsReply) SetEntries(v []*BsnVlanCounterStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnVlanCounterStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnVlanCounterStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnVlanCounterStatsReply, error) {
+	_bsnvlancounterstatsreply := &BsnVlanCounterStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeBsnVlanCounterStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsnvlancounterstatsreply.Entries = append(_bsnvlancounterstatsreply.Entries, item)
+		}
+	}
+	return _bsnvlancounterstatsreply, nil
+}
+
+func NewBsnVlanCounterStatsReply() *BsnVlanCounterStatsReply {
+	obj := &BsnVlanCounterStatsReply{
+		BsnStatsReply: NewBsnStatsReply(9),
+	}
+	return obj
+}
+
+type BsnVlanCounterStatsRequest struct {
+	*BsnStatsRequest
+	VlanVid uint16
+}
+
+type IBsnVlanCounterStatsRequest interface {
+	IBsnStatsRequest
+	GetVlanVid() uint16
+}
+
+func (self *BsnVlanCounterStatsRequest) GetVlanVid() uint16 {
+	return self.VlanVid
+}
+
+func (self *BsnVlanCounterStatsRequest) SetVlanVid(v uint16) {
+	self.VlanVid = v
+}
+
+func (self *BsnVlanCounterStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.VlanVid))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVlanCounterStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnVlanCounterStatsRequest, error) {
+	_bsnvlancounterstatsrequest := &BsnVlanCounterStatsRequest{BsnStatsRequest: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BsnVlanCounterStatsRequest packet too short: %d < 2", decoder.Length())
+	}
+	_bsnvlancounterstatsrequest.VlanVid = uint16(decoder.ReadUint16())
+	return _bsnvlancounterstatsrequest, nil
+}
+
+func NewBsnVlanCounterStatsRequest() *BsnVlanCounterStatsRequest {
+	obj := &BsnVlanCounterStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(9),
+	}
+	return obj
+}
+
+type BsnVrfCounterStatsReply struct {
+	*BsnStatsReply
+	Entries []*BsnVrfCounterStatsEntry
+}
+
+type IBsnVrfCounterStatsReply interface {
+	IBsnStatsReply
+	GetEntries() []*BsnVrfCounterStatsEntry
+}
+
+func (self *BsnVrfCounterStatsReply) GetEntries() []*BsnVrfCounterStatsEntry {
+	return self.Entries
+}
+
+func (self *BsnVrfCounterStatsReply) SetEntries(v []*BsnVrfCounterStatsEntry) {
+	self.Entries = v
+}
+
+func (self *BsnVrfCounterStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeBsnVrfCounterStatsReply(parent *BsnStatsReply, decoder *goloxi.Decoder) (*BsnVrfCounterStatsReply, error) {
+	_bsnvrfcounterstatsreply := &BsnVrfCounterStatsReply{BsnStatsReply: parent}
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeBsnVrfCounterStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsnvrfcounterstatsreply.Entries = append(_bsnvrfcounterstatsreply.Entries, item)
+		}
+	}
+	return _bsnvrfcounterstatsreply, nil
+}
+
+func NewBsnVrfCounterStatsReply() *BsnVrfCounterStatsReply {
+	obj := &BsnVrfCounterStatsReply{
+		BsnStatsReply: NewBsnStatsReply(15),
+	}
+	return obj
+}
+
+type BsnVrfCounterStatsRequest struct {
+	*BsnStatsRequest
+	Vrf uint32
+}
+
+type IBsnVrfCounterStatsRequest interface {
+	IBsnStatsRequest
+	GetVrf() uint32
+}
+
+func (self *BsnVrfCounterStatsRequest) GetVrf() uint32 {
+	return self.Vrf
+}
+
+func (self *BsnVrfCounterStatsRequest) SetVrf(v uint32) {
+	self.Vrf = v
+}
+
+func (self *BsnVrfCounterStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Vrf))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVrfCounterStatsRequest(parent *BsnStatsRequest, decoder *goloxi.Decoder) (*BsnVrfCounterStatsRequest, error) {
+	_bsnvrfcounterstatsrequest := &BsnVrfCounterStatsRequest{BsnStatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnVrfCounterStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnvrfcounterstatsrequest.Vrf = uint32(decoder.ReadUint32())
+	return _bsnvrfcounterstatsrequest, nil
+}
+
+func NewBsnVrfCounterStatsRequest() *BsnVrfCounterStatsRequest {
+	obj := &BsnVrfCounterStatsRequest{
+		BsnStatsRequest: NewBsnStatsRequest(15),
+	}
+	return obj
+}
+
+type BundleAddMsg struct {
+	*Header
+	BundleId uint32
+	Flags    BundleFlags
+	Data     []byte
+}
+
+type IBundleAddMsg interface {
+	IHeader
+	GetBundleId() uint32
+	GetFlags() BundleFlags
+	GetData() []byte
+}
+
+func (self *BundleAddMsg) GetBundleId() uint32 {
+	return self.BundleId
+}
+
+func (self *BundleAddMsg) SetBundleId(v uint32) {
+	self.BundleId = v
+}
+
+func (self *BundleAddMsg) GetFlags() BundleFlags {
+	return self.Flags
+}
+
+func (self *BundleAddMsg) SetFlags(v BundleFlags) {
+	self.Flags = v
+}
+
+func (self *BundleAddMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BundleAddMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BundleAddMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.BundleId))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBundleAddMsg(parent *Header, decoder *goloxi.Decoder) (*BundleAddMsg, error) {
+	_bundleaddmsg := &BundleAddMsg{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BundleAddMsg packet too short: %d < 8", decoder.Length())
+	}
+	_bundleaddmsg.BundleId = uint32(decoder.ReadUint32())
+	decoder.Skip(2)
+	_bundleaddmsg.Flags = BundleFlags(decoder.ReadUint16())
+	_bundleaddmsg.Data = decoder.Read(int(decoder.Length()))
+	return _bundleaddmsg, nil
+}
+
+func NewBundleAddMsg() *BundleAddMsg {
+	obj := &BundleAddMsg{
+		Header: NewHeader(34),
+	}
+	return obj
+}
+
+type BundleCtrlMsg struct {
+	*Header
+	BundleId       uint32
+	BundleCtrlType BundleCtrlType
+	Flags          BundleFlags
+	Properties     []IBundleProp
+}
+
+type IBundleCtrlMsg interface {
+	IHeader
+	GetBundleId() uint32
+	GetBundleCtrlType() BundleCtrlType
+	GetFlags() BundleFlags
+	GetProperties() []IBundleProp
+}
+
+func (self *BundleCtrlMsg) GetBundleId() uint32 {
+	return self.BundleId
+}
+
+func (self *BundleCtrlMsg) SetBundleId(v uint32) {
+	self.BundleId = v
+}
+
+func (self *BundleCtrlMsg) GetBundleCtrlType() BundleCtrlType {
+	return self.BundleCtrlType
+}
+
+func (self *BundleCtrlMsg) SetBundleCtrlType(v BundleCtrlType) {
+	self.BundleCtrlType = v
+}
+
+func (self *BundleCtrlMsg) GetFlags() BundleFlags {
+	return self.Flags
+}
+
+func (self *BundleCtrlMsg) SetFlags(v BundleFlags) {
+	self.Flags = v
+}
+
+func (self *BundleCtrlMsg) GetProperties() []IBundleProp {
+	return self.Properties
+}
+
+func (self *BundleCtrlMsg) SetProperties(v []IBundleProp) {
+	self.Properties = v
+}
+
+func (self *BundleCtrlMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.BundleId))
+	encoder.PutUint16(uint16(self.BundleCtrlType))
+	encoder.PutUint16(uint16(self.Flags))
+	for _, obj := range self.Properties {
+		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 DecodeBundleCtrlMsg(parent *Header, decoder *goloxi.Decoder) (*BundleCtrlMsg, error) {
+	_bundlectrlmsg := &BundleCtrlMsg{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BundleCtrlMsg packet too short: %d < 8", decoder.Length())
+	}
+	_bundlectrlmsg.BundleId = uint32(decoder.ReadUint32())
+	_bundlectrlmsg.BundleCtrlType = BundleCtrlType(decoder.ReadUint16())
+	_bundlectrlmsg.Flags = BundleFlags(decoder.ReadUint16())
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeBundleProp(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bundlectrlmsg.Properties = append(_bundlectrlmsg.Properties, item)
+		}
+	}
+	return _bundlectrlmsg, nil
+}
+
+func NewBundleCtrlMsg() *BundleCtrlMsg {
+	obj := &BundleCtrlMsg{
+		Header: NewHeader(33),
+	}
+	return obj
+}
+
+type BundleFailedErrorMsg struct {
+	*ErrorMsg
+	Code BundleFailedCode
+	Data []byte
+}
+
+type IBundleFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() BundleFailedCode
+	GetData() []byte
+}
+
+func (self *BundleFailedErrorMsg) GetCode() BundleFailedCode {
+	return self.Code
+}
+
+func (self *BundleFailedErrorMsg) SetCode(v BundleFailedCode) {
+	self.Code = v
+}
+
+func (self *BundleFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BundleFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BundleFailedErrorMsg) 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 DecodeBundleFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BundleFailedErrorMsg, error) {
+	_bundlefailederrormsg := &BundleFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BundleFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_bundlefailederrormsg.Code = BundleFailedCode(decoder.ReadUint16())
+	_bundlefailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _bundlefailederrormsg, nil
+}
+
+func NewBundleFailedErrorMsg() *BundleFailedErrorMsg {
+	obj := &BundleFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(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
+	AuxiliaryId  uint8
+	Capabilities Capabilities
+	Reserved     uint32
+}
+
+type IFeaturesReply interface {
+	IHeader
+	GetDatapathId() uint64
+	GetNBuffers() uint32
+	GetNTables() uint8
+	GetAuxiliaryId() uint8
+	GetCapabilities() Capabilities
+	GetReserved() uint32
+}
+
+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) GetAuxiliaryId() uint8 {
+	return self.AuxiliaryId
+}
+
+func (self *FeaturesReply) SetAuxiliaryId(v uint8) {
+	self.AuxiliaryId = 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) 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.PutUint8(uint8(self.AuxiliaryId))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint32(uint32(self.Capabilities))
+	encoder.PutUint32(uint32(self.Reserved))
+	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())
+	_featuresreply.AuxiliaryId = uint8(decoder.ReadByte())
+	decoder.Skip(2)
+	_featuresreply.Capabilities = Capabilities(decoder.ReadUint32())
+	_featuresreply.Reserved = uint32(decoder.ReadUint32())
+	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() < 48 {
+		return nil, fmt.Errorf("FlowMod packet too short: %d < 48", 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
+	}
+
+	decoder.SkipAlign()
+
+	for decoder.Length() >= 4 {
+		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
+	Importance uint16
+}
+
+type IFlowAdd interface {
+	IFlowMod
+	GetImportance() uint16
+}
+
+func (self *FlowAdd) GetImportance() uint16 {
+	return self.Importance
+}
+
+func (self *FlowAdd) SetImportance(v uint16) {
+	self.Importance = v
+}
+
+func (self *FlowAdd) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Importance))
+	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}
+	if decoder.Length() < 10 {
+		return nil, fmt.Errorf("FlowAdd packet too short: %d < 10", decoder.Length())
+	}
+	_flowadd.Importance = uint16(decoder.ReadUint16())
+	return _flowadd, nil
+}
+
+func NewFlowAdd() *FlowAdd {
+	obj := &FlowAdd{
+		FlowMod: NewFlowMod(0),
+	}
+	return obj
+}
+
+type FlowDelete struct {
+	*FlowMod
+	Importance uint16
+}
+
+type IFlowDelete interface {
+	IFlowMod
+	GetImportance() uint16
+}
+
+func (self *FlowDelete) GetImportance() uint16 {
+	return self.Importance
+}
+
+func (self *FlowDelete) SetImportance(v uint16) {
+	self.Importance = v
+}
+
+func (self *FlowDelete) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Importance))
+	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}
+	if decoder.Length() < 10 {
+		return nil, fmt.Errorf("FlowDelete packet too short: %d < 10", decoder.Length())
+	}
+	_flowdelete.Importance = uint16(decoder.ReadUint16())
+	return _flowdelete, nil
+}
+
+func NewFlowDelete() *FlowDelete {
+	obj := &FlowDelete{
+		FlowMod: NewFlowMod(3),
+	}
+	return obj
+}
+
+type FlowDeleteStrict struct {
+	*FlowMod
+	Importance uint16
+}
+
+type IFlowDeleteStrict interface {
+	IFlowMod
+	GetImportance() uint16
+}
+
+func (self *FlowDeleteStrict) GetImportance() uint16 {
+	return self.Importance
+}
+
+func (self *FlowDeleteStrict) SetImportance(v uint16) {
+	self.Importance = v
+}
+
+func (self *FlowDeleteStrict) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Importance))
+	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}
+	if decoder.Length() < 10 {
+		return nil, fmt.Errorf("FlowDeleteStrict packet too short: %d < 10", decoder.Length())
+	}
+	_flowdeletestrict.Importance = uint16(decoder.ReadUint16())
+	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
+	Importance uint16
+}
+
+type IFlowModify interface {
+	IFlowMod
+	GetImportance() uint16
+}
+
+func (self *FlowModify) GetImportance() uint16 {
+	return self.Importance
+}
+
+func (self *FlowModify) SetImportance(v uint16) {
+	self.Importance = v
+}
+
+func (self *FlowModify) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Importance))
+	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}
+	if decoder.Length() < 10 {
+		return nil, fmt.Errorf("FlowModify packet too short: %d < 10", decoder.Length())
+	}
+	_flowmodify.Importance = uint16(decoder.ReadUint16())
+	return _flowmodify, nil
+}
+
+func NewFlowModify() *FlowModify {
+	obj := &FlowModify{
+		FlowMod: NewFlowMod(1),
+	}
+	return obj
+}
+
+type FlowModifyStrict struct {
+	*FlowMod
+	Importance uint16
+}
+
+type IFlowModifyStrict interface {
+	IFlowMod
+	GetImportance() uint16
+}
+
+func (self *FlowModifyStrict) GetImportance() uint16 {
+	return self.Importance
+}
+
+func (self *FlowModifyStrict) SetImportance(v uint16) {
+	self.Importance = v
+}
+
+func (self *FlowModifyStrict) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Importance))
+	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}
+	if decoder.Length() < 10 {
+		return nil, fmt.Errorf("FlowModifyStrict packet too short: %d < 10", decoder.Length())
+	}
+	_flowmodifystrict.Importance = uint16(decoder.ReadUint16())
+	return _flowmodifystrict, nil
+}
+
+func NewFlowModifyStrict() *FlowModifyStrict {
+	obj := &FlowModifyStrict{
+		FlowMod: NewFlowMod(2),
+	}
+	return obj
+}
+
+type FlowMonitorFailedErrorMsg struct {
+	*ErrorMsg
+	Code FlowMonitorFailedCode
+	Data []byte
+}
+
+type IFlowMonitorFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() FlowMonitorFailedCode
+	GetData() []byte
+}
+
+func (self *FlowMonitorFailedErrorMsg) GetCode() FlowMonitorFailedCode {
+	return self.Code
+}
+
+func (self *FlowMonitorFailedErrorMsg) SetCode(v FlowMonitorFailedCode) {
+	self.Code = v
+}
+
+func (self *FlowMonitorFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *FlowMonitorFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *FlowMonitorFailedErrorMsg) 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 DecodeFlowMonitorFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*FlowMonitorFailedErrorMsg, error) {
+	_flowmonitorfailederrormsg := &FlowMonitorFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("FlowMonitorFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_flowmonitorfailederrormsg.Code = FlowMonitorFailedCode(decoder.ReadUint16())
+	_flowmonitorfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _flowmonitorfailederrormsg, nil
+}
+
+func NewFlowMonitorFailedErrorMsg() *FlowMonitorFailedErrorMsg {
+	obj := &FlowMonitorFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(16),
+	}
+	return obj
+}
+
+type FlowMonitorReply struct {
+	*StatsReply
+	Entries []IFlowMonitorReplyEntry
+}
+
+type IFlowMonitorReply interface {
+	IStatsReply
+	GetEntries() []IFlowMonitorReplyEntry
+}
+
+func (self *FlowMonitorReply) GetEntries() []IFlowMonitorReplyEntry {
+	return self.Entries
+}
+
+func (self *FlowMonitorReply) SetEntries(v []IFlowMonitorReplyEntry) {
+	self.Entries = v
+}
+
+func (self *FlowMonitorReply) 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 DecodeFlowMonitorReply(parent *StatsReply, decoder *goloxi.Decoder) (*FlowMonitorReply, error) {
+	_flowmonitorreply := &FlowMonitorReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("FlowMonitorReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeFlowMonitorReplyEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_flowmonitorreply.Entries = append(_flowmonitorreply.Entries, item)
+		}
+	}
+	return _flowmonitorreply, nil
+}
+
+func NewFlowMonitorReply() *FlowMonitorReply {
+	obj := &FlowMonitorReply{
+		StatsReply: NewStatsReply(16),
+	}
+	return obj
+}
+
+type FlowMonitorRequest struct {
+	*StatsRequest
+	Entries []*FlowMonitorEntry
+}
+
+type IFlowMonitorRequest interface {
+	IStatsRequest
+	GetEntries() []*FlowMonitorEntry
+}
+
+func (self *FlowMonitorRequest) GetEntries() []*FlowMonitorEntry {
+	return self.Entries
+}
+
+func (self *FlowMonitorRequest) SetEntries(v []*FlowMonitorEntry) {
+	self.Entries = v
+}
+
+func (self *FlowMonitorRequest) 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))
+	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 DecodeFlowMonitorRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*FlowMonitorRequest, error) {
+	_flowmonitorrequest := &FlowMonitorRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("FlowMonitorRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 24 {
+		item, err := DecodeFlowMonitorEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_flowmonitorrequest.Entries = append(_flowmonitorrequest.Entries, item)
+		}
+	}
+	return _flowmonitorrequest, nil
+}
+
+func NewFlowMonitorRequest() *FlowMonitorRequest {
+	obj := &FlowMonitorRequest{
+		StatsRequest: NewStatsRequest(16),
+	}
+	return obj
+}
+
+type FlowRemoved struct {
+	*Header
+	Cookie       uint64
+	Priority     uint16
+	Reason       FlowRemovedReason
+	TableId      uint8
+	DurationSec  uint32
+	DurationNsec uint32
+	IdleTimeout  uint16
+	HardTimeout  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
+	GetHardTimeout() 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) GetHardTimeout() uint16 {
+	return self.HardTimeout
+}
+
+func (self *FlowRemoved) SetHardTimeout(v uint16) {
+	self.HardTimeout = 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.PutUint16(uint16(self.HardTimeout))
+	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() < 48 {
+		return nil, fmt.Errorf("FlowRemoved packet too short: %d < 48", 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())
+	_flowremoved.HardTimeout = uint16(decoder.ReadUint16())
+	_flowremoved.PacketCount = uint64(decoder.ReadUint64())
+	_flowremoved.ByteCount = uint64(decoder.ReadUint64())
+	if err := _flowremoved.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	decoder.SkipAlign()
+	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() >= 56 {
+		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() < 28 {
+		return nil, fmt.Errorf("FlowStatsRequest packet too short: %d < 28", 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
+	}
+
+	decoder.SkipAlign()
+	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 GroupFeaturesStatsReply struct {
+	*StatsReply
+	Types             uint32
+	Capabilities      GroupCapabilities
+	MaxGroupsAll      uint32
+	MaxGroupsSelect   uint32
+	MaxGroupsIndirect uint32
+	MaxGroupsFf       uint32
+	ActionsAll        uint32
+	ActionsSelect     uint32
+	ActionsIndirect   uint32
+	ActionsFf         uint32
+}
+
+type IGroupFeaturesStatsReply interface {
+	IStatsReply
+	GetTypes() uint32
+	GetCapabilities() GroupCapabilities
+	GetMaxGroupsAll() uint32
+	GetMaxGroupsSelect() uint32
+	GetMaxGroupsIndirect() uint32
+	GetMaxGroupsFf() uint32
+	GetActionsAll() uint32
+	GetActionsSelect() uint32
+	GetActionsIndirect() uint32
+	GetActionsFf() uint32
+}
+
+func (self *GroupFeaturesStatsReply) GetTypes() uint32 {
+	return self.Types
+}
+
+func (self *GroupFeaturesStatsReply) SetTypes(v uint32) {
+	self.Types = v
+}
+
+func (self *GroupFeaturesStatsReply) GetCapabilities() GroupCapabilities {
+	return self.Capabilities
+}
+
+func (self *GroupFeaturesStatsReply) SetCapabilities(v GroupCapabilities) {
+	self.Capabilities = v
+}
+
+func (self *GroupFeaturesStatsReply) GetMaxGroupsAll() uint32 {
+	return self.MaxGroupsAll
+}
+
+func (self *GroupFeaturesStatsReply) SetMaxGroupsAll(v uint32) {
+	self.MaxGroupsAll = v
+}
+
+func (self *GroupFeaturesStatsReply) GetMaxGroupsSelect() uint32 {
+	return self.MaxGroupsSelect
+}
+
+func (self *GroupFeaturesStatsReply) SetMaxGroupsSelect(v uint32) {
+	self.MaxGroupsSelect = v
+}
+
+func (self *GroupFeaturesStatsReply) GetMaxGroupsIndirect() uint32 {
+	return self.MaxGroupsIndirect
+}
+
+func (self *GroupFeaturesStatsReply) SetMaxGroupsIndirect(v uint32) {
+	self.MaxGroupsIndirect = v
+}
+
+func (self *GroupFeaturesStatsReply) GetMaxGroupsFf() uint32 {
+	return self.MaxGroupsFf
+}
+
+func (self *GroupFeaturesStatsReply) SetMaxGroupsFf(v uint32) {
+	self.MaxGroupsFf = v
+}
+
+func (self *GroupFeaturesStatsReply) GetActionsAll() uint32 {
+	return self.ActionsAll
+}
+
+func (self *GroupFeaturesStatsReply) SetActionsAll(v uint32) {
+	self.ActionsAll = v
+}
+
+func (self *GroupFeaturesStatsReply) GetActionsSelect() uint32 {
+	return self.ActionsSelect
+}
+
+func (self *GroupFeaturesStatsReply) SetActionsSelect(v uint32) {
+	self.ActionsSelect = v
+}
+
+func (self *GroupFeaturesStatsReply) GetActionsIndirect() uint32 {
+	return self.ActionsIndirect
+}
+
+func (self *GroupFeaturesStatsReply) SetActionsIndirect(v uint32) {
+	self.ActionsIndirect = v
+}
+
+func (self *GroupFeaturesStatsReply) GetActionsFf() uint32 {
+	return self.ActionsFf
+}
+
+func (self *GroupFeaturesStatsReply) SetActionsFf(v uint32) {
+	self.ActionsFf = v
+}
+
+func (self *GroupFeaturesStatsReply) 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.PutUint32(uint32(self.Types))
+	encoder.PutUint32(uint32(self.Capabilities))
+	encoder.PutUint32(uint32(self.MaxGroupsAll))
+	encoder.PutUint32(uint32(self.MaxGroupsSelect))
+	encoder.PutUint32(uint32(self.MaxGroupsIndirect))
+	encoder.PutUint32(uint32(self.MaxGroupsFf))
+	encoder.PutUint32(uint32(self.ActionsAll))
+	encoder.PutUint32(uint32(self.ActionsSelect))
+	encoder.PutUint32(uint32(self.ActionsIndirect))
+	encoder.PutUint32(uint32(self.ActionsFf))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeGroupFeaturesStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*GroupFeaturesStatsReply, error) {
+	_groupfeaturesstatsreply := &GroupFeaturesStatsReply{StatsReply: parent}
+	if decoder.Length() < 44 {
+		return nil, fmt.Errorf("GroupFeaturesStatsReply packet too short: %d < 44", decoder.Length())
+	}
+	decoder.Skip(4)
+	_groupfeaturesstatsreply.Types = uint32(decoder.ReadUint32())
+	_groupfeaturesstatsreply.Capabilities = GroupCapabilities(decoder.ReadUint32())
+	_groupfeaturesstatsreply.MaxGroupsAll = uint32(decoder.ReadUint32())
+	_groupfeaturesstatsreply.MaxGroupsSelect = uint32(decoder.ReadUint32())
+	_groupfeaturesstatsreply.MaxGroupsIndirect = uint32(decoder.ReadUint32())
+	_groupfeaturesstatsreply.MaxGroupsFf = uint32(decoder.ReadUint32())
+	_groupfeaturesstatsreply.ActionsAll = uint32(decoder.ReadUint32())
+	_groupfeaturesstatsreply.ActionsSelect = uint32(decoder.ReadUint32())
+	_groupfeaturesstatsreply.ActionsIndirect = uint32(decoder.ReadUint32())
+	_groupfeaturesstatsreply.ActionsFf = uint32(decoder.ReadUint32())
+	return _groupfeaturesstatsreply, nil
+}
+
+func NewGroupFeaturesStatsReply() *GroupFeaturesStatsReply {
+	obj := &GroupFeaturesStatsReply{
+		StatsReply: NewStatsReply(8),
+	}
+	return obj
+}
+
+type GroupFeaturesStatsRequest struct {
+	*StatsRequest
+}
+
+type IGroupFeaturesStatsRequest interface {
+	IStatsRequest
+}
+
+func (self *GroupFeaturesStatsRequest) 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 DecodeGroupFeaturesStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*GroupFeaturesStatsRequest, error) {
+	_groupfeaturesstatsrequest := &GroupFeaturesStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("GroupFeaturesStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _groupfeaturesstatsrequest, nil
+}
+
+func NewGroupFeaturesStatsRequest() *GroupFeaturesStatsRequest {
+	obj := &GroupFeaturesStatsRequest{
+		StatsRequest: NewStatsRequest(8),
+	}
+	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() >= 40 {
+		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
+	Elements []IHelloElem
+}
+
+type IHello interface {
+	IHeader
+	GetElements() []IHelloElem
+}
+
+func (self *Hello) GetElements() []IHelloElem {
+	return self.Elements
+}
+
+func (self *Hello) SetElements(v []IHelloElem) {
+	self.Elements = v
+}
+
+func (self *Hello) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	for _, obj := range self.Elements {
+		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 DecodeHello(parent *Header, decoder *goloxi.Decoder) (*Hello, error) {
+	_hello := &Hello{Header: parent}
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeHelloElem(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_hello.Elements = append(_hello.Elements, item)
+		}
+	}
+	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 MeterConfigStatsReply struct {
+	*StatsReply
+	Entries []*MeterConfig
+}
+
+type IMeterConfigStatsReply interface {
+	IStatsReply
+	GetEntries() []*MeterConfig
+}
+
+func (self *MeterConfigStatsReply) GetEntries() []*MeterConfig {
+	return self.Entries
+}
+
+func (self *MeterConfigStatsReply) SetEntries(v []*MeterConfig) {
+	self.Entries = v
+}
+
+func (self *MeterConfigStatsReply) 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 DecodeMeterConfigStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*MeterConfigStatsReply, error) {
+	_meterconfigstatsreply := &MeterConfigStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("MeterConfigStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeMeterConfig(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_meterconfigstatsreply.Entries = append(_meterconfigstatsreply.Entries, item)
+		}
+	}
+	return _meterconfigstatsreply, nil
+}
+
+func NewMeterConfigStatsReply() *MeterConfigStatsReply {
+	obj := &MeterConfigStatsReply{
+		StatsReply: NewStatsReply(10),
+	}
+	return obj
+}
+
+type MeterConfigStatsRequest struct {
+	*StatsRequest
+	MeterId uint32
+}
+
+type IMeterConfigStatsRequest interface {
+	IStatsRequest
+	GetMeterId() uint32
+}
+
+func (self *MeterConfigStatsRequest) GetMeterId() uint32 {
+	return self.MeterId
+}
+
+func (self *MeterConfigStatsRequest) SetMeterId(v uint32) {
+	self.MeterId = v
+}
+
+func (self *MeterConfigStatsRequest) 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.MeterId))
+	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 DecodeMeterConfigStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*MeterConfigStatsRequest, error) {
+	_meterconfigstatsrequest := &MeterConfigStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("MeterConfigStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	_meterconfigstatsrequest.MeterId = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+	return _meterconfigstatsrequest, nil
+}
+
+func NewMeterConfigStatsRequest() *MeterConfigStatsRequest {
+	obj := &MeterConfigStatsRequest{
+		StatsRequest: NewStatsRequest(10),
+	}
+	return obj
+}
+
+type MeterFeaturesStatsReply struct {
+	*StatsReply
+	Features MeterFeatures
+}
+
+type IMeterFeaturesStatsReply interface {
+	IStatsReply
+	GetFeatures() MeterFeatures
+}
+
+func (self *MeterFeaturesStatsReply) GetFeatures() MeterFeatures {
+	return self.Features
+}
+
+func (self *MeterFeaturesStatsReply) SetFeatures(v MeterFeatures) {
+	self.Features = v
+}
+
+func (self *MeterFeaturesStatsReply) 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))
+	if err := self.Features.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 DecodeMeterFeaturesStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*MeterFeaturesStatsReply, error) {
+	_meterfeaturesstatsreply := &MeterFeaturesStatsReply{StatsReply: parent}
+	if decoder.Length() < 20 {
+		return nil, fmt.Errorf("MeterFeaturesStatsReply packet too short: %d < 20", decoder.Length())
+	}
+	decoder.Skip(4)
+	if err := _meterfeaturesstatsreply.Features.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _meterfeaturesstatsreply, nil
+}
+
+func NewMeterFeaturesStatsReply() *MeterFeaturesStatsReply {
+	obj := &MeterFeaturesStatsReply{
+		StatsReply: NewStatsReply(11),
+	}
+	return obj
+}
+
+type MeterFeaturesStatsRequest struct {
+	*StatsRequest
+}
+
+type IMeterFeaturesStatsRequest interface {
+	IStatsRequest
+}
+
+func (self *MeterFeaturesStatsRequest) 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 DecodeMeterFeaturesStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*MeterFeaturesStatsRequest, error) {
+	_meterfeaturesstatsrequest := &MeterFeaturesStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("MeterFeaturesStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _meterfeaturesstatsrequest, nil
+}
+
+func NewMeterFeaturesStatsRequest() *MeterFeaturesStatsRequest {
+	obj := &MeterFeaturesStatsRequest{
+		StatsRequest: NewStatsRequest(11),
+	}
+	return obj
+}
+
+type MeterMod struct {
+	*Header
+	Command MeterModCommand
+	Flags   MeterFlags
+	MeterId uint32
+	Bands   []IMeterBand
+}
+
+type IMeterMod interface {
+	IHeader
+	GetCommand() MeterModCommand
+	GetFlags() MeterFlags
+	GetMeterId() uint32
+	GetBands() []IMeterBand
+}
+
+func (self *MeterMod) GetCommand() MeterModCommand {
+	return self.Command
+}
+
+func (self *MeterMod) SetCommand(v MeterModCommand) {
+	self.Command = v
+}
+
+func (self *MeterMod) GetFlags() MeterFlags {
+	return self.Flags
+}
+
+func (self *MeterMod) SetFlags(v MeterFlags) {
+	self.Flags = v
+}
+
+func (self *MeterMod) GetMeterId() uint32 {
+	return self.MeterId
+}
+
+func (self *MeterMod) SetMeterId(v uint32) {
+	self.MeterId = v
+}
+
+func (self *MeterMod) GetBands() []IMeterBand {
+	return self.Bands
+}
+
+func (self *MeterMod) SetBands(v []IMeterBand) {
+	self.Bands = v
+}
+
+func (self *MeterMod) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Command))
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.PutUint32(uint32(self.MeterId))
+	for _, obj := range self.Bands {
+		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 DecodeMeterMod(parent *Header, decoder *goloxi.Decoder) (*MeterMod, error) {
+	_metermod := &MeterMod{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("MeterMod packet too short: %d < 8", decoder.Length())
+	}
+	_metermod.Command = MeterModCommand(decoder.ReadUint16())
+	_metermod.Flags = MeterFlags(decoder.ReadUint16())
+	_metermod.MeterId = uint32(decoder.ReadUint32())
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeMeterBand(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_metermod.Bands = append(_metermod.Bands, item)
+		}
+	}
+	return _metermod, nil
+}
+
+func NewMeterMod() *MeterMod {
+	obj := &MeterMod{
+		Header: NewHeader(29),
+	}
+	return obj
+}
+
+type MeterModFailedErrorMsg struct {
+	*ErrorMsg
+	Code MeterModFailedCode
+	Data []byte
+}
+
+type IMeterModFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() MeterModFailedCode
+	GetData() []byte
+}
+
+func (self *MeterModFailedErrorMsg) GetCode() MeterModFailedCode {
+	return self.Code
+}
+
+func (self *MeterModFailedErrorMsg) SetCode(v MeterModFailedCode) {
+	self.Code = v
+}
+
+func (self *MeterModFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *MeterModFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *MeterModFailedErrorMsg) 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 DecodeMeterModFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*MeterModFailedErrorMsg, error) {
+	_metermodfailederrormsg := &MeterModFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("MeterModFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_metermodfailederrormsg.Code = MeterModFailedCode(decoder.ReadUint16())
+	_metermodfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _metermodfailederrormsg, nil
+}
+
+func NewMeterModFailedErrorMsg() *MeterModFailedErrorMsg {
+	obj := &MeterModFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(12),
+	}
+	return obj
+}
+
+type MeterStatsReply struct {
+	*StatsReply
+	Entries []*MeterStats
+}
+
+type IMeterStatsReply interface {
+	IStatsReply
+	GetEntries() []*MeterStats
+}
+
+func (self *MeterStatsReply) GetEntries() []*MeterStats {
+	return self.Entries
+}
+
+func (self *MeterStatsReply) SetEntries(v []*MeterStats) {
+	self.Entries = v
+}
+
+func (self *MeterStatsReply) 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 DecodeMeterStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*MeterStatsReply, error) {
+	_meterstatsreply := &MeterStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("MeterStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 40 {
+		item, err := DecodeMeterStats(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_meterstatsreply.Entries = append(_meterstatsreply.Entries, item)
+		}
+	}
+	return _meterstatsreply, nil
+}
+
+func NewMeterStatsReply() *MeterStatsReply {
+	obj := &MeterStatsReply{
+		StatsReply: NewStatsReply(9),
+	}
+	return obj
+}
+
+type MeterStatsRequest struct {
+	*StatsRequest
+	MeterId uint32
+}
+
+type IMeterStatsRequest interface {
+	IStatsRequest
+	GetMeterId() uint32
+}
+
+func (self *MeterStatsRequest) GetMeterId() uint32 {
+	return self.MeterId
+}
+
+func (self *MeterStatsRequest) SetMeterId(v uint32) {
+	self.MeterId = v
+}
+
+func (self *MeterStatsRequest) 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.MeterId))
+	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 DecodeMeterStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*MeterStatsRequest, error) {
+	_meterstatsrequest := &MeterStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("MeterStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	_meterstatsrequest.MeterId = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+	return _meterstatsrequest, nil
+}
+
+func NewMeterStatsRequest() *MeterStatsRequest {
+	obj := &MeterStatsRequest{
+		StatsRequest: NewStatsRequest(9),
+	}
+	return obj
+}
+
+type NiciraStatsReply struct {
+	*ExperimenterStatsReply
+}
+
+type INiciraStatsReply interface {
+	IExperimenterStatsReply
+}
+
+func (self *NiciraStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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())
+	}
+
+	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
+	MonitorId    uint32
+	MonitorFlags NxFlowMonitorFlags
+	OutPort      Port
+	MatchLen     uint16
+	TableId      uint8
+	Match        NiciraMatch
+}
+
+type INiciraFlowMonitorRequest interface {
+	IExperimenterStatsRequest
+	GetMonitorId() uint32
+	GetMonitorFlags() NxFlowMonitorFlags
+	GetOutPort() Port
+	GetMatchLen() uint16
+	GetTableId() uint8
+	GetMatch() NiciraMatch
+}
+
+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.Write(bytes.Repeat([]byte{0}, 4))
+	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() < 22 {
+		return nil, fmt.Errorf("NiciraFlowMonitorRequest packet too short: %d < 22", decoder.Length())
+	}
+	decoder.Skip(4)
+	_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
+	OutPort  Port
+	MatchLen uint16
+	TableId  uint8
+}
+
+type INiciraFlowStatsRequest interface {
+	IExperimenterStatsRequest
+	GetOutPort() Port
+	GetMatchLen() uint16
+	GetTableId() uint8
+}
+
+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.Write(bytes.Repeat([]byte{0}, 4))
+	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() < 14 {
+		return nil, fmt.Errorf("NiciraFlowStatsRequest packet too short: %d < 14", decoder.Length())
+	}
+	decoder.Skip(4)
+	_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
+}
+
+type INiciraHeader interface {
+	IExperimenter
+}
+
+func (self *NiciraHeader) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Experimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func DecodeNiciraHeader(parent *Experimenter, decoder *goloxi.Decoder) (INiciraHeader, error) {
+	_niciraheader := &NiciraHeader{Experimenter: parent}
+	return _niciraheader, nil
+}
+
+func NewNiciraHeader(_subtype uint32) *NiciraHeader {
+	obj := &NiciraHeader{
+		Experimenter: NewExperimenter(8992),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type PacketIn struct {
+	*Header
+	BufferId uint32
+	TotalLen uint16
+	Reason   uint8
+	TableId  uint8
+	Cookie   uint64
+	Match    Match
+	Data     []byte
+}
+
+type IPacketIn interface {
+	IHeader
+	GetBufferId() uint32
+	GetTotalLen() uint16
+	GetReason() uint8
+	GetTableId() uint8
+	GetCookie() uint64
+	GetMatch() Match
+	GetData() []byte
+}
+
+func (self *PacketIn) GetBufferId() uint32 {
+	return self.BufferId
+}
+
+func (self *PacketIn) SetBufferId(v uint32) {
+	self.BufferId = 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) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *PacketIn) SetCookie(v uint64) {
+	self.Cookie = v
+}
+
+func (self *PacketIn) GetMatch() Match {
+	return self.Match
+}
+
+func (self *PacketIn) SetMatch(v Match) {
+	self.Match = 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))
+	encoder.PutUint16(uint16(self.TotalLen))
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.PutUint64(uint64(self.Cookie))
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	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() < 26 {
+		return nil, fmt.Errorf("PacketIn packet too short: %d < 26", decoder.Length())
+	}
+	_packetin.BufferId = uint32(decoder.ReadUint32())
+	_packetin.TotalLen = uint16(decoder.ReadUint16())
+	_packetin.Reason = uint8(decoder.ReadByte())
+	_packetin.TableId = uint8(decoder.ReadByte())
+	_packetin.Cookie = uint64(decoder.ReadUint64())
+	if err := _packetin.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	decoder.SkipAlign()
+	decoder.Skip(2)
+	_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 PortDescStatsReply struct {
+	*StatsReply
+	Entries []*PortDesc
+}
+
+type IPortDescStatsReply interface {
+	IStatsReply
+	GetEntries() []*PortDesc
+}
+
+func (self *PortDescStatsReply) GetEntries() []*PortDesc {
+	return self.Entries
+}
+
+func (self *PortDescStatsReply) SetEntries(v []*PortDesc) {
+	self.Entries = v
+}
+
+func (self *PortDescStatsReply) 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 DecodePortDescStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*PortDescStatsReply, error) {
+	_portdescstatsreply := &PortDescStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("PortDescStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 40 {
+		item := &PortDesc{}
+		if err := item.Decode(decoder); err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_portdescstatsreply.Entries = append(_portdescstatsreply.Entries, item)
+		}
+	}
+	return _portdescstatsreply, nil
+}
+
+func NewPortDescStatsReply() *PortDescStatsReply {
+	obj := &PortDescStatsReply{
+		StatsReply: NewStatsReply(13),
+	}
+	return obj
+}
+
+type PortDescStatsRequest struct {
+	*StatsRequest
+}
+
+type IPortDescStatsRequest interface {
+	IStatsRequest
+}
+
+func (self *PortDescStatsRequest) 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 DecodePortDescStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*PortDescStatsRequest, error) {
+	_portdescstatsrequest := &PortDescStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("PortDescStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _portdescstatsrequest, nil
+}
+
+func NewPortDescStatsRequest() *PortDescStatsRequest {
+	obj := &PortDescStatsRequest{
+		StatsRequest: NewStatsRequest(13),
+	}
+	return obj
+}
+
+type PortMod struct {
+	*Header
+	PortNo     Port
+	HwAddr     net.HardwareAddr
+	Config     PortConfig
+	Mask       PortConfig
+	Properties []IPortModProp
+}
+
+type IPortMod interface {
+	IHeader
+	GetPortNo() Port
+	GetHwAddr() net.HardwareAddr
+	GetConfig() PortConfig
+	GetMask() PortConfig
+	GetProperties() []IPortModProp
+}
+
+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) GetProperties() []IPortModProp {
+	return self.Properties
+}
+
+func (self *PortMod) SetProperties(v []IPortModProp) {
+	self.Properties = 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))
+	for _, obj := range self.Properties {
+		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 DecodePortMod(parent *Header, decoder *goloxi.Decoder) (*PortMod, error) {
+	_portmod := &PortMod{Header: parent}
+	if decoder.Length() < 24 {
+		return nil, fmt.Errorf("PortMod packet too short: %d < 24", 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())
+
+	for decoder.Length() >= 4 {
+		item, err := DecodePortModProp(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_portmod.Properties = append(_portmod.Properties, item)
+		}
+	}
+	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() >= 80 {
+		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() < 48 {
+		return nil, fmt.Errorf("PortStatus packet too short: %d < 48", 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 QueueDescStatsReply struct {
+	*StatsReply
+	Entries []*QueueDesc
+}
+
+type IQueueDescStatsReply interface {
+	IStatsReply
+	GetEntries() []*QueueDesc
+}
+
+func (self *QueueDescStatsReply) GetEntries() []*QueueDesc {
+	return self.Entries
+}
+
+func (self *QueueDescStatsReply) SetEntries(v []*QueueDesc) {
+	self.Entries = v
+}
+
+func (self *QueueDescStatsReply) 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 DecodeQueueDescStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*QueueDescStatsReply, error) {
+	_queuedescstatsreply := &QueueDescStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("QueueDescStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 16 {
+		item, err := DecodeQueueDesc(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_queuedescstatsreply.Entries = append(_queuedescstatsreply.Entries, item)
+		}
+	}
+	return _queuedescstatsreply, nil
+}
+
+func NewQueueDescStatsReply() *QueueDescStatsReply {
+	obj := &QueueDescStatsReply{
+		StatsReply: NewStatsReply(15),
+	}
+	return obj
+}
+
+type QueueDescStatsRequest struct {
+	*StatsRequest
+	PortNo  Port
+	QueueId uint32
+}
+
+type IQueueDescStatsRequest interface {
+	IStatsRequest
+	GetPortNo() Port
+	GetQueueId() uint32
+}
+
+func (self *QueueDescStatsRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *QueueDescStatsRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *QueueDescStatsRequest) GetQueueId() uint32 {
+	return self.QueueId
+}
+
+func (self *QueueDescStatsRequest) SetQueueId(v uint32) {
+	self.QueueId = v
+}
+
+func (self *QueueDescStatsRequest) 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 DecodeQueueDescStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*QueueDescStatsRequest, error) {
+	_queuedescstatsrequest := &QueueDescStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("QueueDescStatsRequest packet too short: %d < 12", decoder.Length())
+	}
+	decoder.Skip(4)
+	_queuedescstatsrequest.PortNo.Decode(decoder)
+	_queuedescstatsrequest.QueueId = uint32(decoder.ReadUint32())
+	return _queuedescstatsrequest, nil
+}
+
+func NewQueueDescStatsRequest() *QueueDescStatsRequest {
+	obj := &QueueDescStatsRequest{
+		StatsRequest: NewStatsRequest(15),
+	}
+	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() >= 48 {
+		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 Requestforward struct {
+	*Header
+	Request IHeader
+}
+
+type IRequestforward interface {
+	IHeader
+	GetRequest() IHeader
+}
+
+func (self *Requestforward) GetRequest() IHeader {
+	return self.Request
+}
+
+func (self *Requestforward) SetRequest(v IHeader) {
+	self.Request = v
+}
+
+func (self *Requestforward) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.Request.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeRequestforward(parent *Header, decoder *goloxi.Decoder) (*Requestforward, error) {
+	_requestforward := &Requestforward{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("Requestforward packet too short: %d < 8", decoder.Length())
+	}
+	if obj, err := DecodeHeader(decoder); err != nil {
+		return nil, err
+	} else {
+		_requestforward.Request = obj
+	}
+
+	return _requestforward, nil
+}
+
+func NewRequestforward() *Requestforward {
+	obj := &Requestforward{
+		Header: NewHeader(32),
+	}
+	return obj
+}
+
+type RoleReply struct {
+	*Header
+	Role         ControllerRole
+	GenerationId uint64
+}
+
+type IRoleReply interface {
+	IHeader
+	GetRole() ControllerRole
+	GetGenerationId() uint64
+}
+
+func (self *RoleReply) GetRole() ControllerRole {
+	return self.Role
+}
+
+func (self *RoleReply) SetRole(v ControllerRole) {
+	self.Role = v
+}
+
+func (self *RoleReply) GetGenerationId() uint64 {
+	return self.GenerationId
+}
+
+func (self *RoleReply) SetGenerationId(v uint64) {
+	self.GenerationId = v
+}
+
+func (self *RoleReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Role))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint64(uint64(self.GenerationId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeRoleReply(parent *Header, decoder *goloxi.Decoder) (*RoleReply, error) {
+	_rolereply := &RoleReply{Header: parent}
+	if decoder.Length() < 16 {
+		return nil, fmt.Errorf("RoleReply packet too short: %d < 16", decoder.Length())
+	}
+	_rolereply.Role = ControllerRole(decoder.ReadUint32())
+	decoder.Skip(4)
+	_rolereply.GenerationId = uint64(decoder.ReadUint64())
+	return _rolereply, nil
+}
+
+func NewRoleReply() *RoleReply {
+	obj := &RoleReply{
+		Header: NewHeader(25),
+	}
+	return obj
+}
+
+type RoleRequest struct {
+	*Header
+	Role         ControllerRole
+	GenerationId uint64
+}
+
+type IRoleRequest interface {
+	IHeader
+	GetRole() ControllerRole
+	GetGenerationId() uint64
+}
+
+func (self *RoleRequest) GetRole() ControllerRole {
+	return self.Role
+}
+
+func (self *RoleRequest) SetRole(v ControllerRole) {
+	self.Role = v
+}
+
+func (self *RoleRequest) GetGenerationId() uint64 {
+	return self.GenerationId
+}
+
+func (self *RoleRequest) SetGenerationId(v uint64) {
+	self.GenerationId = v
+}
+
+func (self *RoleRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Role))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint64(uint64(self.GenerationId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeRoleRequest(parent *Header, decoder *goloxi.Decoder) (*RoleRequest, error) {
+	_rolerequest := &RoleRequest{Header: parent}
+	if decoder.Length() < 16 {
+		return nil, fmt.Errorf("RoleRequest packet too short: %d < 16", decoder.Length())
+	}
+	_rolerequest.Role = ControllerRole(decoder.ReadUint32())
+	decoder.Skip(4)
+	_rolerequest.GenerationId = uint64(decoder.ReadUint64())
+	return _rolerequest, nil
+}
+
+func NewRoleRequest() *RoleRequest {
+	obj := &RoleRequest{
+		Header: NewHeader(24),
+	}
+	return obj
+}
+
+type RoleRequestFailedErrorMsg struct {
+	*ErrorMsg
+	Code RoleRequestFailedCode
+	Data []byte
+}
+
+type IRoleRequestFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() RoleRequestFailedCode
+	GetData() []byte
+}
+
+func (self *RoleRequestFailedErrorMsg) GetCode() RoleRequestFailedCode {
+	return self.Code
+}
+
+func (self *RoleRequestFailedErrorMsg) SetCode(v RoleRequestFailedCode) {
+	self.Code = v
+}
+
+func (self *RoleRequestFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *RoleRequestFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *RoleRequestFailedErrorMsg) 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 DecodeRoleRequestFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*RoleRequestFailedErrorMsg, error) {
+	_rolerequestfailederrormsg := &RoleRequestFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("RoleRequestFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_rolerequestfailederrormsg.Code = RoleRequestFailedCode(decoder.ReadUint16())
+	_rolerequestfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _rolerequestfailederrormsg, nil
+}
+
+func NewRoleRequestFailedErrorMsg() *RoleRequestFailedErrorMsg {
+	obj := &RoleRequestFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(11),
+	}
+	return obj
+}
+
+type RoleStatus struct {
+	*Header
+	Role         ControllerRole
+	Reason       ControllerRoleReason
+	GenerationId uint64
+	Properties   []IRoleProp
+}
+
+type IRoleStatus interface {
+	IHeader
+	GetRole() ControllerRole
+	GetReason() ControllerRoleReason
+	GetGenerationId() uint64
+	GetProperties() []IRoleProp
+}
+
+func (self *RoleStatus) GetRole() ControllerRole {
+	return self.Role
+}
+
+func (self *RoleStatus) SetRole(v ControllerRole) {
+	self.Role = v
+}
+
+func (self *RoleStatus) GetReason() ControllerRoleReason {
+	return self.Reason
+}
+
+func (self *RoleStatus) SetReason(v ControllerRoleReason) {
+	self.Reason = v
+}
+
+func (self *RoleStatus) GetGenerationId() uint64 {
+	return self.GenerationId
+}
+
+func (self *RoleStatus) SetGenerationId(v uint64) {
+	self.GenerationId = v
+}
+
+func (self *RoleStatus) GetProperties() []IRoleProp {
+	return self.Properties
+}
+
+func (self *RoleStatus) SetProperties(v []IRoleProp) {
+	self.Properties = v
+}
+
+func (self *RoleStatus) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Role))
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.PutUint64(uint64(self.GenerationId))
+	for _, obj := range self.Properties {
+		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 DecodeRoleStatus(parent *Header, decoder *goloxi.Decoder) (*RoleStatus, error) {
+	_rolestatus := &RoleStatus{Header: parent}
+	if decoder.Length() < 16 {
+		return nil, fmt.Errorf("RoleStatus packet too short: %d < 16", decoder.Length())
+	}
+	_rolestatus.Role = ControllerRole(decoder.ReadUint32())
+	_rolestatus.Reason = ControllerRoleReason(decoder.ReadByte())
+	decoder.Skip(3)
+	_rolestatus.GenerationId = uint64(decoder.ReadUint64())
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeRoleProp(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_rolestatus.Properties = append(_rolestatus.Properties, item)
+		}
+	}
+	return _rolestatus, nil
+}
+
+func NewRoleStatus() *RoleStatus {
+	obj := &RoleStatus{
+		Header: NewHeader(30),
+	}
+	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 TableDescStatsReply struct {
+	*StatsReply
+	Entries []*TableDesc
+}
+
+type ITableDescStatsReply interface {
+	IStatsReply
+	GetEntries() []*TableDesc
+}
+
+func (self *TableDescStatsReply) GetEntries() []*TableDesc {
+	return self.Entries
+}
+
+func (self *TableDescStatsReply) SetEntries(v []*TableDesc) {
+	self.Entries = v
+}
+
+func (self *TableDescStatsReply) 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 DecodeTableDescStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*TableDescStatsReply, error) {
+	_tabledescstatsreply := &TableDescStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("TableDescStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 8 {
+		item := &TableDesc{}
+		if err := item.Decode(decoder); err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_tabledescstatsreply.Entries = append(_tabledescstatsreply.Entries, item)
+		}
+	}
+	return _tabledescstatsreply, nil
+}
+
+func NewTableDescStatsReply() *TableDescStatsReply {
+	obj := &TableDescStatsReply{
+		StatsReply: NewStatsReply(14),
+	}
+	return obj
+}
+
+type TableDescStatsRequest struct {
+	*StatsRequest
+}
+
+type ITableDescStatsRequest interface {
+	IStatsRequest
+}
+
+func (self *TableDescStatsRequest) 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 DecodeTableDescStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*TableDescStatsRequest, error) {
+	_tabledescstatsrequest := &TableDescStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("TableDescStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _tabledescstatsrequest, nil
+}
+
+func NewTableDescStatsRequest() *TableDescStatsRequest {
+	obj := &TableDescStatsRequest{
+		StatsRequest: NewStatsRequest(14),
+	}
+	return obj
+}
+
+type TableFeaturesFailedErrorMsg struct {
+	*ErrorMsg
+	Code TableFeaturesFailedCode
+	Data []byte
+}
+
+type ITableFeaturesFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() TableFeaturesFailedCode
+	GetData() []byte
+}
+
+func (self *TableFeaturesFailedErrorMsg) GetCode() TableFeaturesFailedCode {
+	return self.Code
+}
+
+func (self *TableFeaturesFailedErrorMsg) SetCode(v TableFeaturesFailedCode) {
+	self.Code = v
+}
+
+func (self *TableFeaturesFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *TableFeaturesFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *TableFeaturesFailedErrorMsg) 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 DecodeTableFeaturesFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*TableFeaturesFailedErrorMsg, error) {
+	_tablefeaturesfailederrormsg := &TableFeaturesFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("TableFeaturesFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_tablefeaturesfailederrormsg.Code = TableFeaturesFailedCode(decoder.ReadUint16())
+	_tablefeaturesfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _tablefeaturesfailederrormsg, nil
+}
+
+func NewTableFeaturesFailedErrorMsg() *TableFeaturesFailedErrorMsg {
+	obj := &TableFeaturesFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(13),
+	}
+	return obj
+}
+
+type TableFeaturesStatsReply struct {
+	*StatsReply
+	Entries []*TableFeatures
+}
+
+type ITableFeaturesStatsReply interface {
+	IStatsReply
+	GetEntries() []*TableFeatures
+}
+
+func (self *TableFeaturesStatsReply) GetEntries() []*TableFeatures {
+	return self.Entries
+}
+
+func (self *TableFeaturesStatsReply) SetEntries(v []*TableFeatures) {
+	self.Entries = v
+}
+
+func (self *TableFeaturesStatsReply) 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 DecodeTableFeaturesStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*TableFeaturesStatsReply, error) {
+	_tablefeaturesstatsreply := &TableFeaturesStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("TableFeaturesStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 64 {
+		item, err := DecodeTableFeatures(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_tablefeaturesstatsreply.Entries = append(_tablefeaturesstatsreply.Entries, item)
+		}
+	}
+	return _tablefeaturesstatsreply, nil
+}
+
+func NewTableFeaturesStatsReply() *TableFeaturesStatsReply {
+	obj := &TableFeaturesStatsReply{
+		StatsReply: NewStatsReply(12),
+	}
+	return obj
+}
+
+type TableFeaturesStatsRequest struct {
+	*StatsRequest
+	Entries []*TableFeatures
+}
+
+type ITableFeaturesStatsRequest interface {
+	IStatsRequest
+	GetEntries() []*TableFeatures
+}
+
+func (self *TableFeaturesStatsRequest) GetEntries() []*TableFeatures {
+	return self.Entries
+}
+
+func (self *TableFeaturesStatsRequest) SetEntries(v []*TableFeatures) {
+	self.Entries = v
+}
+
+func (self *TableFeaturesStatsRequest) 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))
+	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 DecodeTableFeaturesStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*TableFeaturesStatsRequest, error) {
+	_tablefeaturesstatsrequest := &TableFeaturesStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("TableFeaturesStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 64 {
+		item, err := DecodeTableFeatures(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_tablefeaturesstatsrequest.Entries = append(_tablefeaturesstatsrequest.Entries, item)
+		}
+	}
+	return _tablefeaturesstatsrequest, nil
+}
+
+func NewTableFeaturesStatsRequest() *TableFeaturesStatsRequest {
+	obj := &TableFeaturesStatsRequest{
+		StatsRequest: NewStatsRequest(12),
+	}
+	return obj
+}
+
+type TableMod struct {
+	*Header
+	TableId    uint8
+	Config     uint32
+	Properties []ITableModProp
+}
+
+type ITableMod interface {
+	IHeader
+	GetTableId() uint8
+	GetConfig() uint32
+	GetProperties() []ITableModProp
+}
+
+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) GetProperties() []ITableModProp {
+	return self.Properties
+}
+
+func (self *TableMod) SetProperties(v []ITableModProp) {
+	self.Properties = 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))
+	for _, obj := range self.Properties {
+		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 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())
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeTableModProp(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_tablemod.Properties = append(_tablemod.Properties, item)
+		}
+	}
+	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() >= 24 {
+		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
+}
+
+type TableStatus struct {
+	*Header
+	Role   uint32
+	Reason TableReason
+	Table  TableDesc
+}
+
+type ITableStatus interface {
+	IHeader
+	GetRole() uint32
+	GetReason() TableReason
+	GetTable() TableDesc
+}
+
+func (self *TableStatus) GetRole() uint32 {
+	return self.Role
+}
+
+func (self *TableStatus) SetRole(v uint32) {
+	self.Role = v
+}
+
+func (self *TableStatus) GetReason() TableReason {
+	return self.Reason
+}
+
+func (self *TableStatus) SetReason(v TableReason) {
+	self.Reason = v
+}
+
+func (self *TableStatus) GetTable() TableDesc {
+	return self.Table
+}
+
+func (self *TableStatus) SetTable(v TableDesc) {
+	self.Table = v
+}
+
+func (self *TableStatus) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Role))
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.Write(bytes.Repeat([]byte{0}, 7))
+	if err := self.Table.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 DecodeTableStatus(parent *Header, decoder *goloxi.Decoder) (*TableStatus, error) {
+	_tablestatus := &TableStatus{Header: parent}
+	if decoder.Length() < 20 {
+		return nil, fmt.Errorf("TableStatus packet too short: %d < 20", decoder.Length())
+	}
+	_tablestatus.Role = uint32(decoder.ReadUint32())
+	_tablestatus.Reason = TableReason(decoder.ReadByte())
+	decoder.Skip(7)
+	if err := _tablestatus.Table.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _tablestatus, nil
+}
+
+func NewTableStatus() *TableStatus {
+	obj := &TableStatus{
+		Header: NewHeader(31),
+	}
+	return obj
+}
