diff --git a/of10/message.go b/of10/message.go
new file mode 100644
index 0000000..422a722
--- /dev/null
+++ b/of10/message.go
@@ -0,0 +1,5834 @@
+/*
+ * 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 of10
+
+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(1))
+	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 DecodePortMod(_header, decoder)
+	case 16:
+		return DecodeStatsRequest(_header, decoder)
+	case 17:
+		return DecodeStatsReply(_header, decoder)
+	case 18:
+		return DecodeBarrierRequest(_header, decoder)
+	case 19:
+		return DecodeBarrierReply(_header, decoder)
+	case 20:
+		return DecodeQueueGetConfigRequest(_header, decoder)
+	case 21:
+		return DecodeQueueGetConfigReply(_header, decoder)
+	case 22:
+		return DecodeTableMod(_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 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(17),
+	}
+	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.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() < 24 {
+		return nil, fmt.Errorf("AggregateStatsReply packet too short: %d < 24", decoder.Length())
+	}
+	_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 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(16),
+	}
+	obj.StatsType = _stats_type
+	return obj
+}
+
+type AggregateStatsRequest struct {
+	*StatsRequest
+	Match   Match
+	TableId uint8
+	OutPort Port
+}
+
+type IAggregateStatsRequest interface {
+	IStatsRequest
+	GetMatch() Match
+	GetTableId() uint8
+	GetOutPort() Port
+}
+
+func (self *AggregateStatsRequest) GetMatch() Match {
+	return self.Match
+}
+
+func (self *AggregateStatsRequest) SetMatch(v Match) {
+	self.Match = v
+}
+
+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) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	self.OutPort.Serialize(encoder)
+	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() < 44 {
+		return nil, fmt.Errorf("AggregateStatsRequest packet too short: %d < 44", decoder.Length())
+	}
+	if err := _aggregatestatsrequest.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	_aggregatestatsrequest.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_aggregatestatsrequest.OutPort.Decode(decoder)
+	return _aggregatestatsrequest, nil
+}
+
+func NewAggregateStatsRequest() *AggregateStatsRequest {
+	obj := &AggregateStatsRequest{
+		StatsRequest: NewStatsRequest(2),
+	}
+	return obj
+}
+
+type ErrorMsg struct {
+	*Header
+	ErrType uint16
+}
+
+type IErrorMsg interface {
+	IHeader
+	GetErrType() uint16
+}
+
+func (self *ErrorMsg) GetErrType() uint16 {
+	return self.ErrType
+}
+
+func (self *ErrorMsg) SetErrType(v uint16) {
+	self.ErrType = v
+}
+
+func (self *ErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.ErrType))
+
+	return nil
+}
+
+func DecodeErrorMsg(parent *Header, decoder *goloxi.Decoder) (IErrorMsg, error) {
+	_errormsg := &ErrorMsg{Header: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("ErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_errormsg.ErrType = uint16(decoder.ReadUint16())
+
+	switch _errormsg.ErrType {
+	case 0:
+		return DecodeHelloFailedErrorMsg(_errormsg, decoder)
+	case 1:
+		return DecodeBadRequestErrorMsg(_errormsg, decoder)
+	case 2:
+		return DecodeBadActionErrorMsg(_errormsg, decoder)
+	case 3:
+		return DecodeFlowModFailedErrorMsg(_errormsg, decoder)
+	case 4:
+		return DecodePortModFailedErrorMsg(_errormsg, decoder)
+	case 5:
+		return DecodeQueueOpFailedErrorMsg(_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 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(19),
+	}
+	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(18),
+	}
+	return obj
+}
+
+type Experimenter struct {
+	*Header
+	Experimenter uint32
+}
+
+type IExperimenter interface {
+	IHeader
+	GetExperimenter() uint32
+}
+
+func (self *Experimenter) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *Experimenter) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *Experimenter) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Experimenter))
+
+	return nil
+}
+
+func DecodeExperimenter(parent *Header, decoder *goloxi.Decoder) (IExperimenter, error) {
+	_experimenter := &Experimenter{Header: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("Experimenter packet too short: %d < 4", decoder.Length())
+	}
+	_experimenter.Experimenter = uint32(decoder.ReadUint32())
+
+	switch _experimenter.Experimenter {
+	case 8992:
+		return DecodeNiciraHeader(_experimenter, decoder)
+	case 6035143:
+		return DecodeBsnHeader(_experimenter, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'Experimenter'", _experimenter.Experimenter)
+	}
+}
+
+func NewExperimenter(_experimenter uint32) *Experimenter {
+	obj := &Experimenter{
+		Header: NewHeader(4),
+	}
+	obj.Experimenter = _experimenter
+	return obj
+}
+
+type BsnHeader struct {
+	*Experimenter
+	Subtype uint32
+}
+
+type IBsnHeader interface {
+	IExperimenter
+	GetSubtype() uint32
+}
+
+func (self *BsnHeader) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *BsnHeader) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *BsnHeader) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Experimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeBsnHeader(parent *Experimenter, decoder *goloxi.Decoder) (IBsnHeader, error) {
+	_bsnheader := &BsnHeader{Experimenter: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnHeader packet too short: %d < 4", decoder.Length())
+	}
+	_bsnheader.Subtype = uint32(decoder.ReadUint32())
+
+	switch _bsnheader.Subtype {
+	case 0:
+		return DecodeBsnSetIpMask(_bsnheader, decoder)
+	case 1:
+		return DecodeBsnGetIpMaskRequest(_bsnheader, decoder)
+	case 2:
+		return DecodeBsnGetIpMaskReply(_bsnheader, decoder)
+	case 3:
+		return DecodeBsnSetMirroring(_bsnheader, decoder)
+	case 4:
+		return DecodeBsnGetMirroringRequest(_bsnheader, decoder)
+	case 5:
+		return DecodeBsnGetMirroringReply(_bsnheader, decoder)
+	case 6:
+		return DecodeBsnShellCommand(_bsnheader, decoder)
+	case 7:
+		return DecodeBsnShellOutput(_bsnheader, decoder)
+	case 8:
+		return DecodeBsnShellStatus(_bsnheader, decoder)
+	case 9:
+		return DecodeBsnGetInterfacesRequest(_bsnheader, decoder)
+	case 10:
+		return DecodeBsnGetInterfacesReply(_bsnheader, decoder)
+	case 11:
+		return DecodeBsnSetPktinSuppressionRequest(_bsnheader, decoder)
+	case 12:
+		return DecodeBsnSetL2TableRequest(_bsnheader, decoder)
+	case 13:
+		return DecodeBsnGetL2TableRequest(_bsnheader, decoder)
+	case 14:
+		return DecodeBsnGetL2TableReply(_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 24:
+		return DecodeBsnSetL2TableReply(_bsnheader, decoder)
+	case 25:
+		return DecodeBsnSetPktinSuppressionReply(_bsnheader, decoder)
+	case 26:
+		return DecodeBsnVirtualPortRemoveReply(_bsnheader, decoder)
+	case 27:
+		return DecodeBsnHybridGetRequest(_bsnheader, decoder)
+	case 28:
+		return DecodeBsnHybridGetReply(_bsnheader, decoder)
+	case 31:
+		return DecodeBsnPduTxRequest(_bsnheader, decoder)
+	case 32:
+		return DecodeBsnPduTxReply(_bsnheader, decoder)
+	case 33:
+		return DecodeBsnPduRxRequest(_bsnheader, decoder)
+	case 34:
+		return DecodeBsnPduRxReply(_bsnheader, decoder)
+	case 35:
+		return DecodeBsnPduRxTimeout(_bsnheader, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'BsnHeader'", _bsnheader.Subtype)
+	}
+}
+
+func NewBsnHeader(_subtype uint32) *BsnHeader {
+	obj := &BsnHeader{
+		Experimenter: NewExperimenter(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type BsnBwClearDataReply struct {
+	*BsnHeader
+	Status uint32
+}
+
+type IBsnBwClearDataReply interface {
+	IBsnHeader
+	GetStatus() uint32
+}
+
+func (self *BsnBwClearDataReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnBwClearDataReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnBwClearDataReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwClearDataReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwClearDataReply, error) {
+	_bsnbwcleardatareply := &BsnBwClearDataReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnBwClearDataReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnbwcleardatareply.Status = uint32(decoder.ReadUint32())
+	return _bsnbwcleardatareply, nil
+}
+
+func NewBsnBwClearDataReply() *BsnBwClearDataReply {
+	obj := &BsnBwClearDataReply{
+		BsnHeader: NewBsnHeader(22),
+	}
+	return obj
+}
+
+type BsnBwClearDataRequest struct {
+	*BsnHeader
+}
+
+type IBsnBwClearDataRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnBwClearDataRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwClearDataRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwClearDataRequest, error) {
+	_bsnbwcleardatarequest := &BsnBwClearDataRequest{BsnHeader: parent}
+	return _bsnbwcleardatarequest, nil
+}
+
+func NewBsnBwClearDataRequest() *BsnBwClearDataRequest {
+	obj := &BsnBwClearDataRequest{
+		BsnHeader: NewBsnHeader(21),
+	}
+	return obj
+}
+
+type BsnBwEnableGetReply struct {
+	*BsnHeader
+	Enabled uint32
+}
+
+type IBsnBwEnableGetReply interface {
+	IBsnHeader
+	GetEnabled() uint32
+}
+
+func (self *BsnBwEnableGetReply) GetEnabled() uint32 {
+	return self.Enabled
+}
+
+func (self *BsnBwEnableGetReply) SetEnabled(v uint32) {
+	self.Enabled = v
+}
+
+func (self *BsnBwEnableGetReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Enabled))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwEnableGetReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwEnableGetReply, error) {
+	_bsnbwenablegetreply := &BsnBwEnableGetReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnBwEnableGetReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnbwenablegetreply.Enabled = uint32(decoder.ReadUint32())
+	return _bsnbwenablegetreply, nil
+}
+
+func NewBsnBwEnableGetReply() *BsnBwEnableGetReply {
+	obj := &BsnBwEnableGetReply{
+		BsnHeader: NewBsnHeader(20),
+	}
+	return obj
+}
+
+type BsnBwEnableGetRequest struct {
+	*BsnHeader
+}
+
+type IBsnBwEnableGetRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnBwEnableGetRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwEnableGetRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwEnableGetRequest, error) {
+	_bsnbwenablegetrequest := &BsnBwEnableGetRequest{BsnHeader: parent}
+	return _bsnbwenablegetrequest, nil
+}
+
+func NewBsnBwEnableGetRequest() *BsnBwEnableGetRequest {
+	obj := &BsnBwEnableGetRequest{
+		BsnHeader: NewBsnHeader(19),
+	}
+	return obj
+}
+
+type BsnBwEnableSetReply struct {
+	*BsnHeader
+	Enable uint32
+	Status uint32
+}
+
+type IBsnBwEnableSetReply interface {
+	IBsnHeader
+	GetEnable() uint32
+	GetStatus() uint32
+}
+
+func (self *BsnBwEnableSetReply) GetEnable() uint32 {
+	return self.Enable
+}
+
+func (self *BsnBwEnableSetReply) SetEnable(v uint32) {
+	self.Enable = v
+}
+
+func (self *BsnBwEnableSetReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnBwEnableSetReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnBwEnableSetReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Enable))
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwEnableSetReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwEnableSetReply, error) {
+	_bsnbwenablesetreply := &BsnBwEnableSetReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnBwEnableSetReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnbwenablesetreply.Enable = uint32(decoder.ReadUint32())
+	_bsnbwenablesetreply.Status = uint32(decoder.ReadUint32())
+	return _bsnbwenablesetreply, nil
+}
+
+func NewBsnBwEnableSetReply() *BsnBwEnableSetReply {
+	obj := &BsnBwEnableSetReply{
+		BsnHeader: NewBsnHeader(23),
+	}
+	return obj
+}
+
+type BsnBwEnableSetRequest struct {
+	*BsnHeader
+	Enable uint32
+}
+
+type IBsnBwEnableSetRequest interface {
+	IBsnHeader
+	GetEnable() uint32
+}
+
+func (self *BsnBwEnableSetRequest) GetEnable() uint32 {
+	return self.Enable
+}
+
+func (self *BsnBwEnableSetRequest) SetEnable(v uint32) {
+	self.Enable = v
+}
+
+func (self *BsnBwEnableSetRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Enable))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnBwEnableSetRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnBwEnableSetRequest, error) {
+	_bsnbwenablesetrequest := &BsnBwEnableSetRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnBwEnableSetRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnbwenablesetrequest.Enable = uint32(decoder.ReadUint32())
+	return _bsnbwenablesetrequest, nil
+}
+
+func NewBsnBwEnableSetRequest() *BsnBwEnableSetRequest {
+	obj := &BsnBwEnableSetRequest{
+		BsnHeader: NewBsnHeader(18),
+	}
+	return obj
+}
+
+type BsnGetInterfacesReply struct {
+	*BsnHeader
+	Interfaces []*BsnInterface
+}
+
+type IBsnGetInterfacesReply interface {
+	IBsnHeader
+	GetInterfaces() []*BsnInterface
+}
+
+func (self *BsnGetInterfacesReply) GetInterfaces() []*BsnInterface {
+	return self.Interfaces
+}
+
+func (self *BsnGetInterfacesReply) SetInterfaces(v []*BsnInterface) {
+	self.Interfaces = v
+}
+
+func (self *BsnGetInterfacesReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	for _, obj := range self.Interfaces {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetInterfacesReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetInterfacesReply, error) {
+	_bsngetinterfacesreply := &BsnGetInterfacesReply{BsnHeader: parent}
+
+	for decoder.Length() >= 32 {
+		item, err := DecodeBsnInterface(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_bsngetinterfacesreply.Interfaces = append(_bsngetinterfacesreply.Interfaces, item)
+		}
+	}
+	return _bsngetinterfacesreply, nil
+}
+
+func NewBsnGetInterfacesReply() *BsnGetInterfacesReply {
+	obj := &BsnGetInterfacesReply{
+		BsnHeader: NewBsnHeader(10),
+	}
+	return obj
+}
+
+type BsnGetInterfacesRequest struct {
+	*BsnHeader
+}
+
+type IBsnGetInterfacesRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnGetInterfacesRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetInterfacesRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetInterfacesRequest, error) {
+	_bsngetinterfacesrequest := &BsnGetInterfacesRequest{BsnHeader: parent}
+	return _bsngetinterfacesrequest, nil
+}
+
+func NewBsnGetInterfacesRequest() *BsnGetInterfacesRequest {
+	obj := &BsnGetInterfacesRequest{
+		BsnHeader: NewBsnHeader(9),
+	}
+	return obj
+}
+
+type BsnGetIpMaskReply struct {
+	*BsnHeader
+	Index uint8
+	Mask  uint32
+}
+
+type IBsnGetIpMaskReply interface {
+	IBsnHeader
+	GetIndex() uint8
+	GetMask() uint32
+}
+
+func (self *BsnGetIpMaskReply) GetIndex() uint8 {
+	return self.Index
+}
+
+func (self *BsnGetIpMaskReply) SetIndex(v uint8) {
+	self.Index = v
+}
+
+func (self *BsnGetIpMaskReply) GetMask() uint32 {
+	return self.Mask
+}
+
+func (self *BsnGetIpMaskReply) SetMask(v uint32) {
+	self.Mask = v
+}
+
+func (self *BsnGetIpMaskReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Index))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.PutUint32(uint32(self.Mask))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetIpMaskReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetIpMaskReply, error) {
+	_bsngetipmaskreply := &BsnGetIpMaskReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnGetIpMaskReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsngetipmaskreply.Index = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_bsngetipmaskreply.Mask = uint32(decoder.ReadUint32())
+	return _bsngetipmaskreply, nil
+}
+
+func NewBsnGetIpMaskReply() *BsnGetIpMaskReply {
+	obj := &BsnGetIpMaskReply{
+		BsnHeader: NewBsnHeader(2),
+	}
+	return obj
+}
+
+type BsnGetIpMaskRequest struct {
+	*BsnHeader
+	Index uint8
+}
+
+type IBsnGetIpMaskRequest interface {
+	IBsnHeader
+	GetIndex() uint8
+}
+
+func (self *BsnGetIpMaskRequest) GetIndex() uint8 {
+	return self.Index
+}
+
+func (self *BsnGetIpMaskRequest) SetIndex(v uint8) {
+	self.Index = v
+}
+
+func (self *BsnGetIpMaskRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Index))
+	encoder.Write(bytes.Repeat([]byte{0}, 7))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnGetIpMaskRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetIpMaskRequest, error) {
+	_bsngetipmaskrequest := &BsnGetIpMaskRequest{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnGetIpMaskRequest packet too short: %d < 8", decoder.Length())
+	}
+	_bsngetipmaskrequest.Index = uint8(decoder.ReadByte())
+	decoder.Skip(7)
+	return _bsngetipmaskrequest, nil
+}
+
+func NewBsnGetIpMaskRequest() *BsnGetIpMaskRequest {
+	obj := &BsnGetIpMaskRequest{
+		BsnHeader: NewBsnHeader(1),
+	}
+	return obj
+}
+
+type BsnGetL2TableReply struct {
+	*BsnHeader
+	L2TableEnable   uint8
+	L2TablePriority uint16
+}
+
+type IBsnGetL2TableReply interface {
+	IBsnHeader
+	GetL2TableEnable() uint8
+	GetL2TablePriority() uint16
+}
+
+func (self *BsnGetL2TableReply) GetL2TableEnable() uint8 {
+	return self.L2TableEnable
+}
+
+func (self *BsnGetL2TableReply) SetL2TableEnable(v uint8) {
+	self.L2TableEnable = v
+}
+
+func (self *BsnGetL2TableReply) GetL2TablePriority() uint16 {
+	return self.L2TablePriority
+}
+
+func (self *BsnGetL2TableReply) SetL2TablePriority(v uint16) {
+	self.L2TablePriority = v
+}
+
+func (self *BsnGetL2TableReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.L2TableEnable))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint16(uint16(self.L2TablePriority))
+	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 DecodeBsnGetL2TableReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetL2TableReply, error) {
+	_bsngetl2tablereply := &BsnGetL2TableReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnGetL2TableReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsngetl2tablereply.L2TableEnable = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_bsngetl2tablereply.L2TablePriority = uint16(decoder.ReadUint16())
+	decoder.Skip(4)
+	return _bsngetl2tablereply, nil
+}
+
+func NewBsnGetL2TableReply() *BsnGetL2TableReply {
+	obj := &BsnGetL2TableReply{
+		BsnHeader: NewBsnHeader(14),
+	}
+	return obj
+}
+
+type BsnGetL2TableRequest struct {
+	*BsnHeader
+}
+
+type IBsnGetL2TableRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnGetL2TableRequest) 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 DecodeBsnGetL2TableRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnGetL2TableRequest, error) {
+	_bsngetl2tablerequest := &BsnGetL2TableRequest{BsnHeader: parent}
+	return _bsngetl2tablerequest, nil
+}
+
+func NewBsnGetL2TableRequest() *BsnGetL2TableRequest {
+	obj := &BsnGetL2TableRequest{
+		BsnHeader: NewBsnHeader(13),
+	}
+	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 BsnHybridGetReply struct {
+	*BsnHeader
+	HybridEnable  uint8
+	HybridVersion uint16
+}
+
+type IBsnHybridGetReply interface {
+	IBsnHeader
+	GetHybridEnable() uint8
+	GetHybridVersion() uint16
+}
+
+func (self *BsnHybridGetReply) GetHybridEnable() uint8 {
+	return self.HybridEnable
+}
+
+func (self *BsnHybridGetReply) SetHybridEnable(v uint8) {
+	self.HybridEnable = v
+}
+
+func (self *BsnHybridGetReply) GetHybridVersion() uint16 {
+	return self.HybridVersion
+}
+
+func (self *BsnHybridGetReply) SetHybridVersion(v uint16) {
+	self.HybridVersion = v
+}
+
+func (self *BsnHybridGetReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.HybridEnable))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint16(uint16(self.HybridVersion))
+	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 DecodeBsnHybridGetReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnHybridGetReply, error) {
+	_bsnhybridgetreply := &BsnHybridGetReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnHybridGetReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnhybridgetreply.HybridEnable = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_bsnhybridgetreply.HybridVersion = uint16(decoder.ReadUint16())
+	decoder.Skip(4)
+	return _bsnhybridgetreply, nil
+}
+
+func NewBsnHybridGetReply() *BsnHybridGetReply {
+	obj := &BsnHybridGetReply{
+		BsnHeader: NewBsnHeader(28),
+	}
+	return obj
+}
+
+type BsnHybridGetRequest struct {
+	*BsnHeader
+}
+
+type IBsnHybridGetRequest interface {
+	IBsnHeader
+}
+
+func (self *BsnHybridGetRequest) 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 DecodeBsnHybridGetRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnHybridGetRequest, error) {
+	_bsnhybridgetrequest := &BsnHybridGetRequest{BsnHeader: parent}
+	return _bsnhybridgetrequest, nil
+}
+
+func NewBsnHybridGetRequest() *BsnHybridGetRequest {
+	obj := &BsnHybridGetRequest{
+		BsnHeader: NewBsnHeader(27),
+	}
+	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() < 7 {
+		return nil, fmt.Errorf("BsnPduRxReply packet too short: %d < 7", 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() < 10 {
+		return nil, fmt.Errorf("BsnPduRxRequest packet too short: %d < 10", 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() < 3 {
+		return nil, fmt.Errorf("BsnPduRxTimeout packet too short: %d < 3", 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() < 7 {
+		return nil, fmt.Errorf("BsnPduTxReply packet too short: %d < 7", 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() < 10 {
+		return nil, fmt.Errorf("BsnPduTxRequest packet too short: %d < 10", 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 BsnSetIpMask struct {
+	*BsnHeader
+	Index uint8
+	Mask  uint32
+}
+
+type IBsnSetIpMask interface {
+	IBsnHeader
+	GetIndex() uint8
+	GetMask() uint32
+}
+
+func (self *BsnSetIpMask) GetIndex() uint8 {
+	return self.Index
+}
+
+func (self *BsnSetIpMask) SetIndex(v uint8) {
+	self.Index = v
+}
+
+func (self *BsnSetIpMask) GetMask() uint32 {
+	return self.Mask
+}
+
+func (self *BsnSetIpMask) SetMask(v uint32) {
+	self.Mask = v
+}
+
+func (self *BsnSetIpMask) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Index))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.PutUint32(uint32(self.Mask))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetIpMask(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetIpMask, error) {
+	_bsnsetipmask := &BsnSetIpMask{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnSetIpMask packet too short: %d < 8", decoder.Length())
+	}
+	_bsnsetipmask.Index = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_bsnsetipmask.Mask = uint32(decoder.ReadUint32())
+	return _bsnsetipmask, nil
+}
+
+func NewBsnSetIpMask() *BsnSetIpMask {
+	obj := &BsnSetIpMask{
+		BsnHeader: NewBsnHeader(0),
+	}
+	return obj
+}
+
+type BsnSetL2TableReply struct {
+	*BsnHeader
+	L2TableEnable   uint8
+	L2TablePriority uint16
+	Status          uint32
+}
+
+type IBsnSetL2TableReply interface {
+	IBsnHeader
+	GetL2TableEnable() uint8
+	GetL2TablePriority() uint16
+	GetStatus() uint32
+}
+
+func (self *BsnSetL2TableReply) GetL2TableEnable() uint8 {
+	return self.L2TableEnable
+}
+
+func (self *BsnSetL2TableReply) SetL2TableEnable(v uint8) {
+	self.L2TableEnable = v
+}
+
+func (self *BsnSetL2TableReply) GetL2TablePriority() uint16 {
+	return self.L2TablePriority
+}
+
+func (self *BsnSetL2TableReply) SetL2TablePriority(v uint16) {
+	self.L2TablePriority = v
+}
+
+func (self *BsnSetL2TableReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnSetL2TableReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnSetL2TableReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.L2TableEnable))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint16(uint16(self.L2TablePriority))
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnSetL2TableReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetL2TableReply, error) {
+	_bsnsetl2tablereply := &BsnSetL2TableReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnSetL2TableReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnsetl2tablereply.L2TableEnable = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_bsnsetl2tablereply.L2TablePriority = uint16(decoder.ReadUint16())
+	_bsnsetl2tablereply.Status = uint32(decoder.ReadUint32())
+	return _bsnsetl2tablereply, nil
+}
+
+func NewBsnSetL2TableReply() *BsnSetL2TableReply {
+	obj := &BsnSetL2TableReply{
+		BsnHeader: NewBsnHeader(24),
+	}
+	return obj
+}
+
+type BsnSetL2TableRequest struct {
+	*BsnHeader
+	L2TableEnable   uint8
+	L2TablePriority uint16
+}
+
+type IBsnSetL2TableRequest interface {
+	IBsnHeader
+	GetL2TableEnable() uint8
+	GetL2TablePriority() uint16
+}
+
+func (self *BsnSetL2TableRequest) GetL2TableEnable() uint8 {
+	return self.L2TableEnable
+}
+
+func (self *BsnSetL2TableRequest) SetL2TableEnable(v uint8) {
+	self.L2TableEnable = v
+}
+
+func (self *BsnSetL2TableRequest) GetL2TablePriority() uint16 {
+	return self.L2TablePriority
+}
+
+func (self *BsnSetL2TableRequest) SetL2TablePriority(v uint16) {
+	self.L2TablePriority = v
+}
+
+func (self *BsnSetL2TableRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.L2TableEnable))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint16(uint16(self.L2TablePriority))
+	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 DecodeBsnSetL2TableRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnSetL2TableRequest, error) {
+	_bsnsetl2tablerequest := &BsnSetL2TableRequest{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnSetL2TableRequest packet too short: %d < 8", decoder.Length())
+	}
+	_bsnsetl2tablerequest.L2TableEnable = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_bsnsetl2tablerequest.L2TablePriority = uint16(decoder.ReadUint16())
+	decoder.Skip(4)
+	return _bsnsetl2tablerequest, nil
+}
+
+func NewBsnSetL2TableRequest() *BsnSetL2TableRequest {
+	obj := &BsnSetL2TableRequest{
+		BsnHeader: NewBsnHeader(12),
+	}
+	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 BsnShellCommand struct {
+	*BsnHeader
+	Service uint32
+	Data    []byte
+}
+
+type IBsnShellCommand interface {
+	IBsnHeader
+	GetService() uint32
+	GetData() []byte
+}
+
+func (self *BsnShellCommand) GetService() uint32 {
+	return self.Service
+}
+
+func (self *BsnShellCommand) SetService(v uint32) {
+	self.Service = v
+}
+
+func (self *BsnShellCommand) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnShellCommand) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnShellCommand) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Service))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnShellCommand(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnShellCommand, error) {
+	_bsnshellcommand := &BsnShellCommand{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnShellCommand packet too short: %d < 4", decoder.Length())
+	}
+	_bsnshellcommand.Service = uint32(decoder.ReadUint32())
+	_bsnshellcommand.Data = decoder.Read(int(decoder.Length()))
+	return _bsnshellcommand, nil
+}
+
+func NewBsnShellCommand() *BsnShellCommand {
+	obj := &BsnShellCommand{
+		BsnHeader: NewBsnHeader(6),
+	}
+	return obj
+}
+
+type BsnShellOutput struct {
+	*BsnHeader
+	Data []byte
+}
+
+type IBsnShellOutput interface {
+	IBsnHeader
+	GetData() []byte
+}
+
+func (self *BsnShellOutput) GetData() []byte {
+	return self.Data
+}
+
+func (self *BsnShellOutput) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *BsnShellOutput) 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 DecodeBsnShellOutput(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnShellOutput, error) {
+	_bsnshelloutput := &BsnShellOutput{BsnHeader: parent}
+	_bsnshelloutput.Data = decoder.Read(int(decoder.Length()))
+	return _bsnshelloutput, nil
+}
+
+func NewBsnShellOutput() *BsnShellOutput {
+	obj := &BsnShellOutput{
+		BsnHeader: NewBsnHeader(7),
+	}
+	return obj
+}
+
+type BsnShellStatus struct {
+	*BsnHeader
+	Status uint32
+}
+
+type IBsnShellStatus interface {
+	IBsnHeader
+	GetStatus() uint32
+}
+
+func (self *BsnShellStatus) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnShellStatus) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnShellStatus) 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 DecodeBsnShellStatus(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnShellStatus, error) {
+	_bsnshellstatus := &BsnShellStatus{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnShellStatus packet too short: %d < 4", decoder.Length())
+	}
+	_bsnshellstatus.Status = uint32(decoder.ReadUint32())
+	return _bsnshellstatus, nil
+}
+
+func NewBsnShellStatus() *BsnShellStatus {
+	obj := &BsnShellStatus{
+		BsnHeader: NewBsnHeader(8),
+	}
+	return obj
+}
+
+type ExperimenterStatsReply struct {
+	*StatsReply
+	Experimenter uint32
+}
+
+type IExperimenterStatsReply interface {
+	IStatsReply
+	GetExperimenter() uint32
+}
+
+func (self *ExperimenterStatsReply) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *ExperimenterStatsReply) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *ExperimenterStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Experimenter))
+
+	return nil
+}
+
+func DecodeExperimenterStatsReply(parent *StatsReply, decoder *goloxi.Decoder) (IExperimenterStatsReply, error) {
+	_experimenterstatsreply := &ExperimenterStatsReply{StatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ExperimenterStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	_experimenterstatsreply.Experimenter = 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
+	Subtype uint32
+}
+
+type IBsnStatsReply interface {
+	IExperimenterStatsReply
+	GetSubtype() uint32
+}
+
+func (self *BsnStatsReply) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *BsnStatsReply) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *BsnStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeBsnStatsReply(parent *ExperimenterStatsReply, decoder *goloxi.Decoder) (IBsnStatsReply, error) {
+	_bsnstatsreply := &BsnStatsReply{ExperimenterStatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnstatsreply.Subtype = uint32(decoder.ReadUint32())
+	return _bsnstatsreply, nil
+}
+
+func NewBsnStatsReply(_subtype uint32) *BsnStatsReply {
+	obj := &BsnStatsReply{
+		ExperimenterStatsReply: NewExperimenterStatsReply(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type ExperimenterStatsRequest struct {
+	*StatsRequest
+	Experimenter uint32
+}
+
+type IExperimenterStatsRequest interface {
+	IStatsRequest
+	GetExperimenter() uint32
+}
+
+func (self *ExperimenterStatsRequest) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *ExperimenterStatsRequest) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *ExperimenterStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Experimenter))
+
+	return nil
+}
+
+func DecodeExperimenterStatsRequest(parent *StatsRequest, decoder *goloxi.Decoder) (IExperimenterStatsRequest, error) {
+	_experimenterstatsrequest := &ExperimenterStatsRequest{StatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ExperimenterStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	_experimenterstatsrequest.Experimenter = 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
+	Subtype uint32
+}
+
+type IBsnStatsRequest interface {
+	IExperimenterStatsRequest
+	GetSubtype() uint32
+}
+
+func (self *BsnStatsRequest) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *BsnStatsRequest) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *BsnStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeBsnStatsRequest(parent *ExperimenterStatsRequest, decoder *goloxi.Decoder) (IBsnStatsRequest, error) {
+	_bsnstatsrequest := &BsnStatsRequest{ExperimenterStatsRequest: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnStatsRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnstatsrequest.Subtype = uint32(decoder.ReadUint32())
+	return _bsnstatsrequest, nil
+}
+
+func NewBsnStatsRequest(_subtype uint32) *BsnStatsRequest {
+	obj := &BsnStatsRequest{
+		ExperimenterStatsRequest: NewExperimenterStatsRequest(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type BsnVirtualPortCreateReply struct {
+	*BsnHeader
+	Status  uint32
+	VportNo uint32
+}
+
+type IBsnVirtualPortCreateReply interface {
+	IBsnHeader
+	GetStatus() uint32
+	GetVportNo() uint32
+}
+
+func (self *BsnVirtualPortCreateReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnVirtualPortCreateReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnVirtualPortCreateReply) GetVportNo() uint32 {
+	return self.VportNo
+}
+
+func (self *BsnVirtualPortCreateReply) SetVportNo(v uint32) {
+	self.VportNo = v
+}
+
+func (self *BsnVirtualPortCreateReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	encoder.PutUint32(uint32(self.VportNo))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVirtualPortCreateReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVirtualPortCreateReply, error) {
+	_bsnvirtualportcreatereply := &BsnVirtualPortCreateReply{BsnHeader: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("BsnVirtualPortCreateReply packet too short: %d < 8", decoder.Length())
+	}
+	_bsnvirtualportcreatereply.Status = uint32(decoder.ReadUint32())
+	_bsnvirtualportcreatereply.VportNo = uint32(decoder.ReadUint32())
+	return _bsnvirtualportcreatereply, nil
+}
+
+func NewBsnVirtualPortCreateReply() *BsnVirtualPortCreateReply {
+	obj := &BsnVirtualPortCreateReply{
+		BsnHeader: NewBsnHeader(16),
+	}
+	return obj
+}
+
+type BsnVirtualPortCreateRequest struct {
+	*BsnHeader
+	Vport BSNVport
+}
+
+type IBsnVirtualPortCreateRequest interface {
+	IBsnHeader
+	GetVport() BSNVport
+}
+
+func (self *BsnVirtualPortCreateRequest) GetVport() BSNVport {
+	return self.Vport
+}
+
+func (self *BsnVirtualPortCreateRequest) SetVport(v BSNVport) {
+	self.Vport = v
+}
+
+func (self *BsnVirtualPortCreateRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	if err := self.Vport.Serialize(encoder); err != nil {
+		return err
+	}
+
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVirtualPortCreateRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVirtualPortCreateRequest, error) {
+	_bsnvirtualportcreaterequest := &BsnVirtualPortCreateRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnVirtualPortCreateRequest packet too short: %d < 4", decoder.Length())
+	}
+	if err := _bsnvirtualportcreaterequest.Vport.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	return _bsnvirtualportcreaterequest, nil
+}
+
+func NewBsnVirtualPortCreateRequest() *BsnVirtualPortCreateRequest {
+	obj := &BsnVirtualPortCreateRequest{
+		BsnHeader: NewBsnHeader(15),
+	}
+	return obj
+}
+
+type BsnVirtualPortRemoveReply struct {
+	*BsnHeader
+	Status uint32
+}
+
+type IBsnVirtualPortRemoveReply interface {
+	IBsnHeader
+	GetStatus() uint32
+}
+
+func (self *BsnVirtualPortRemoveReply) GetStatus() uint32 {
+	return self.Status
+}
+
+func (self *BsnVirtualPortRemoveReply) SetStatus(v uint32) {
+	self.Status = v
+}
+
+func (self *BsnVirtualPortRemoveReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Status))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVirtualPortRemoveReply(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVirtualPortRemoveReply, error) {
+	_bsnvirtualportremovereply := &BsnVirtualPortRemoveReply{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnVirtualPortRemoveReply packet too short: %d < 4", decoder.Length())
+	}
+	_bsnvirtualportremovereply.Status = uint32(decoder.ReadUint32())
+	return _bsnvirtualportremovereply, nil
+}
+
+func NewBsnVirtualPortRemoveReply() *BsnVirtualPortRemoveReply {
+	obj := &BsnVirtualPortRemoveReply{
+		BsnHeader: NewBsnHeader(26),
+	}
+	return obj
+}
+
+type BsnVirtualPortRemoveRequest struct {
+	*BsnHeader
+	VportNo uint32
+}
+
+type IBsnVirtualPortRemoveRequest interface {
+	IBsnHeader
+	GetVportNo() uint32
+}
+
+func (self *BsnVirtualPortRemoveRequest) GetVportNo() uint32 {
+	return self.VportNo
+}
+
+func (self *BsnVirtualPortRemoveRequest) SetVportNo(v uint32) {
+	self.VportNo = v
+}
+
+func (self *BsnVirtualPortRemoveRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.BsnHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.VportNo))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeBsnVirtualPortRemoveRequest(parent *BsnHeader, decoder *goloxi.Decoder) (*BsnVirtualPortRemoveRequest, error) {
+	_bsnvirtualportremoverequest := &BsnVirtualPortRemoveRequest{BsnHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("BsnVirtualPortRemoveRequest packet too short: %d < 4", decoder.Length())
+	}
+	_bsnvirtualportremoverequest.VportNo = uint32(decoder.ReadUint32())
+	return _bsnvirtualportremoverequest, nil
+}
+
+func NewBsnVirtualPortRemoveRequest() *BsnVirtualPortRemoveRequest {
+	obj := &BsnVirtualPortRemoveRequest{
+		BsnHeader: NewBsnHeader(17),
+	}
+	return obj
+}
+
+type DescStatsReply struct {
+	*StatsReply
+	MfrDesc   string
+	HwDesc    string
+	SwDesc    string
+	SerialNum string
+	DpDesc    string
+}
+
+type IDescStatsReply interface {
+	IStatsReply
+	GetMfrDesc() string
+	GetHwDesc() string
+	GetSwDesc() string
+	GetSerialNum() string
+	GetDpDesc() string
+}
+
+func (self *DescStatsReply) GetMfrDesc() string {
+	return self.MfrDesc
+}
+
+func (self *DescStatsReply) SetMfrDesc(v string) {
+	self.MfrDesc = v
+}
+
+func (self *DescStatsReply) GetHwDesc() string {
+	return self.HwDesc
+}
+
+func (self *DescStatsReply) SetHwDesc(v string) {
+	self.HwDesc = v
+}
+
+func (self *DescStatsReply) GetSwDesc() string {
+	return self.SwDesc
+}
+
+func (self *DescStatsReply) SetSwDesc(v string) {
+	self.SwDesc = v
+}
+
+func (self *DescStatsReply) GetSerialNum() string {
+	return self.SerialNum
+}
+
+func (self *DescStatsReply) SetSerialNum(v string) {
+	self.SerialNum = v
+}
+
+func (self *DescStatsReply) GetDpDesc() string {
+	return self.DpDesc
+}
+
+func (self *DescStatsReply) SetDpDesc(v string) {
+	self.DpDesc = v
+}
+
+func (self *DescStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write([]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() < 1056 {
+		return nil, fmt.Errorf("DescStatsReply packet too short: %d < 1056", decoder.Length())
+	}
+	_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
+	}
+	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}
+	return _descstatsrequest, nil
+}
+
+func NewDescStatsRequest() *DescStatsRequest {
+	obj := &DescStatsRequest{
+		StatsRequest: NewStatsRequest(0),
+	}
+	return obj
+}
+
+type EchoReply struct {
+	*Header
+	Data []byte
+}
+
+type IEchoReply interface {
+	IHeader
+	GetData() []byte
+}
+
+func (self *EchoReply) GetData() []byte {
+	return self.Data
+}
+
+func (self *EchoReply) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *EchoReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeEchoReply(parent *Header, decoder *goloxi.Decoder) (*EchoReply, error) {
+	_echoreply := &EchoReply{Header: parent}
+	_echoreply.Data = decoder.Read(int(decoder.Length()))
+	return _echoreply, nil
+}
+
+func NewEchoReply() *EchoReply {
+	obj := &EchoReply{
+		Header: NewHeader(3),
+	}
+	return obj
+}
+
+type EchoRequest struct {
+	*Header
+	Data []byte
+}
+
+type IEchoRequest interface {
+	IHeader
+	GetData() []byte
+}
+
+func (self *EchoRequest) GetData() []byte {
+	return self.Data
+}
+
+func (self *EchoRequest) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *EchoRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeEchoRequest(parent *Header, decoder *goloxi.Decoder) (*EchoRequest, error) {
+	_echorequest := &EchoRequest{Header: parent}
+	_echorequest.Data = decoder.Read(int(decoder.Length()))
+	return _echorequest, nil
+}
+
+func NewEchoRequest() *EchoRequest {
+	obj := &EchoRequest{
+		Header: NewHeader(2),
+	}
+	return obj
+}
+
+type FeaturesReply struct {
+	*Header
+	DatapathId   uint64
+	NBuffers     uint32
+	NTables      uint8
+	Capabilities Capabilities
+	Actions      uint32
+	Ports        []*PortDesc
+}
+
+type IFeaturesReply interface {
+	IHeader
+	GetDatapathId() uint64
+	GetNBuffers() uint32
+	GetNTables() uint8
+	GetCapabilities() Capabilities
+	GetActions() uint32
+	GetPorts() []*PortDesc
+}
+
+func (self *FeaturesReply) GetDatapathId() uint64 {
+	return self.DatapathId
+}
+
+func (self *FeaturesReply) SetDatapathId(v uint64) {
+	self.DatapathId = v
+}
+
+func (self *FeaturesReply) GetNBuffers() uint32 {
+	return self.NBuffers
+}
+
+func (self *FeaturesReply) SetNBuffers(v uint32) {
+	self.NBuffers = v
+}
+
+func (self *FeaturesReply) GetNTables() uint8 {
+	return self.NTables
+}
+
+func (self *FeaturesReply) SetNTables(v uint8) {
+	self.NTables = v
+}
+
+func (self *FeaturesReply) GetCapabilities() Capabilities {
+	return self.Capabilities
+}
+
+func (self *FeaturesReply) SetCapabilities(v Capabilities) {
+	self.Capabilities = v
+}
+
+func (self *FeaturesReply) GetActions() uint32 {
+	return self.Actions
+}
+
+func (self *FeaturesReply) SetActions(v uint32) {
+	self.Actions = v
+}
+
+func (self *FeaturesReply) GetPorts() []*PortDesc {
+	return self.Ports
+}
+
+func (self *FeaturesReply) SetPorts(v []*PortDesc) {
+	self.Ports = v
+}
+
+func (self *FeaturesReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.DatapathId))
+	encoder.PutUint32(uint32(self.NBuffers))
+	encoder.PutUint8(uint8(self.NTables))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.PutUint32(uint32(self.Capabilities))
+	encoder.PutUint32(uint32(self.Actions))
+	for _, obj := range self.Ports {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFeaturesReply(parent *Header, decoder *goloxi.Decoder) (*FeaturesReply, error) {
+	_featuresreply := &FeaturesReply{Header: parent}
+	if decoder.Length() < 24 {
+		return nil, fmt.Errorf("FeaturesReply packet too short: %d < 24", decoder.Length())
+	}
+	_featuresreply.DatapathId = uint64(decoder.ReadUint64())
+	_featuresreply.NBuffers = uint32(decoder.ReadUint32())
+	_featuresreply.NTables = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_featuresreply.Capabilities = Capabilities(decoder.ReadUint32())
+	_featuresreply.Actions = uint32(decoder.ReadUint32())
+
+	for decoder.Length() >= 48 {
+		item := &PortDesc{}
+		if err := item.Decode(decoder); err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_featuresreply.Ports = append(_featuresreply.Ports, item)
+		}
+	}
+	return _featuresreply, nil
+}
+
+func NewFeaturesReply() *FeaturesReply {
+	obj := &FeaturesReply{
+		Header: NewHeader(6),
+	}
+	return obj
+}
+
+type FeaturesRequest struct {
+	*Header
+}
+
+type IFeaturesRequest interface {
+	IHeader
+}
+
+func (self *FeaturesRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeFeaturesRequest(parent *Header, decoder *goloxi.Decoder) (*FeaturesRequest, error) {
+	_featuresrequest := &FeaturesRequest{Header: parent}
+	return _featuresrequest, nil
+}
+
+func NewFeaturesRequest() *FeaturesRequest {
+	obj := &FeaturesRequest{
+		Header: NewHeader(5),
+	}
+	return obj
+}
+
+type FlowMod struct {
+	*Header
+	Match       Match
+	Cookie      uint64
+	Command     FmCmd
+	IdleTimeout uint16
+	HardTimeout uint16
+	Priority    uint16
+	BufferId    uint32
+	OutPort     Port
+	Flags       FlowModFlags
+	Actions     []goloxi.IAction
+}
+
+type IFlowMod interface {
+	IHeader
+	GetMatch() Match
+	GetCookie() uint64
+	GetCommand() FmCmd
+	GetIdleTimeout() uint16
+	GetHardTimeout() uint16
+	GetPriority() uint16
+	GetBufferId() uint32
+	GetOutPort() Port
+	GetFlags() FlowModFlags
+	GetActions() []goloxi.IAction
+}
+
+func (self *FlowMod) GetMatch() Match {
+	return self.Match
+}
+
+func (self *FlowMod) SetMatch(v Match) {
+	self.Match = v
+}
+
+func (self *FlowMod) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *FlowMod) SetCookie(v uint64) {
+	self.Cookie = 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) GetFlags() FlowModFlags {
+	return self.Flags
+}
+
+func (self *FlowMod) SetFlags(v FlowModFlags) {
+	self.Flags = v
+}
+
+func (self *FlowMod) GetActions() []goloxi.IAction {
+	return self.Actions
+}
+
+func (self *FlowMod) SetActions(v []goloxi.IAction) {
+	self.Actions = v
+}
+
+func (self *FlowMod) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.Cookie))
+	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.PutUint16(uint16(self.Flags))
+	for _, obj := range self.Actions {
+		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() < 64 {
+		return nil, fmt.Errorf("FlowMod packet too short: %d < 64", decoder.Length())
+	}
+	if err := _flowmod.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	_flowmod.Cookie = uint64(decoder.ReadUint64())
+	_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.Flags = FlowModFlags(decoder.ReadUint16())
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeAction(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_flowmod.Actions = append(_flowmod.Actions, 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(3),
+	}
+	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
+	Match        Match
+	Cookie       uint64
+	Priority     uint16
+	Reason       FlowRemovedReason
+	DurationSec  uint32
+	DurationNsec uint32
+	IdleTimeout  uint16
+	PacketCount  uint64
+	ByteCount    uint64
+}
+
+type IFlowRemoved interface {
+	IHeader
+	GetMatch() Match
+	GetCookie() uint64
+	GetPriority() uint16
+	GetReason() FlowRemovedReason
+	GetDurationSec() uint32
+	GetDurationNsec() uint32
+	GetIdleTimeout() uint16
+	GetPacketCount() uint64
+	GetByteCount() uint64
+}
+
+func (self *FlowRemoved) GetMatch() Match {
+	return self.Match
+}
+
+func (self *FlowRemoved) SetMatch(v Match) {
+	self.Match = v
+}
+
+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) GetDurationSec() uint32 {
+	return self.DurationSec
+}
+
+func (self *FlowRemoved) SetDurationSec(v uint32) {
+	self.DurationSec = v
+}
+
+func (self *FlowRemoved) GetDurationNsec() uint32 {
+	return self.DurationNsec
+}
+
+func (self *FlowRemoved) SetDurationNsec(v uint32) {
+	self.DurationNsec = v
+}
+
+func (self *FlowRemoved) GetIdleTimeout() uint16 {
+	return self.IdleTimeout
+}
+
+func (self *FlowRemoved) SetIdleTimeout(v uint16) {
+	self.IdleTimeout = v
+}
+
+func (self *FlowRemoved) GetPacketCount() uint64 {
+	return self.PacketCount
+}
+
+func (self *FlowRemoved) SetPacketCount(v uint64) {
+	self.PacketCount = v
+}
+
+func (self *FlowRemoved) GetByteCount() uint64 {
+	return self.ByteCount
+}
+
+func (self *FlowRemoved) SetByteCount(v uint64) {
+	self.ByteCount = v
+}
+
+func (self *FlowRemoved) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.Cookie))
+	encoder.PutUint16(uint16(self.Priority))
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint32(uint32(self.DurationSec))
+	encoder.PutUint32(uint32(self.DurationNsec))
+	encoder.PutUint16(uint16(self.IdleTimeout))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint64(uint64(self.PacketCount))
+	encoder.PutUint64(uint64(self.ByteCount))
+	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() < 80 {
+		return nil, fmt.Errorf("FlowRemoved packet too short: %d < 80", decoder.Length())
+	}
+	if err := _flowremoved.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	_flowremoved.Cookie = uint64(decoder.ReadUint64())
+	_flowremoved.Priority = uint16(decoder.ReadUint16())
+	_flowremoved.Reason = FlowRemovedReason(decoder.ReadByte())
+	decoder.Skip(1)
+	_flowremoved.DurationSec = uint32(decoder.ReadUint32())
+	_flowremoved.DurationNsec = uint32(decoder.ReadUint32())
+	_flowremoved.IdleTimeout = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_flowremoved.PacketCount = uint64(decoder.ReadUint64())
+	_flowremoved.ByteCount = uint64(decoder.ReadUint64())
+	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
+	}
+
+	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}
+
+	for decoder.Length() >= 88 {
+		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
+	Match   Match
+	TableId uint8
+	OutPort Port
+}
+
+type IFlowStatsRequest interface {
+	IStatsRequest
+	GetMatch() Match
+	GetTableId() uint8
+	GetOutPort() Port
+}
+
+func (self *FlowStatsRequest) GetMatch() Match {
+	return self.Match
+}
+
+func (self *FlowStatsRequest) SetMatch(v Match) {
+	self.Match = v
+}
+
+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) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	if err := self.Match.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	self.OutPort.Serialize(encoder)
+	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() < 44 {
+		return nil, fmt.Errorf("FlowStatsRequest packet too short: %d < 44", decoder.Length())
+	}
+	if err := _flowstatsrequest.Match.Decode(decoder); err != nil {
+		return nil, err
+	}
+
+	_flowstatsrequest.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_flowstatsrequest.OutPort.Decode(decoder)
+	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 Hello struct {
+	*Header
+}
+
+type IHello interface {
+	IHeader
+}
+
+func (self *Hello) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeHello(parent *Header, decoder *goloxi.Decoder) (*Hello, error) {
+	_hello := &Hello{Header: parent}
+	return _hello, nil
+}
+
+func NewHello() *Hello {
+	obj := &Hello{
+		Header: NewHeader(0),
+	}
+	return obj
+}
+
+type HelloFailedErrorMsg struct {
+	*ErrorMsg
+	Code HelloFailedCode
+	Data []byte
+}
+
+type IHelloFailedErrorMsg interface {
+	IErrorMsg
+	GetCode() HelloFailedCode
+	GetData() []byte
+}
+
+func (self *HelloFailedErrorMsg) GetCode() HelloFailedCode {
+	return self.Code
+}
+
+func (self *HelloFailedErrorMsg) SetCode(v HelloFailedCode) {
+	self.Code = v
+}
+
+func (self *HelloFailedErrorMsg) GetData() []byte {
+	return self.Data
+}
+
+func (self *HelloFailedErrorMsg) SetData(v []byte) {
+	self.Data = v
+}
+
+func (self *HelloFailedErrorMsg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ErrorMsg.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Code))
+	encoder.Write(self.Data)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeHelloFailedErrorMsg(parent *ErrorMsg, decoder *goloxi.Decoder) (*HelloFailedErrorMsg, error) {
+	_hellofailederrormsg := &HelloFailedErrorMsg{ErrorMsg: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("HelloFailedErrorMsg packet too short: %d < 2", decoder.Length())
+	}
+	_hellofailederrormsg.Code = HelloFailedCode(decoder.ReadUint16())
+	_hellofailederrormsg.Data = decoder.Read(int(decoder.Length()))
+	return _hellofailederrormsg, nil
+}
+
+func NewHelloFailedErrorMsg() *HelloFailedErrorMsg {
+	obj := &HelloFailedErrorMsg{
+		ErrorMsg: NewErrorMsg(0),
+	}
+	return obj
+}
+
+type NiciraHeader struct {
+	*Experimenter
+	Subtype uint32
+}
+
+type INiciraHeader interface {
+	IExperimenter
+	GetSubtype() uint32
+}
+
+func (self *NiciraHeader) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *NiciraHeader) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *NiciraHeader) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Experimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeNiciraHeader(parent *Experimenter, decoder *goloxi.Decoder) (INiciraHeader, error) {
+	_niciraheader := &NiciraHeader{Experimenter: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraHeader packet too short: %d < 4", decoder.Length())
+	}
+	_niciraheader.Subtype = uint32(decoder.ReadUint32())
+
+	switch _niciraheader.Subtype {
+	case 10:
+		return DecodeNiciraControllerRoleRequest(_niciraheader, decoder)
+	case 11:
+		return DecodeNiciraControllerRoleReply(_niciraheader, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'NiciraHeader'", _niciraheader.Subtype)
+	}
+}
+
+func NewNiciraHeader(_subtype uint32) *NiciraHeader {
+	obj := &NiciraHeader{
+		Experimenter: NewExperimenter(8992),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type NiciraControllerRoleReply struct {
+	*NiciraHeader
+	Role NiciraControllerRole
+}
+
+type INiciraControllerRoleReply interface {
+	INiciraHeader
+	GetRole() NiciraControllerRole
+}
+
+func (self *NiciraControllerRoleReply) GetRole() NiciraControllerRole {
+	return self.Role
+}
+
+func (self *NiciraControllerRoleReply) SetRole(v NiciraControllerRole) {
+	self.Role = v
+}
+
+func (self *NiciraControllerRoleReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.NiciraHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Role))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeNiciraControllerRoleReply(parent *NiciraHeader, decoder *goloxi.Decoder) (*NiciraControllerRoleReply, error) {
+	_niciracontrollerrolereply := &NiciraControllerRoleReply{NiciraHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraControllerRoleReply packet too short: %d < 4", decoder.Length())
+	}
+	_niciracontrollerrolereply.Role = NiciraControllerRole(decoder.ReadUint32())
+	return _niciracontrollerrolereply, nil
+}
+
+func NewNiciraControllerRoleReply() *NiciraControllerRoleReply {
+	obj := &NiciraControllerRoleReply{
+		NiciraHeader: NewNiciraHeader(11),
+	}
+	return obj
+}
+
+type NiciraControllerRoleRequest struct {
+	*NiciraHeader
+	Role NiciraControllerRole
+}
+
+type INiciraControllerRoleRequest interface {
+	INiciraHeader
+	GetRole() NiciraControllerRole
+}
+
+func (self *NiciraControllerRoleRequest) GetRole() NiciraControllerRole {
+	return self.Role
+}
+
+func (self *NiciraControllerRoleRequest) SetRole(v NiciraControllerRole) {
+	self.Role = v
+}
+
+func (self *NiciraControllerRoleRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.NiciraHeader.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Role))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeNiciraControllerRoleRequest(parent *NiciraHeader, decoder *goloxi.Decoder) (*NiciraControllerRoleRequest, error) {
+	_niciracontrollerrolerequest := &NiciraControllerRoleRequest{NiciraHeader: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraControllerRoleRequest packet too short: %d < 4", decoder.Length())
+	}
+	_niciracontrollerrolerequest.Role = NiciraControllerRole(decoder.ReadUint32())
+	return _niciracontrollerrolerequest, nil
+}
+
+func NewNiciraControllerRoleRequest() *NiciraControllerRoleRequest {
+	obj := &NiciraControllerRoleRequest{
+		NiciraHeader: NewNiciraHeader(10),
+	}
+	return obj
+}
+
+type NiciraStatsReply struct {
+	*ExperimenterStatsReply
+	Subtype uint32
+}
+
+type INiciraStatsReply interface {
+	IExperimenterStatsReply
+	GetSubtype() uint32
+}
+
+func (self *NiciraStatsReply) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *NiciraStatsReply) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *NiciraStatsReply) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ExperimenterStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeNiciraStatsReply(parent *ExperimenterStatsReply, decoder *goloxi.Decoder) (INiciraStatsReply, error) {
+	_nicirastatsreply := &NiciraStatsReply{ExperimenterStatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraStatsReply packet too short: %d < 4", decoder.Length())
+	}
+	_nicirastatsreply.Subtype = uint32(decoder.ReadUint32())
+
+	switch _nicirastatsreply.Subtype {
+	case 0:
+		return DecodeNiciraFlowStatsReply(_nicirastatsreply, decoder)
+	case 2:
+		return DecodeNiciraFlowMonitorReply(_nicirastatsreply, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'NiciraStatsReply'", _nicirastatsreply.Subtype)
+	}
+}
+
+func NewNiciraStatsReply(_subtype uint32) *NiciraStatsReply {
+	obj := &NiciraStatsReply{
+		ExperimenterStatsReply: NewExperimenterStatsReply(8992),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type NiciraFlowMonitorReply struct {
+	*NiciraStatsReply
+	Updates []INiciraFlowUpdateEvent
+}
+
+type INiciraFlowMonitorReply interface {
+	INiciraStatsReply
+	GetUpdates() []INiciraFlowUpdateEvent
+}
+
+func (self *NiciraFlowMonitorReply) GetUpdates() []INiciraFlowUpdateEvent {
+	return self.Updates
+}
+
+func (self *NiciraFlowMonitorReply) SetUpdates(v []INiciraFlowUpdateEvent) {
+	self.Updates = v
+}
+
+func (self *NiciraFlowMonitorReply) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.NiciraStatsReply.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Updates {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeNiciraFlowMonitorReply(parent *NiciraStatsReply, decoder *goloxi.Decoder) (*NiciraFlowMonitorReply, error) {
+	_niciraflowmonitorreply := &NiciraFlowMonitorReply{NiciraStatsReply: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("NiciraFlowMonitorReply packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeNiciraFlowUpdateEvent(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_niciraflowmonitorreply.Updates = append(_niciraflowmonitorreply.Updates, item)
+		}
+	}
+	return _niciraflowmonitorreply, nil
+}
+
+func NewNiciraFlowMonitorReply() *NiciraFlowMonitorReply {
+	obj := &NiciraFlowMonitorReply{
+		NiciraStatsReply: NewNiciraStatsReply(2),
+	}
+	return obj
+}
+
+type NiciraFlowMonitorRequest struct {
+	*ExperimenterStatsRequest
+	Subtype      uint32
+	MonitorId    uint32
+	MonitorFlags NxFlowMonitorFlags
+	OutPort      Port
+	MatchLen     uint16
+	TableId      uint8
+	Match        NiciraMatch
+}
+
+type INiciraFlowMonitorRequest interface {
+	IExperimenterStatsRequest
+	GetSubtype() uint32
+	GetMonitorId() uint32
+	GetMonitorFlags() NxFlowMonitorFlags
+	GetOutPort() Port
+	GetMatchLen() uint16
+	GetTableId() uint8
+	GetMatch() NiciraMatch
+}
+
+func (self *NiciraFlowMonitorRequest) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *NiciraFlowMonitorRequest) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetMonitorId() uint32 {
+	return self.MonitorId
+}
+
+func (self *NiciraFlowMonitorRequest) SetMonitorId(v uint32) {
+	self.MonitorId = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetMonitorFlags() NxFlowMonitorFlags {
+	return self.MonitorFlags
+}
+
+func (self *NiciraFlowMonitorRequest) SetMonitorFlags(v NxFlowMonitorFlags) {
+	self.MonitorFlags = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetOutPort() Port {
+	return self.OutPort
+}
+
+func (self *NiciraFlowMonitorRequest) SetOutPort(v Port) {
+	self.OutPort = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetMatchLen() uint16 {
+	return self.MatchLen
+}
+
+func (self *NiciraFlowMonitorRequest) SetMatchLen(v uint16) {
+	self.MatchLen = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *NiciraFlowMonitorRequest) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *NiciraFlowMonitorRequest) GetMatch() NiciraMatch {
+	return self.Match
+}
+
+func (self *NiciraFlowMonitorRequest) SetMatch(v NiciraMatch) {
+	self.Match = v
+}
+
+func (self *NiciraFlowMonitorRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ExperimenterStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+	encoder.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() < 24 {
+		return nil, fmt.Errorf("NiciraFlowMonitorRequest packet too short: %d < 24", decoder.Length())
+	}
+	_niciraflowmonitorrequest.Subtype = uint32(decoder.ReadUint32())
+	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
+	Subtype  uint32
+	OutPort  Port
+	MatchLen uint16
+	TableId  uint8
+}
+
+type INiciraFlowStatsRequest interface {
+	IExperimenterStatsRequest
+	GetSubtype() uint32
+	GetOutPort() Port
+	GetMatchLen() uint16
+	GetTableId() uint8
+}
+
+func (self *NiciraFlowStatsRequest) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *NiciraFlowStatsRequest) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *NiciraFlowStatsRequest) GetOutPort() Port {
+	return self.OutPort
+}
+
+func (self *NiciraFlowStatsRequest) SetOutPort(v Port) {
+	self.OutPort = v
+}
+
+func (self *NiciraFlowStatsRequest) GetMatchLen() uint16 {
+	return self.MatchLen
+}
+
+func (self *NiciraFlowStatsRequest) SetMatchLen(v uint16) {
+	self.MatchLen = v
+}
+
+func (self *NiciraFlowStatsRequest) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *NiciraFlowStatsRequest) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *NiciraFlowStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ExperimenterStatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+	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() < 16 {
+		return nil, fmt.Errorf("NiciraFlowStatsRequest packet too short: %d < 16", decoder.Length())
+	}
+	_niciraflowstatsrequest.Subtype = uint32(decoder.ReadUint32())
+	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 PacketIn struct {
+	*Header
+	BufferId uint32
+	TotalLen uint16
+	InPort   Port
+	Reason   uint8
+	Data     []byte
+}
+
+type IPacketIn interface {
+	IHeader
+	GetBufferId() uint32
+	GetTotalLen() uint16
+	GetInPort() Port
+	GetReason() uint8
+	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) GetInPort() Port {
+	return self.InPort
+}
+
+func (self *PacketIn) SetInPort(v Port) {
+	self.InPort = v
+}
+
+func (self *PacketIn) GetReason() uint8 {
+	return self.Reason
+}
+
+func (self *PacketIn) SetReason(v uint8) {
+	self.Reason = 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))
+	self.InPort.Serialize(encoder)
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	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() < 10 {
+		return nil, fmt.Errorf("PacketIn packet too short: %d < 10", decoder.Length())
+	}
+	_packetin.BufferId = uint32(decoder.ReadUint32())
+	_packetin.TotalLen = uint16(decoder.ReadUint16())
+	_packetin.InPort.Decode(decoder)
+	_packetin.Reason = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_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))
+	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() < 8 {
+		return nil, fmt.Errorf("PacketOut packet too short: %d < 8", decoder.Length())
+	}
+	_packetout.BufferId = uint32(decoder.ReadUint32())
+	_packetout.InPort.Decode(decoder)
+	_packetout.ActionsLen = uint16(decoder.ReadUint16())
+
+	end := decoder.Offset() + int(_packetout.ActionsLen)
+	for decoder.Offset() < end {
+		item, err := DecodeAction(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_packetout.Actions = append(_packetout.Actions, item)
+		}
+	}
+	_packetout.Data = decoder.Read(int(decoder.Length()))
+	return _packetout, nil
+}
+
+func NewPacketOut() *PacketOut {
+	obj := &PacketOut{
+		Header: NewHeader(13),
+	}
+	return obj
+}
+
+type PortMod struct {
+	*Header
+	PortNo    Port
+	HwAddr    net.HardwareAddr
+	Config    PortConfig
+	Mask      PortConfig
+	Advertise uint32
+}
+
+type IPortMod interface {
+	IHeader
+	GetPortNo() Port
+	GetHwAddr() net.HardwareAddr
+	GetConfig() PortConfig
+	GetMask() PortConfig
+	GetAdvertise() uint32
+}
+
+func (self *PortMod) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *PortMod) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *PortMod) GetHwAddr() net.HardwareAddr {
+	return self.HwAddr
+}
+
+func (self *PortMod) SetHwAddr(v net.HardwareAddr) {
+	self.HwAddr = v
+}
+
+func (self *PortMod) GetConfig() PortConfig {
+	return self.Config
+}
+
+func (self *PortMod) SetConfig(v PortConfig) {
+	self.Config = v
+}
+
+func (self *PortMod) GetMask() PortConfig {
+	return self.Mask
+}
+
+func (self *PortMod) SetMask(v PortConfig) {
+	self.Mask = v
+}
+
+func (self *PortMod) GetAdvertise() uint32 {
+	return self.Advertise
+}
+
+func (self *PortMod) SetAdvertise(v uint32) {
+	self.Advertise = v
+}
+
+func (self *PortMod) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.PortNo.Serialize(encoder)
+	encoder.Write(self.HwAddr)
+	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() < 24 {
+		return nil, fmt.Errorf("PortMod packet too short: %d < 24", decoder.Length())
+	}
+	_portmod.PortNo.Decode(decoder)
+	_portmod.HwAddr = net.HardwareAddr(decoder.Read(6))
+	_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(15),
+	}
+	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(4),
+	}
+	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
+	}
+
+	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}
+
+	for decoder.Length() >= 104 {
+		item, err := DecodePortStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_portstatsreply.Entries = append(_portstatsreply.Entries, item)
+		}
+	}
+	return _portstatsreply, nil
+}
+
+func NewPortStatsReply() *PortStatsReply {
+	obj := &PortStatsReply{
+		StatsReply: NewStatsReply(4),
+	}
+	return obj
+}
+
+type PortStatsRequest struct {
+	*StatsRequest
+	PortNo Port
+}
+
+type IPortStatsRequest interface {
+	IStatsRequest
+	GetPortNo() Port
+}
+
+func (self *PortStatsRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *PortStatsRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *PortStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.PortNo.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 6))
+	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() < 8 {
+		return nil, fmt.Errorf("PortStatsRequest packet too short: %d < 8", decoder.Length())
+	}
+	_portstatsrequest.PortNo.Decode(decoder)
+	decoder.Skip(6)
+	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() < 56 {
+		return nil, fmt.Errorf("PortStatus packet too short: %d < 56", 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}, 6))
+	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(6)
+
+	for decoder.Length() >= 8 {
+		item, err := DecodePacketQueue(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_queuegetconfigreply.Queues = append(_queuegetconfigreply.Queues, item)
+		}
+	}
+	return _queuegetconfigreply, nil
+}
+
+func NewQueueGetConfigReply() *QueueGetConfigReply {
+	obj := &QueueGetConfigReply{
+		Header: NewHeader(21),
+	}
+	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}, 2))
+	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() < 4 {
+		return nil, fmt.Errorf("QueueGetConfigRequest packet too short: %d < 4", decoder.Length())
+	}
+	_queuegetconfigrequest.Port.Decode(decoder)
+	decoder.Skip(2)
+	return _queuegetconfigrequest, nil
+}
+
+func NewQueueGetConfigRequest() *QueueGetConfigRequest {
+	obj := &QueueGetConfigRequest{
+		Header: NewHeader(20),
+	}
+	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(5),
+	}
+	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
+	}
+
+	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}
+
+	for decoder.Length() >= 32 {
+		item, err := DecodeQueueStatsEntry(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_queuestatsreply.Entries = append(_queuestatsreply.Entries, item)
+		}
+	}
+	return _queuestatsreply, nil
+}
+
+func NewQueueStatsReply() *QueueStatsReply {
+	obj := &QueueStatsReply{
+		StatsReply: NewStatsReply(5),
+	}
+	return obj
+}
+
+type QueueStatsRequest struct {
+	*StatsRequest
+	PortNo  Port
+	QueueId uint32
+}
+
+type IQueueStatsRequest interface {
+	IStatsRequest
+	GetPortNo() Port
+	GetQueueId() uint32
+}
+
+func (self *QueueStatsRequest) GetPortNo() Port {
+	return self.PortNo
+}
+
+func (self *QueueStatsRequest) SetPortNo(v Port) {
+	self.PortNo = v
+}
+
+func (self *QueueStatsRequest) GetQueueId() uint32 {
+	return self.QueueId
+}
+
+func (self *QueueStatsRequest) SetQueueId(v uint32) {
+	self.QueueId = v
+}
+
+func (self *QueueStatsRequest) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.StatsRequest.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.PortNo.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	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() < 8 {
+		return nil, fmt.Errorf("QueueStatsRequest packet too short: %d < 8", decoder.Length())
+	}
+	_queuestatsrequest.PortNo.Decode(decoder)
+	decoder.Skip(2)
+	_queuestatsrequest.QueueId = uint32(decoder.ReadUint32())
+	return _queuestatsrequest, nil
+}
+
+func NewQueueStatsRequest() *QueueStatsRequest {
+	obj := &QueueStatsRequest{
+		StatsRequest: NewStatsRequest(5),
+	}
+	return obj
+}
+
+type SetConfig struct {
+	*Header
+	Flags       ConfigFlags
+	MissSendLen uint16
+}
+
+type ISetConfig interface {
+	IHeader
+	GetFlags() ConfigFlags
+	GetMissSendLen() uint16
+}
+
+func (self *SetConfig) GetFlags() ConfigFlags {
+	return self.Flags
+}
+
+func (self *SetConfig) SetFlags(v ConfigFlags) {
+	self.Flags = v
+}
+
+func (self *SetConfig) GetMissSendLen() uint16 {
+	return self.MissSendLen
+}
+
+func (self *SetConfig) SetMissSendLen(v uint16) {
+	self.MissSendLen = v
+}
+
+func (self *SetConfig) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Header.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.PutUint16(uint16(self.MissSendLen))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeSetConfig(parent *Header, decoder *goloxi.Decoder) (*SetConfig, error) {
+	_setconfig := &SetConfig{Header: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("SetConfig packet too short: %d < 4", decoder.Length())
+	}
+	_setconfig.Flags = ConfigFlags(decoder.ReadUint16())
+	_setconfig.MissSendLen = uint16(decoder.ReadUint16())
+	return _setconfig, nil
+}
+
+func NewSetConfig() *SetConfig {
+	obj := &SetConfig{
+		Header: NewHeader(9),
+	}
+	return obj
+}
+
+type 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(22),
+	}
+	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
+	}
+
+	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}
+
+	for decoder.Length() >= 64 {
+		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
+	}
+	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}
+	return _tablestatsrequest, nil
+}
+
+func NewTableStatsRequest() *TableStatsRequest {
+	obj := &TableStatsRequest{
+		StatsRequest: NewStatsRequest(3),
+	}
+	return obj
+}
