diff --git a/vendor/github.com/opencord/goloxi/of13/instruction.go b/vendor/github.com/opencord/goloxi/of13/instruction.go
new file mode 100644
index 0000000..28dc5fc
--- /dev/null
+++ b/vendor/github.com/opencord/goloxi/of13/instruction.go
@@ -0,0 +1,1214 @@
+/*
+ * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
+ * Copyright (c) 2011, 2012 Open Networking Foundation
+ * Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler.
+ * Copyright 2018, Red Hat, Inc.
+ */
+// Automatically generated by LOXI from template module.go
+// Do not modify
+
+package of13
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+
+	"github.com/opencord/goloxi"
+)
+
+type Instruction struct {
+	Type uint16
+	Len  uint16
+}
+
+type IInstruction interface {
+	goloxi.Serializable
+	GetType() uint16
+	GetLen() uint16
+}
+
+func (self *Instruction) GetType() uint16 {
+	return self.Type
+}
+
+func (self *Instruction) SetType(v uint16) {
+	self.Type = v
+}
+
+func (self *Instruction) GetLen() uint16 {
+	return self.Len
+}
+
+func (self *Instruction) SetLen(v uint16) {
+	self.Len = v
+}
+
+func (self *Instruction) Serialize(encoder *goloxi.Encoder) error {
+
+	encoder.PutUint16(uint16(self.Type))
+	encoder.PutUint16(uint16(self.Len))
+
+	return nil
+}
+
+func DecodeInstruction(decoder *goloxi.Decoder) (IInstruction, error) {
+	_instruction := &Instruction{}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("Instruction packet too short: %d < 4", decoder.Length())
+	}
+	_instruction.Type = uint16(decoder.ReadUint16())
+	_instruction.Len = uint16(decoder.ReadUint16())
+	oldDecoder := decoder
+	defer func() { decoder = oldDecoder }()
+	decoder = decoder.SliceDecoder(int(_instruction.Len), 2+2)
+
+	switch _instruction.Type {
+	case 1:
+		return DecodeInstructionGotoTable(_instruction, decoder)
+	case 2:
+		return DecodeInstructionWriteMetadata(_instruction, decoder)
+	case 3:
+		return DecodeInstructionWriteActions(_instruction, decoder)
+	case 4:
+		return DecodeInstructionApplyActions(_instruction, decoder)
+	case 5:
+		return DecodeInstructionClearActions(_instruction, decoder)
+	case 6:
+		return DecodeInstructionMeter(_instruction, decoder)
+	case 65535:
+		return DecodeInstructionExperimenter(_instruction, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'Instruction'", _instruction.Type)
+	}
+}
+
+func NewInstruction(_type uint16) *Instruction {
+	obj := &Instruction{}
+	obj.Type = _type
+	return obj
+}
+
+type InstructionApplyActions struct {
+	*Instruction
+	Actions []goloxi.IAction
+}
+
+type IInstructionApplyActions interface {
+	IInstruction
+	GetActions() []goloxi.IAction
+}
+
+func (self *InstructionApplyActions) GetActions() []goloxi.IAction {
+	return self.Actions
+}
+
+func (self *InstructionApplyActions) SetActions(v []goloxi.IAction) {
+	self.Actions = v
+}
+
+func (self *InstructionApplyActions) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Instruction.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Actions {
+		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 DecodeInstructionApplyActions(parent *Instruction, decoder *goloxi.Decoder) (*InstructionApplyActions, error) {
+	_instructionapplyactions := &InstructionApplyActions{Instruction: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionApplyActions packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeAction(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_instructionapplyactions.Actions = append(_instructionapplyactions.Actions, item)
+		}
+	}
+	return _instructionapplyactions, nil
+}
+
+func NewInstructionApplyActions() *InstructionApplyActions {
+	obj := &InstructionApplyActions{
+		Instruction: NewInstruction(4),
+	}
+	return obj
+}
+
+type InstructionExperimenter struct {
+	*Instruction
+	Experimenter uint32
+}
+
+type IInstructionExperimenter interface {
+	IInstruction
+	GetExperimenter() uint32
+}
+
+func (self *InstructionExperimenter) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *InstructionExperimenter) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *InstructionExperimenter) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Instruction.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Experimenter))
+
+	return nil
+}
+
+func DecodeInstructionExperimenter(parent *Instruction, decoder *goloxi.Decoder) (IInstructionExperimenter, error) {
+	_instructionexperimenter := &InstructionExperimenter{Instruction: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionExperimenter packet too short: %d < 4", decoder.Length())
+	}
+	_instructionexperimenter.Experimenter = uint32(decoder.ReadUint32())
+
+	switch _instructionexperimenter.Experimenter {
+	case 6035143:
+		return DecodeInstructionBsn(_instructionexperimenter, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'InstructionExperimenter'", _instructionexperimenter.Experimenter)
+	}
+}
+
+func NewInstructionExperimenter(_experimenter uint32) *InstructionExperimenter {
+	obj := &InstructionExperimenter{
+		Instruction: NewInstruction(65535),
+	}
+	obj.Experimenter = _experimenter
+	return obj
+}
+
+type InstructionBsn struct {
+	*InstructionExperimenter
+	Subtype uint32
+}
+
+type IInstructionBsn interface {
+	IInstructionExperimenter
+	GetSubtype() uint32
+}
+
+func (self *InstructionBsn) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *InstructionBsn) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *InstructionBsn) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.InstructionExperimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeInstructionBsn(parent *InstructionExperimenter, decoder *goloxi.Decoder) (IInstructionBsn, error) {
+	_instructionbsn := &InstructionBsn{InstructionExperimenter: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsn packet too short: %d < 4", decoder.Length())
+	}
+	_instructionbsn.Subtype = uint32(decoder.ReadUint32())
+
+	switch _instructionbsn.Subtype {
+	case 0:
+		return DecodeInstructionBsnDisableSrcMacCheck(_instructionbsn, decoder)
+	case 1:
+		return DecodeInstructionBsnArpOffload(_instructionbsn, decoder)
+	case 2:
+		return DecodeInstructionBsnDhcpOffload(_instructionbsn, decoder)
+	case 3:
+		return DecodeInstructionBsnDisableSplitHorizonCheck(_instructionbsn, decoder)
+	case 4:
+		return DecodeInstructionBsnPermit(_instructionbsn, decoder)
+	case 5:
+		return DecodeInstructionBsnDeny(_instructionbsn, decoder)
+	case 6:
+		return DecodeInstructionBsnPacketOfDeath(_instructionbsn, decoder)
+	case 7:
+		return DecodeInstructionBsnPrioritizePdus(_instructionbsn, decoder)
+	case 8:
+		return DecodeInstructionBsnRequireVlanXlate(_instructionbsn, decoder)
+	case 9:
+		return DecodeInstructionBsnDisableVlanCounters(_instructionbsn, decoder)
+	case 10:
+		return DecodeInstructionBsnSpanDestination(_instructionbsn, decoder)
+	case 11:
+		return DecodeInstructionBsnAutoNegotiation(_instructionbsn, decoder)
+	case 12:
+		return DecodeInstructionBsnInternalPriority(_instructionbsn, decoder)
+	case 13:
+		return DecodeInstructionBsnDisableL3(_instructionbsn, decoder)
+	case 14:
+		return DecodeInstructionBsnNdpOffload(_instructionbsn, decoder)
+	case 15:
+		return DecodeInstructionBsnHashSelect(_instructionbsn, decoder)
+	case 16:
+		return DecodeInstructionBsnDirectedBroadcast(_instructionbsn, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'InstructionBsn'", _instructionbsn.Subtype)
+	}
+}
+
+func NewInstructionBsn(_subtype uint32) *InstructionBsn {
+	obj := &InstructionBsn{
+		InstructionExperimenter: NewInstructionExperimenter(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+
+type InstructionBsnArpOffload struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnArpOffload interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnArpOffload) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnArpOffload(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnArpOffload, error) {
+	_instructionbsnarpoffload := &InstructionBsnArpOffload{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnArpOffload packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsnarpoffload, nil
+}
+
+func NewInstructionBsnArpOffload() *InstructionBsnArpOffload {
+	obj := &InstructionBsnArpOffload{
+		InstructionBsn: NewInstructionBsn(1),
+	}
+	return obj
+}
+
+type InstructionBsnAutoNegotiation struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnAutoNegotiation interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnAutoNegotiation) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnAutoNegotiation(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnAutoNegotiation, error) {
+	_instructionbsnautonegotiation := &InstructionBsnAutoNegotiation{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnAutoNegotiation packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsnautonegotiation, nil
+}
+
+func NewInstructionBsnAutoNegotiation() *InstructionBsnAutoNegotiation {
+	obj := &InstructionBsnAutoNegotiation{
+		InstructionBsn: NewInstructionBsn(11),
+	}
+	return obj
+}
+
+type InstructionBsnDeny struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnDeny interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnDeny) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnDeny(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDeny, error) {
+	_instructionbsndeny := &InstructionBsnDeny{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnDeny packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsndeny, nil
+}
+
+func NewInstructionBsnDeny() *InstructionBsnDeny {
+	obj := &InstructionBsnDeny{
+		InstructionBsn: NewInstructionBsn(5),
+	}
+	return obj
+}
+
+type InstructionBsnDhcpOffload struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnDhcpOffload interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnDhcpOffload) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnDhcpOffload(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDhcpOffload, error) {
+	_instructionbsndhcpoffload := &InstructionBsnDhcpOffload{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnDhcpOffload packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsndhcpoffload, nil
+}
+
+func NewInstructionBsnDhcpOffload() *InstructionBsnDhcpOffload {
+	obj := &InstructionBsnDhcpOffload{
+		InstructionBsn: NewInstructionBsn(2),
+	}
+	return obj
+}
+
+type InstructionBsnDirectedBroadcast struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnDirectedBroadcast interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnDirectedBroadcast) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnDirectedBroadcast(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDirectedBroadcast, error) {
+	_instructionbsndirectedbroadcast := &InstructionBsnDirectedBroadcast{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnDirectedBroadcast packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsndirectedbroadcast, nil
+}
+
+func NewInstructionBsnDirectedBroadcast() *InstructionBsnDirectedBroadcast {
+	obj := &InstructionBsnDirectedBroadcast{
+		InstructionBsn: NewInstructionBsn(16),
+	}
+	return obj
+}
+
+type InstructionBsnDisableL3 struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnDisableL3 interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnDisableL3) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnDisableL3(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDisableL3, error) {
+	_instructionbsndisablel3 := &InstructionBsnDisableL3{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnDisableL3 packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsndisablel3, nil
+}
+
+func NewInstructionBsnDisableL3() *InstructionBsnDisableL3 {
+	obj := &InstructionBsnDisableL3{
+		InstructionBsn: NewInstructionBsn(13),
+	}
+	return obj
+}
+
+type InstructionBsnDisableSplitHorizonCheck struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnDisableSplitHorizonCheck interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnDisableSplitHorizonCheck) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnDisableSplitHorizonCheck(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDisableSplitHorizonCheck, error) {
+	_instructionbsndisablesplithorizoncheck := &InstructionBsnDisableSplitHorizonCheck{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnDisableSplitHorizonCheck packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsndisablesplithorizoncheck, nil
+}
+
+func NewInstructionBsnDisableSplitHorizonCheck() *InstructionBsnDisableSplitHorizonCheck {
+	obj := &InstructionBsnDisableSplitHorizonCheck{
+		InstructionBsn: NewInstructionBsn(3),
+	}
+	return obj
+}
+
+type InstructionBsnDisableSrcMacCheck struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnDisableSrcMacCheck interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnDisableSrcMacCheck) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnDisableSrcMacCheck(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDisableSrcMacCheck, error) {
+	_instructionbsndisablesrcmaccheck := &InstructionBsnDisableSrcMacCheck{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnDisableSrcMacCheck packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsndisablesrcmaccheck, nil
+}
+
+func NewInstructionBsnDisableSrcMacCheck() *InstructionBsnDisableSrcMacCheck {
+	obj := &InstructionBsnDisableSrcMacCheck{
+		InstructionBsn: NewInstructionBsn(0),
+	}
+	return obj
+}
+
+type InstructionBsnDisableVlanCounters struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnDisableVlanCounters interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnDisableVlanCounters) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnDisableVlanCounters(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnDisableVlanCounters, error) {
+	_instructionbsndisablevlancounters := &InstructionBsnDisableVlanCounters{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnDisableVlanCounters packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsndisablevlancounters, nil
+}
+
+func NewInstructionBsnDisableVlanCounters() *InstructionBsnDisableVlanCounters {
+	obj := &InstructionBsnDisableVlanCounters{
+		InstructionBsn: NewInstructionBsn(9),
+	}
+	return obj
+}
+
+type InstructionBsnHashSelect struct {
+	*InstructionBsn
+	Flags BsnHashSelectFlags
+}
+
+type IInstructionBsnHashSelect interface {
+	IInstructionBsn
+	GetFlags() BsnHashSelectFlags
+}
+
+func (self *InstructionBsnHashSelect) GetFlags() BsnHashSelectFlags {
+	return self.Flags
+}
+
+func (self *InstructionBsnHashSelect) SetFlags(v BsnHashSelectFlags) {
+	self.Flags = v
+}
+
+func (self *InstructionBsnHashSelect) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Flags))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnHashSelect(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnHashSelect, error) {
+	_instructionbsnhashselect := &InstructionBsnHashSelect{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnHashSelect packet too short: %d < 4", decoder.Length())
+	}
+	_instructionbsnhashselect.Flags = BsnHashSelectFlags(decoder.ReadUint32())
+	return _instructionbsnhashselect, nil
+}
+
+func NewInstructionBsnHashSelect() *InstructionBsnHashSelect {
+	obj := &InstructionBsnHashSelect{
+		InstructionBsn: NewInstructionBsn(15),
+	}
+	return obj
+}
+
+type InstructionBsnInternalPriority struct {
+	*InstructionBsn
+	Value uint32
+}
+
+type IInstructionBsnInternalPriority interface {
+	IInstructionBsn
+	GetValue() uint32
+}
+
+func (self *InstructionBsnInternalPriority) GetValue() uint32 {
+	return self.Value
+}
+
+func (self *InstructionBsnInternalPriority) SetValue(v uint32) {
+	self.Value = v
+}
+
+func (self *InstructionBsnInternalPriority) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Value))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnInternalPriority(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnInternalPriority, error) {
+	_instructionbsninternalpriority := &InstructionBsnInternalPriority{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnInternalPriority packet too short: %d < 4", decoder.Length())
+	}
+	_instructionbsninternalpriority.Value = uint32(decoder.ReadUint32())
+	return _instructionbsninternalpriority, nil
+}
+
+func NewInstructionBsnInternalPriority() *InstructionBsnInternalPriority {
+	obj := &InstructionBsnInternalPriority{
+		InstructionBsn: NewInstructionBsn(12),
+	}
+	return obj
+}
+
+type InstructionBsnNdpOffload struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnNdpOffload interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnNdpOffload) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnNdpOffload(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnNdpOffload, error) {
+	_instructionbsnndpoffload := &InstructionBsnNdpOffload{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnNdpOffload packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsnndpoffload, nil
+}
+
+func NewInstructionBsnNdpOffload() *InstructionBsnNdpOffload {
+	obj := &InstructionBsnNdpOffload{
+		InstructionBsn: NewInstructionBsn(14),
+	}
+	return obj
+}
+
+type InstructionBsnPacketOfDeath struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnPacketOfDeath interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnPacketOfDeath) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnPacketOfDeath(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnPacketOfDeath, error) {
+	_instructionbsnpacketofdeath := &InstructionBsnPacketOfDeath{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnPacketOfDeath packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsnpacketofdeath, nil
+}
+
+func NewInstructionBsnPacketOfDeath() *InstructionBsnPacketOfDeath {
+	obj := &InstructionBsnPacketOfDeath{
+		InstructionBsn: NewInstructionBsn(6),
+	}
+	return obj
+}
+
+type InstructionBsnPermit struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnPermit interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnPermit) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnPermit(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnPermit, error) {
+	_instructionbsnpermit := &InstructionBsnPermit{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnPermit packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsnpermit, nil
+}
+
+func NewInstructionBsnPermit() *InstructionBsnPermit {
+	obj := &InstructionBsnPermit{
+		InstructionBsn: NewInstructionBsn(4),
+	}
+	return obj
+}
+
+type InstructionBsnPrioritizePdus struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnPrioritizePdus interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnPrioritizePdus) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnPrioritizePdus(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnPrioritizePdus, error) {
+	_instructionbsnprioritizepdus := &InstructionBsnPrioritizePdus{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnPrioritizePdus packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsnprioritizepdus, nil
+}
+
+func NewInstructionBsnPrioritizePdus() *InstructionBsnPrioritizePdus {
+	obj := &InstructionBsnPrioritizePdus{
+		InstructionBsn: NewInstructionBsn(7),
+	}
+	return obj
+}
+
+type InstructionBsnRequireVlanXlate struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnRequireVlanXlate interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnRequireVlanXlate) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnRequireVlanXlate(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnRequireVlanXlate, error) {
+	_instructionbsnrequirevlanxlate := &InstructionBsnRequireVlanXlate{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnRequireVlanXlate packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsnrequirevlanxlate, nil
+}
+
+func NewInstructionBsnRequireVlanXlate() *InstructionBsnRequireVlanXlate {
+	obj := &InstructionBsnRequireVlanXlate{
+		InstructionBsn: NewInstructionBsn(8),
+	}
+	return obj
+}
+
+type InstructionBsnSpanDestination struct {
+	*InstructionBsn
+}
+
+type IInstructionBsnSpanDestination interface {
+	IInstructionBsn
+}
+
+func (self *InstructionBsnSpanDestination) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.InstructionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionBsnSpanDestination(parent *InstructionBsn, decoder *goloxi.Decoder) (*InstructionBsnSpanDestination, error) {
+	_instructionbsnspandestination := &InstructionBsnSpanDestination{InstructionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionBsnSpanDestination packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionbsnspandestination, nil
+}
+
+func NewInstructionBsnSpanDestination() *InstructionBsnSpanDestination {
+	obj := &InstructionBsnSpanDestination{
+		InstructionBsn: NewInstructionBsn(10),
+	}
+	return obj
+}
+
+type InstructionClearActions struct {
+	*Instruction
+}
+
+type IInstructionClearActions interface {
+	IInstruction
+}
+
+func (self *InstructionClearActions) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Instruction.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionClearActions(parent *Instruction, decoder *goloxi.Decoder) (*InstructionClearActions, error) {
+	_instructionclearactions := &InstructionClearActions{Instruction: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionClearActions packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _instructionclearactions, nil
+}
+
+func NewInstructionClearActions() *InstructionClearActions {
+	obj := &InstructionClearActions{
+		Instruction: NewInstruction(5),
+	}
+	return obj
+}
+
+type InstructionGotoTable struct {
+	*Instruction
+	TableId uint8
+}
+
+type IInstructionGotoTable interface {
+	IInstruction
+	GetTableId() uint8
+}
+
+func (self *InstructionGotoTable) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *InstructionGotoTable) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *InstructionGotoTable) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Instruction.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeInstructionGotoTable(parent *Instruction, decoder *goloxi.Decoder) (*InstructionGotoTable, error) {
+	_instructiongototable := &InstructionGotoTable{Instruction: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionGotoTable packet too short: %d < 4", decoder.Length())
+	}
+	_instructiongototable.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _instructiongototable, nil
+}
+
+func NewInstructionGotoTable() *InstructionGotoTable {
+	obj := &InstructionGotoTable{
+		Instruction: NewInstruction(1),
+	}
+	return obj
+}
+
+type InstructionMeter struct {
+	*Instruction
+	MeterId uint32
+}
+
+type IInstructionMeter interface {
+	IInstruction
+	GetMeterId() uint32
+}
+
+func (self *InstructionMeter) GetMeterId() uint32 {
+	return self.MeterId
+}
+
+func (self *InstructionMeter) SetMeterId(v uint32) {
+	self.MeterId = v
+}
+
+func (self *InstructionMeter) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Instruction.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.MeterId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionMeter(parent *Instruction, decoder *goloxi.Decoder) (*InstructionMeter, error) {
+	_instructionmeter := &InstructionMeter{Instruction: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionMeter packet too short: %d < 4", decoder.Length())
+	}
+	_instructionmeter.MeterId = uint32(decoder.ReadUint32())
+	return _instructionmeter, nil
+}
+
+func NewInstructionMeter() *InstructionMeter {
+	obj := &InstructionMeter{
+		Instruction: NewInstruction(6),
+	}
+	return obj
+}
+
+type InstructionWriteActions struct {
+	*Instruction
+	Actions []goloxi.IAction
+}
+
+type IInstructionWriteActions interface {
+	IInstruction
+	GetActions() []goloxi.IAction
+}
+
+func (self *InstructionWriteActions) GetActions() []goloxi.IAction {
+	return self.Actions
+}
+
+func (self *InstructionWriteActions) SetActions(v []goloxi.IAction) {
+	self.Actions = v
+}
+
+func (self *InstructionWriteActions) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Instruction.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.Actions {
+		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 DecodeInstructionWriteActions(parent *Instruction, decoder *goloxi.Decoder) (*InstructionWriteActions, error) {
+	_instructionwriteactions := &InstructionWriteActions{Instruction: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("InstructionWriteActions packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeAction(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_instructionwriteactions.Actions = append(_instructionwriteactions.Actions, item)
+		}
+	}
+	return _instructionwriteactions, nil
+}
+
+func NewInstructionWriteActions() *InstructionWriteActions {
+	obj := &InstructionWriteActions{
+		Instruction: NewInstruction(3),
+	}
+	return obj
+}
+
+type InstructionWriteMetadata struct {
+	*Instruction
+	Metadata     uint64
+	MetadataMask uint64
+}
+
+type IInstructionWriteMetadata interface {
+	IInstruction
+	GetMetadata() uint64
+	GetMetadataMask() uint64
+}
+
+func (self *InstructionWriteMetadata) GetMetadata() uint64 {
+	return self.Metadata
+}
+
+func (self *InstructionWriteMetadata) SetMetadata(v uint64) {
+	self.Metadata = v
+}
+
+func (self *InstructionWriteMetadata) GetMetadataMask() uint64 {
+	return self.MetadataMask
+}
+
+func (self *InstructionWriteMetadata) SetMetadataMask(v uint64) {
+	self.MetadataMask = v
+}
+
+func (self *InstructionWriteMetadata) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Instruction.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	encoder.PutUint64(uint64(self.Metadata))
+	encoder.PutUint64(uint64(self.MetadataMask))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeInstructionWriteMetadata(parent *Instruction, decoder *goloxi.Decoder) (*InstructionWriteMetadata, error) {
+	_instructionwritemetadata := &InstructionWriteMetadata{Instruction: parent}
+	if decoder.Length() < 20 {
+		return nil, fmt.Errorf("InstructionWriteMetadata packet too short: %d < 20", decoder.Length())
+	}
+	decoder.Skip(4)
+	_instructionwritemetadata.Metadata = uint64(decoder.ReadUint64())
+	_instructionwritemetadata.MetadataMask = uint64(decoder.ReadUint64())
+	return _instructionwritemetadata, nil
+}
+
+func NewInstructionWriteMetadata() *InstructionWriteMetadata {
+	obj := &InstructionWriteMetadata{
+		Instruction: NewInstruction(2),
+	}
+	return obj
+}
