diff --git a/vendor/github.com/opencord/goloxi/of13/message.go b/vendor/github.com/opencord/goloxi/of13/message.go
new file mode 100644
index 0000000..e627a9d
--- /dev/null
+++ b/vendor/github.com/opencord/goloxi/of13/message.go
@@ -0,0 +1,11407 @@
+/*
+ * 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 of13
+
+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(4))
+	encoder.PutUint8(uint8(self.Type))
+	encoder.PutUint16(uint16(self.Length))
+	encoder.PutUint32(uint32(self.Xid))
+
+	return nil
+}
+func (self *Header) Decode(decoder *goloxi.Decoder) error {
+	if decoder.Length() < 8 {
+		return fmt.Errorf("Header packet too short: %d < 8", decoder.Length())
+	}
+
+	self.Version = uint8(decoder.ReadByte())
+	self.Type = uint8(decoder.ReadByte())
+	self.Length = uint16(decoder.ReadUint16())
+	oldDecoder := decoder
+	defer func() { decoder = oldDecoder }()
+	decoder = decoder.SliceDecoder(int(self.Length), 2+2)
+	self.Xid = uint32(decoder.ReadUint32())
+
+	return nil
+}
+func DecodeHeader(decoder *goloxi.Decoder) (IHeader, error) {
+	_header := &Header{}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("Header packet too short: %d < 8", decoder.Length())
+	}
+	_header.Version = uint8(decoder.ReadByte())
+	_header.Type = uint8(decoder.ReadByte())
+	_header.Length = uint16(decoder.ReadUint16())
+	oldDecoder := decoder
+	defer func() { decoder = oldDecoder }()
+	decoder = decoder.SliceDecoder(int(_header.Length), 2+2)
+	_header.Xid = uint32(decoder.ReadUint32())
+
+	switch _header.Type {
+	case 0:
+		return DecodeHello(_header, decoder)
+	case 1:
+		return DecodeErrorMsg(_header, decoder)
+	case 2:
+		return DecodeEchoRequest(_header, decoder)
+	case 3:
+		return DecodeEchoReply(_header, decoder)
+	case 4:
+		return DecodeExperimenter(_header, decoder)
+	case 5:
+		return DecodeFeaturesRequest(_header, decoder)
+	case 6:
+		return DecodeFeaturesReply(_header, decoder)
+	case 7:
+		return DecodeGetConfigRequest(_header, decoder)
+	case 8:
+		return DecodeGetConfigReply(_header, decoder)
+	case 9:
+		return DecodeSetConfig(_header, decoder)
+	case 10:
+		return DecodePacketIn(_header, decoder)
+	case 11:
+		return DecodeFlowRemoved(_header, decoder)
+	case 12:
+		return DecodePortStatus(_header, decoder)
+	case 13:
+		return DecodePacketOut(_header, decoder)
+	case 14:
+		return DecodeFlowMod(_header, decoder)
+	case 15:
+		return DecodeGroupMod(_header, decoder)
+	case 16:
+		return DecodePortMod(_header, decoder)
+	case 17:
+		return DecodeTableMod(_header, decoder)
+	case 18:
+		return DecodeStatsRequest(_header, decoder)
+	case 19:
+		return DecodeStatsReply(_header, decoder)
+	case 20:
+		return DecodeBarrierRequest(_header, decoder)
+	case 21:
+		return DecodeBarrierReply(_header, decoder)
+	case 22:
+		return DecodeQueueGetConfigRequest(_header, decoder)
+	case 23:
+		return DecodeQueueGetConfigReply(_header, decoder)
+	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)
+	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 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 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 AsyncGetReply struct {
+	*Header
+	PacketInMaskEqualMaster    uint32
+	PacketInMaskSlave          uint32
+	PortStatusMaskEqualMaster  uint32
+	PortStatusMaskSlave        uint32
+	FlowRemovedMaskEqualMaster uint32
+	FlowRemovedMaskSlave       uint32
+}
+
+type IAsyncGetReply interface {
+	IHeader
+	GetPacketInMaskEqualMaster() uint32
+	GetPacketInMaskSlave() uint32
+	GetPortStatusMaskEqualMaster() uint32
+	GetPortStatusMaskSlave() uint32
+	GetFlowRemovedMaskEqualMaster() uint32
+	GetFlowRemovedMaskSlave() uint32
+}
+
+func (self *AsyncGetReply) GetPacketInMaskEqualMaster() uint32 {
+	return self.PacketInMaskEqualMaster
+}
+
+func (self *AsyncGetReply) SetPacketInMaskEqualMaster(v uint32) {
+	self.PacketInMaskEqualMaster = v
+}
+
+func (self *AsyncGetReply) GetPacketInMaskSlave() uint32 {
+	return self.PacketInMaskSlave
+}
+
+func (self *AsyncGetReply) SetPacketInMaskSlave(v uint32) {
+	self.PacketInMaskSlave = v
+}
+
+func (self *AsyncGetReply) GetPortStatusMaskEqualMaster() uint32 {
+	return self.PortStatusMaskEqualMaster
+}
+
+func (self *AsyncGetReply) SetPortStatusMaskEqualMaster(v uint32) {
+	self.PortStatusMaskEqualMaster = v
+}
+
+func (self *AsyncGetReply) GetPortStatusMaskSlave() uint32 {
+	return self.PortStatusMaskSlave
+}
+
+func (self *AsyncGetReply) SetPortStatusMaskSlave(v uint32) {
+	self.PortStatusMaskSlave = v
+}
+
+func (self *AsyncGetReply) GetFlowRemovedMaskEqualMaster() uint32 {
+	return self.FlowRemovedMaskEqualMaster
+}
+
+func (self *AsyncGetReply) SetFlowRemovedMaskEqualMaster(v uint32) {
+	self.FlowRemovedMaskEqualMaster = v
+}
+
+func (self *AsyncGetReply) GetFlowRemovedMaskSlave() uint32 {
+	return self.FlowRemovedMaskSlave
+}
+
+func (self *AsyncGetReply) SetFlowRemovedMaskSlave(v uint32) {
+	self.FlowRemovedMaskSlave = v
+}
+
+func (self *AsyncGetReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.PacketInMaskEqualMaster))
+	encoder.PutUint32(uint32(self.PacketInMaskSlave))
+	encoder.PutUint32(uint32(self.PortStatusMaskEqualMaster))
+	encoder.PutUint32(uint32(self.PortStatusMaskSlave))
+	encoder.PutUint32(uint32(self.FlowRemovedMaskEqualMaster))
+	encoder.PutUint32(uint32(self.FlowRemovedMaskSlave))
+	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}
+	if decoder.Length() < 24 {
+		return nil, fmt.Errorf("AsyncGetReply packet too short: %d < 24", decoder.Length())
+	}
+	_asyncgetreply.PacketInMaskEqualMaster = uint32(decoder.ReadUint32())
+	_asyncgetreply.PacketInMaskSlave = uint32(decoder.ReadUint32())
+	_asyncgetreply.PortStatusMaskEqualMaster = uint32(decoder.ReadUint32())
+	_asyncgetreply.PortStatusMaskSlave = uint32(decoder.ReadUint32())
+	_asyncgetreply.FlowRemovedMaskEqualMaster = uint32(decoder.ReadUint32())
+	_asyncgetreply.FlowRemovedMaskSlave = uint32(decoder.ReadUint32())
+	return _asyncgetreply, nil
+}
+
+func NewAsyncGetReply() *AsyncGetReply {
+	obj := &AsyncGetReply{
+		Header: NewHeader(27),
+	}
+	return obj
+}
+
+type AsyncGetRequest struct {
+	*Header
+}
+
+type IAsyncGetRequest interface {
+	IHeader
+}
+
+func (self *AsyncGetRequest) 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 DecodeAsyncGetRequest(parent *Header, decoder *goloxi.Decoder) (*AsyncGetRequest, error) {
+	_asyncgetrequest := &AsyncGetRequest{Header: parent}
+	return _asyncgetrequest, nil
+}
+
+func NewAsyncGetRequest() *AsyncGetRequest {
+	obj := &AsyncGetRequest{
+		Header: NewHeader(26),
+	}
+	return obj
+}
+
+type AsyncSet struct {
+	*Header
+	PacketInMaskEqualMaster    uint32
+	PacketInMaskSlave          uint32
+	PortStatusMaskEqualMaster  uint32
+	PortStatusMaskSlave        uint32
+	FlowRemovedMaskEqualMaster uint32
+	FlowRemovedMaskSlave       uint32
+}
+
+type IAsyncSet interface {
+	IHeader
+	GetPacketInMaskEqualMaster() uint32
+	GetPacketInMaskSlave() uint32
+	GetPortStatusMaskEqualMaster() uint32
+	GetPortStatusMaskSlave() uint32
+	GetFlowRemovedMaskEqualMaster() uint32
+	GetFlowRemovedMaskSlave() uint32
+}
+
+func (self *AsyncSet) GetPacketInMaskEqualMaster() uint32 {
+	return self.PacketInMaskEqualMaster
+}
+
+func (self *AsyncSet) SetPacketInMaskEqualMaster(v uint32) {
+	self.PacketInMaskEqualMaster = v
+}
+
+func (self *AsyncSet) GetPacketInMaskSlave() uint32 {
+	return self.PacketInMaskSlave
+}
+
+func (self *AsyncSet) SetPacketInMaskSlave(v uint32) {
+	self.PacketInMaskSlave = v
+}
+
+func (self *AsyncSet) GetPortStatusMaskEqualMaster() uint32 {
+	return self.PortStatusMaskEqualMaster
+}
+
+func (self *AsyncSet) SetPortStatusMaskEqualMaster(v uint32) {
+	self.PortStatusMaskEqualMaster = v
+}
+
+func (self *AsyncSet) GetPortStatusMaskSlave() uint32 {
+	return self.PortStatusMaskSlave
+}
+
+func (self *AsyncSet) SetPortStatusMaskSlave(v uint32) {
+	self.PortStatusMaskSlave = v
+}
+
+func (self *AsyncSet) GetFlowRemovedMaskEqualMaster() uint32 {
+	return self.FlowRemovedMaskEqualMaster
+}
+
+func (self *AsyncSet) SetFlowRemovedMaskEqualMaster(v uint32) {
+	self.FlowRemovedMaskEqualMaster = v
+}
+
+func (self *AsyncSet) GetFlowRemovedMaskSlave() uint32 {
+	return self.FlowRemovedMaskSlave
+}
+
+func (self *AsyncSet) SetFlowRemovedMaskSlave(v uint32) {
+	self.FlowRemovedMaskSlave = v
+}
+
+func (self *AsyncSet) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.PacketInMaskEqualMaster))
+	encoder.PutUint32(uint32(self.PacketInMaskSlave))
+	encoder.PutUint32(uint32(self.PortStatusMaskEqualMaster))
+	encoder.PutUint32(uint32(self.PortStatusMaskSlave))
+	encoder.PutUint32(uint32(self.FlowRemovedMaskEqualMaster))
+	encoder.PutUint32(uint32(self.FlowRemovedMaskSlave))
+	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}
+	if decoder.Length() < 24 {
+		return nil, fmt.Errorf("AsyncSet packet too short: %d < 24", decoder.Length())
+	}
+	_asyncset.PacketInMaskEqualMaster = uint32(decoder.ReadUint32())
+	_asyncset.PacketInMaskSlave = uint32(decoder.ReadUint32())
+	_asyncset.PortStatusMaskEqualMaster = uint32(decoder.ReadUint32())
+	_asyncset.PortStatusMaskSlave = uint32(decoder.ReadUint32())
+	_asyncset.FlowRemovedMaskEqualMaster = uint32(decoder.ReadUint32())
+	_asyncset.FlowRemovedMaskSlave = uint32(decoder.ReadUint32())
+	return _asyncset, nil
+}
+
+func NewAsyncSet() *AsyncSet {
+	obj := &AsyncSet{
+		Header: NewHeader(28),
+	}
+	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 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 BadActionErrorMsg struct {
+	*ErrorMsg
+	Code BadActionCode
+	Data []byte
+}
+
+type IBadActionErrorMsg interface {
+	IErrorMsg
+	GetCode() BadActionCode
+	GetData() []byte
+}
+
+func (self *BadActionErrorMsg) GetCode() BadActionCode {
+	return self.Code
+}
+
+func (self *BadActionErrorMsg) SetCode(v BadActionCode) {
+	self.Code = v
+}
+
+func (self *BadActionErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadActionErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadActionErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBadActionErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadActionErrorMsg, error) {
+	_badactionerrormsg := &BadActionErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadActionErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badactionerrormsg.Code = BadActionCode(decoder.ReadUint16())
+	_badactionerrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badactionerrormsg, nil
+}
+
+func NewBadActionErrorMsg() *BadActionErrorMsg {
+	obj := &BadActionErrorMsg{
+		ErrorMsg: NewErrorMsg(2),
+	}
+	return obj
+}
+
+type BadInstructionErrorMsg struct {
+	*ErrorMsg
+	Code BadInstructionCode
+	Data []byte
+}
+
+type IBadInstructionErrorMsg interface {
+	IErrorMsg
+	GetCode() BadInstructionCode
+	GetData() []byte
+}
+
+func (self *BadInstructionErrorMsg) GetCode() BadInstructionCode {
+	return self.Code
+}
+
+func (self *BadInstructionErrorMsg) SetCode(v BadInstructionCode) {
+	self.Code = v
+}
+
+func (self *BadInstructionErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadInstructionErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadInstructionErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBadInstructionErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadInstructionErrorMsg, error) {
+	_badinstructionerrormsg := &BadInstructionErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadInstructionErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badinstructionerrormsg.Code = BadInstructionCode(decoder.ReadUint16())
+	_badinstructionerrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badinstructionerrormsg, nil
+}
+
+func NewBadInstructionErrorMsg() *BadInstructionErrorMsg {
+	obj := &BadInstructionErrorMsg{
+		ErrorMsg: NewErrorMsg(3),
+	}
+	return obj
+}
+
+type BadMatchErrorMsg struct {
+	*ErrorMsg
+	Code BadMatchCode
+	Data []byte
+}
+
+type IBadMatchErrorMsg interface {
+	IErrorMsg
+	GetCode() BadMatchCode
+	GetData() []byte
+}
+
+func (self *BadMatchErrorMsg) GetCode() BadMatchCode {
+	return self.Code
+}
+
+func (self *BadMatchErrorMsg) SetCode(v BadMatchCode) {
+	self.Code = v
+}
+
+func (self *BadMatchErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadMatchErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadMatchErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBadMatchErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadMatchErrorMsg, error) {
+	_badmatcherrormsg := &BadMatchErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadMatchErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badmatcherrormsg.Code = BadMatchCode(decoder.ReadUint16())
+	_badmatcherrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badmatcherrormsg, nil
+}
+
+func NewBadMatchErrorMsg() *BadMatchErrorMsg {
+	obj := &BadMatchErrorMsg{
+		ErrorMsg: NewErrorMsg(4),
+	}
+	return obj
+}
+
+type BadRequestErrorMsg struct {
+	*ErrorMsg
+	Code BadRequestCode
+	Data []byte
+}
+
+type IBadRequestErrorMsg interface {
+	IErrorMsg
+	GetCode() BadRequestCode
+	GetData() []byte
+}
+
+func (self *BadRequestErrorMsg) GetCode() BadRequestCode {
+	return self.Code
+}
+
+func (self *BadRequestErrorMsg) SetCode(v BadRequestCode) {
+	self.Code = v
+}
+
+func (self *BadRequestErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *BadRequestErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BadRequestErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBadRequestErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*BadRequestErrorMsg, error) {
+	_badrequesterrormsg := &BadRequestErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("BadRequestErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_badrequesterrormsg.Code = BadRequestCode(decoder.ReadUint16())
+	_badrequesterrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _badrequesterrormsg, nil
+}
+
+func NewBadRequestErrorMsg() *BadRequestErrorMsg {
+	obj := &BadRequestErrorMsg{
+		ErrorMsg: NewErrorMsg(1),
+	}
+	return obj
+}
+
+type BarrierReply struct {
+	*Header
+}
+
+type IBarrierReply interface {
+	IHeader
+}
+
+func (self *BarrierReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBarrierReply(parent *Header, decoder *goloxi.Decoder) (*BarrierReply, error) {
+	_barrierreply := &BarrierReply{Header: parent}
+	return _barrierreply, nil
+}
+
+func NewBarrierReply() *BarrierReply {
+	obj := &BarrierReply{
+		Header: NewHeader(21),
+	}
+	return obj
+}
+
+type BarrierRequest struct {
+	*Header
+}
+
+type IBarrierRequest interface {
+	IHeader
+}
+
+func (self *BarrierRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBarrierRequest(parent *Header, decoder *goloxi.Decoder) (*BarrierRequest, error) {
+	_barrierrequest := &BarrierRequest{Header: parent}
+	return _barrierrequest, nil
+}
+
+func NewBarrierRequest() *BarrierRequest {
+	obj := &BarrierRequest{
+		Header: NewHeader(20),
+	}
+	return obj
+}
+
+type Experimenter struct {
+	*Header
+	Experimenter uint32
+	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 55:
+		return DecodeBsnRoleStatus(_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 70:
+		return DecodeBsnVlanCounterClear(_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 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 BsnRoleStatus struct {
+	*BsnHeader
+	Role         ControllerRole
+	Reason       BsnControllerRoleReason
+	GenerationId uint64
+}
+
+type IBsnRoleStatus interface {
+	IBsnHeader
+	GetRole() ControllerRole
+	GetReason() BsnControllerRoleReason
+	GetGenerationId() uint64
+}
+
+func (self *BsnRoleStatus) GetRole() ControllerRole {
+	return self.Role
+}
+
+func (self *BsnRoleStatus) SetRole(v ControllerRole) {
+	self.Role = v
+}
+
+func (self *BsnRoleStatus) GetReason() BsnControllerRoleReason {
+	return self.Reason
+}
+
+func (self *BsnRoleStatus) SetReason(v BsnControllerRoleReason) {
+	self.Reason = v
+}
+
+func (self *BsnRoleStatus) GetGenerationId() uint64 {
+	return self.GenerationId
+}
+
+func (self *BsnRoleStatus) SetGenerationId(v uint64) {
+	self.GenerationId = v
+}
+
+func (self *BsnRoleStatus) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.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))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnRoleStatus(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnRoleStatus, error) {
+	_bsnrolestatus := &BsnRoleStatus{BsnHeader: parent}
+	if decoder.Length() < 16 {
+		return nil, fmt.Errorf("BsnRoleStatus packet too short: %d < 16", decoder.Length())
+	}
+	_bsnrolestatus.Role = ControllerRole(decoder.ReadUint32())
+	_bsnrolestatus.Reason = BsnControllerRoleReason(decoder.ReadByte())
+	decoder.Skip(3)
+	_bsnrolestatus.GenerationId = uint64(decoder.ReadUint64())
+	return _bsnrolestatus, nil
+}
+
+func NewBsnRoleStatus() *BsnRoleStatus {
+	obj := &BsnRoleStatus{
+		BsnHeader: NewBsnHeader(55),
+	}
+	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 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 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
+}
+
+type IFlowAdd interface {
+	IFlowMod
+}
+
+func (self *FlowAdd) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowAdd(parent *FlowMod, decoder *goloxi.Decoder) (*FlowAdd, error) {
+	_flowadd := &FlowAdd{FlowMod: parent}
+	return _flowadd, nil
+}
+
+func NewFlowAdd() *FlowAdd {
+	obj := &FlowAdd{
+		FlowMod: NewFlowMod(0),
+	}
+	return obj
+}
+
+type FlowDelete struct {
+	*FlowMod
+}
+
+type IFlowDelete interface {
+	IFlowMod
+}
+
+func (self *FlowDelete) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowDelete(parent *FlowMod, decoder *goloxi.Decoder) (*FlowDelete, error) {
+	_flowdelete := &FlowDelete{FlowMod: parent}
+	return _flowdelete, nil
+}
+
+func NewFlowDelete() *FlowDelete {
+	obj := &FlowDelete{
+		FlowMod: NewFlowMod(3),
+	}
+	return obj
+}
+
+type FlowDeleteStrict struct {
+	*FlowMod
+}
+
+type IFlowDeleteStrict interface {
+	IFlowMod
+}
+
+func (self *FlowDeleteStrict) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowDeleteStrict(parent *FlowMod, decoder *goloxi.Decoder) (*FlowDeleteStrict, error) {
+	_flowdeletestrict := &FlowDeleteStrict{FlowMod: parent}
+	return _flowdeletestrict, nil
+}
+
+func NewFlowDeleteStrict() *FlowDeleteStrict {
+	obj := &FlowDeleteStrict{
+		FlowMod: NewFlowMod(4),
+	}
+	return obj
+}
+
+type FlowModFailedErrorMsg struct {
+	*ErrorMsg
+	Code FlowModFailedCode
+	Data []byte
+}
+
+type IFlowModFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() FlowModFailedCode
+	GetData() []byte
+}
+
+func (self *FlowModFailedErrorMsg) GetCode() FlowModFailedCode {
+	return self.Code
+}
+
+func (self *FlowModFailedErrorMsg) SetCode(v FlowModFailedCode) {
+	self.Code = v
+}
+
+func (self *FlowModFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *FlowModFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *FlowModFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowModFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*FlowModFailedErrorMsg, error) {
+	_flowmodfailederrormsg := &FlowModFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("FlowModFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_flowmodfailederrormsg.Code = FlowModFailedCode(decoder.ReadUint16())
+	_flowmodfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _flowmodfailederrormsg, nil
+}
+
+func NewFlowModFailedErrorMsg() *FlowModFailedErrorMsg {
+	obj := &FlowModFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(5),
+	}
+	return obj
+}
+
+type FlowModify struct {
+	*FlowMod
+}
+
+type IFlowModify interface {
+	IFlowMod
+}
+
+func (self *FlowModify) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowModify(parent *FlowMod, decoder *goloxi.Decoder) (*FlowModify, error) {
+	_flowmodify := &FlowModify{FlowMod: parent}
+	return _flowmodify, nil
+}
+
+func NewFlowModify() *FlowModify {
+	obj := &FlowModify{
+		FlowMod: NewFlowMod(1),
+	}
+	return obj
+}
+
+type FlowModifyStrict struct {
+	*FlowMod
+}
+
+type IFlowModifyStrict interface {
+	IFlowMod
+}
+
+func (self *FlowModifyStrict) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.FlowMod.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFlowModifyStrict(parent *FlowMod, decoder *goloxi.Decoder) (*FlowModifyStrict, error) {
+	_flowmodifystrict := &FlowModifyStrict{FlowMod: parent}
+	return _flowmodifystrict, nil
+}
+
+func NewFlowModifyStrict() *FlowModifyStrict {
+	obj := &FlowModifyStrict{
+		FlowMod: NewFlowMod(2),
+	}
+	return obj
+}
+
+type FlowRemoved struct {
+	*Header
+	Cookie       uint64
+	Priority     uint16
+	Reason       FlowRemovedReason
+	TableId      uint8
+	DurationSec  uint32
+	DurationNsec uint32
+	IdleTimeout  uint16
+	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
+	Meters  []IMeterBand
+}
+
+type IMeterMod interface {
+	IHeader
+	GetCommand() MeterModCommand
+	GetFlags() MeterFlags
+	GetMeterId() uint32
+	GetMeters() []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) GetMeters() []IMeterBand {
+	return self.Meters
+}
+
+func (self *MeterMod) SetMeters(v []IMeterBand) {
+	self.Meters = 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.Meters {
+		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.Meters = append(_metermod.Meters, 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() >= 64 {
+		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
+	Advertise uint32
+}
+
+type IPortMod interface {
+	IHeader
+	GetPortNo() Port
+	GetHwAddr() net.HardwareAddr
+	GetConfig() PortConfig
+	GetMask() PortConfig
+	GetAdvertise() uint32
+}
+
+func (self *PortMod) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *PortMod) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *PortMod) GetHwAddr() net.HardwareAddr {
+	return self.HwAddr
+}
+
+func (self *PortMod) SetHwAddr(v net.HardwareAddr) {
+	self.HwAddr = v
+}
+
+func (self *PortMod) GetConfig() PortConfig {
+	return self.Config
+}
+
+func (self *PortMod) SetConfig(v PortConfig) {
+	self.Config = v
+}
+
+func (self *PortMod) GetMask() PortConfig {
+	return self.Mask
+}
+
+func (self *PortMod) SetMask(v PortConfig) {
+	self.Mask = v
+}
+
+func (self *PortMod) GetAdvertise() uint32 {
+	return self.Advertise
+}
+
+func (self *PortMod) SetAdvertise(v uint32) {
+	self.Advertise = v
+}
+
+func (self *PortMod) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.PortNo.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.Write(self.HwAddr)
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint32(uint32(self.Config))
+	encoder.PutUint32(uint32(self.Mask))
+	encoder.PutUint32(uint32(self.Advertise))
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortMod(parent *Header, decoder *goloxi.Decoder) (*PortMod, error) {
+	_portmod := &PortMod{Header: parent}
+	if decoder.Length() < 32 {
+		return nil, fmt.Errorf("PortMod packet too short: %d < 32", decoder.Length())
+	}
+	_portmod.PortNo.Decode(decoder)
+	decoder.Skip(4)
+	_portmod.HwAddr = net.HardwareAddr(decoder.Read(6))
+	decoder.Skip(2)
+	_portmod.Config = PortConfig(decoder.ReadUint32())
+	_portmod.Mask = PortConfig(decoder.ReadUint32())
+	_portmod.Advertise = uint32(decoder.ReadUint32())
+	decoder.Skip(4)
+	return _portmod, nil
+}
+
+func NewPortMod() *PortMod {
+	obj := &PortMod{
+		Header: NewHeader(16),
+	}
+	return obj
+}
+
+type PortModFailedErrorMsg struct {
+	*ErrorMsg
+	Code PortModFailedCode
+	Data []byte
+}
+
+type IPortModFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() PortModFailedCode
+	GetData() []byte
+}
+
+func (self *PortModFailedErrorMsg) GetCode() PortModFailedCode {
+	return self.Code
+}
+
+func (self *PortModFailedErrorMsg) SetCode(v PortModFailedCode) {
+	self.Code = v
+}
+
+func (self *PortModFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *PortModFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *PortModFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortModFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*PortModFailedErrorMsg, error) {
+	_portmodfailederrormsg := &PortModFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("PortModFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_portmodfailederrormsg.Code = PortModFailedCode(decoder.ReadUint16())
+	_portmodfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _portmodfailederrormsg, nil
+}
+
+func NewPortModFailedErrorMsg() *PortModFailedErrorMsg {
+	obj := &PortModFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(7),
+	}
+	return obj
+}
+
+type PortStatsReply struct {
+	*StatsReply
+	Entries []*PortStatsEntry
+}
+
+type IPortStatsReply interface {
+	IStatsReply
+	GetEntries() []*PortStatsEntry
+}
+
+func (self *PortStatsReply) GetEntries() []*PortStatsEntry {
+	return self.Entries
+}
+
+func (self *PortStatsReply) SetEntries(v []*PortStatsEntry) {
+	self.Entries = v
+}
+
+func (self *PortStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*PortStatsReply, error) {
+	_portstatsreply := &PortStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("PortStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 112 {
+		item, err := DecodePortStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_portstatsreply.Entries = append(_portstatsreply.Entries, item)
+		}
+	}
+	return _portstatsreply, nil
+}
+
+func NewPortStatsReply() *PortStatsReply {
+	obj := &PortStatsReply{
+		StatsReply: NewStatsReply(4),
+	}
+	return obj
+}
+
+type PortStatsRequest struct {
+	*StatsRequest
+	PortNo Port
+}
+
+type IPortStatsRequest interface {
+	IStatsRequest
+	GetPortNo() Port
+}
+
+func (self *PortStatsRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *PortStatsRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *PortStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	self.PortNo.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (*PortStatsRequest, error) {
+	_portstatsrequest := &PortStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("PortStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	_portstatsrequest.PortNo.Decode(decoder)
+	decoder.Skip(4)
+	return _portstatsrequest, nil
+}
+
+func NewPortStatsRequest() *PortStatsRequest {
+	obj := &PortStatsRequest{
+		StatsRequest: NewStatsRequest(4),
+	}
+	return obj
+}
+
+type PortStatus struct {
+	*Header
+	Reason PortReason
+	Desc   PortDesc
+}
+
+type IPortStatus interface {
+	IHeader
+	GetReason() PortReason
+	GetDesc() PortDesc
+}
+
+func (self *PortStatus) GetReason() PortReason {
+	return self.Reason
+}
+
+func (self *PortStatus) SetReason(v PortReason) {
+	self.Reason = v
+}
+
+func (self *PortStatus) GetDesc() PortDesc {
+	return self.Desc
+}
+
+func (self *PortStatus) SetDesc(v PortDesc) {
+	self.Desc = v
+}
+
+func (self *PortStatus) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.Write(bytes.Repeat([]byte{0}, 7))
+	if err := self.Desc.Serialize(encoder); err != nil {
+		return err
+	}
+
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodePortStatus(parent *Header, decoder *goloxi.Decoder) (*PortStatus, error) {
+	_portstatus := &PortStatus{Header: parent}
+	if decoder.Length() < 72 {
+		return nil, fmt.Errorf("PortStatus packet too short: %d < 72", decoder.Length())
+	}
+	_portstatus.Reason = PortReason(decoder.ReadByte())
+	decoder.Skip(7)
+	if err := _portstatus.Desc.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _portstatus, nil
+}
+
+func NewPortStatus() *PortStatus {
+	obj := &PortStatus{
+		Header: NewHeader(12),
+	}
+	return obj
+}
+
+type QueueGetConfigReply struct {
+	*Header
+	Port   Port
+	Queues []*PacketQueue
+}
+
+type IQueueGetConfigReply interface {
+	IHeader
+	GetPort() Port
+	GetQueues() []*PacketQueue
+}
+
+func (self *QueueGetConfigReply) GetPort() Port {
+	return self.Port
+}
+
+func (self *QueueGetConfigReply) SetPort(v Port) {
+	self.Port = v
+}
+
+func (self *QueueGetConfigReply) GetQueues() []*PacketQueue {
+	return self.Queues
+}
+
+func (self *QueueGetConfigReply) SetQueues(v []*PacketQueue) {
+	self.Queues = v
+}
+
+func (self *QueueGetConfigReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.Port.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Queues {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueGetConfigReply(parent *Header, decoder *goloxi.Decoder) (*QueueGetConfigReply, error) {
+	_queuegetconfigreply := &QueueGetConfigReply{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("QueueGetConfigReply packet too short: %d < 8", decoder.Length())
+	}
+	_queuegetconfigreply.Port.Decode(decoder)
+	decoder.Skip(4)
+
+	for decoder.Length() >= 16 {
+		item, err := DecodePacketQueue(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_queuegetconfigreply.Queues = append(_queuegetconfigreply.Queues, item)
+		}
+	}
+	return _queuegetconfigreply, nil
+}
+
+func NewQueueGetConfigReply() *QueueGetConfigReply {
+	obj := &QueueGetConfigReply{
+		Header: NewHeader(23),
+	}
+	return obj
+}
+
+type QueueGetConfigRequest struct {
+	*Header
+	Port Port
+}
+
+type IQueueGetConfigRequest interface {
+	IHeader
+	GetPort() Port
+}
+
+func (self *QueueGetConfigRequest) GetPort() Port {
+	return self.Port
+}
+
+func (self *QueueGetConfigRequest) SetPort(v Port) {
+	self.Port = v
+}
+
+func (self *QueueGetConfigRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.Port.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueGetConfigRequest(parent *Header, decoder *goloxi.Decoder) (*QueueGetConfigRequest, error) {
+	_queuegetconfigrequest := &QueueGetConfigRequest{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("QueueGetConfigRequest packet too short: %d < 8", decoder.Length())
+	}
+	_queuegetconfigrequest.Port.Decode(decoder)
+	decoder.Skip(4)
+	return _queuegetconfigrequest, nil
+}
+
+func NewQueueGetConfigRequest() *QueueGetConfigRequest {
+	obj := &QueueGetConfigRequest{
+		Header: NewHeader(22),
+	}
+	return obj
+}
+
+type QueueOpFailedErrorMsg struct {
+	*ErrorMsg
+	Code QueueOpFailedCode
+	Data []byte
+}
+
+type IQueueOpFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() QueueOpFailedCode
+	GetData() []byte
+}
+
+func (self *QueueOpFailedErrorMsg) GetCode() QueueOpFailedCode {
+	return self.Code
+}
+
+func (self *QueueOpFailedErrorMsg) SetCode(v QueueOpFailedCode) {
+	self.Code = v
+}
+
+func (self *QueueOpFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *QueueOpFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *QueueOpFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueOpFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*QueueOpFailedErrorMsg, error) {
+	_queueopfailederrormsg := &QueueOpFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("QueueOpFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_queueopfailederrormsg.Code = QueueOpFailedCode(decoder.ReadUint16())
+	_queueopfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _queueopfailederrormsg, nil
+}
+
+func NewQueueOpFailedErrorMsg() *QueueOpFailedErrorMsg {
+	obj := &QueueOpFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(9),
+	}
+	return obj
+}
+
+type QueueStatsReply struct {
+	*StatsReply
+	Entries []*QueueStatsEntry
+}
+
+type IQueueStatsReply interface {
+	IStatsReply
+	GetEntries() []*QueueStatsEntry
+}
+
+func (self *QueueStatsReply) GetEntries() []*QueueStatsEntry {
+	return self.Entries
+}
+
+func (self *QueueStatsReply) SetEntries(v []*QueueStatsEntry) {
+	self.Entries = v
+}
+
+func (self *QueueStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeQueueStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*QueueStatsReply, error) {
+	_queuestatsreply := &QueueStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("QueueStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 40 {
+		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 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 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 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
+}
+
+type ITableMod interface {
+	IHeader
+	GetTableId() uint8
+	GetConfig() uint32
+}
+
+func (self *TableMod) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *TableMod) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *TableMod) GetConfig() uint32 {
+	return self.Config
+}
+
+func (self *TableMod) SetConfig(v uint32) {
+	self.Config = v
+}
+
+func (self *TableMod) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.PutUint32(uint32(self.Config))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeTableMod(parent *Header, decoder *goloxi.Decoder) (*TableMod, error) {
+	_tablemod := &TableMod{Header: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("TableMod packet too short: %d < 8", decoder.Length())
+	}
+	_tablemod.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_tablemod.Config = uint32(decoder.ReadUint32())
+	return _tablemod, nil
+}
+
+func NewTableMod() *TableMod {
+	obj := &TableMod{
+		Header: NewHeader(17),
+	}
+	return obj
+}
+
+type TableModFailedErrorMsg struct {
+	*ErrorMsg
+	Code TableModFailedCode
+	Data []byte
+}
+
+type ITableModFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() TableModFailedCode
+	GetData() []byte
+}
+
+func (self *TableModFailedErrorMsg) GetCode() TableModFailedCode {
+	return self.Code
+}
+
+func (self *TableModFailedErrorMsg) SetCode(v TableModFailedCode) {
+	self.Code = v
+}
+
+func (self *TableModFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *TableModFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *TableModFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeTableModFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*TableModFailedErrorMsg, error) {
+	_tablemodfailederrormsg := &TableModFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("TableModFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_tablemodfailederrormsg.Code = TableModFailedCode(decoder.ReadUint16())
+	_tablemodfailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _tablemodfailederrormsg, nil
+}
+
+func NewTableModFailedErrorMsg() *TableModFailedErrorMsg {
+	obj := &TableModFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(8),
+	}
+	return obj
+}
+
+type TableStatsReply struct {
+	*StatsReply
+	Entries []*TableStatsEntry
+}
+
+type ITableStatsReply interface {
+	IStatsReply
+	GetEntries() []*TableStatsEntry
+}
+
+func (self *TableStatsReply) GetEntries() []*TableStatsEntry {
+	return self.Entries
+}
+
+func (self *TableStatsReply) SetEntries(v []*TableStatsEntry) {
+	self.Entries = v
+}
+
+func (self *TableStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Entries {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeTableStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (*TableStatsReply, error) {
+	_tablestatsreply := &TableStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("TableStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 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
+}
