diff --git a/vendor/github.com/opencord/goloxi/of13/action.go b/vendor/github.com/opencord/goloxi/of13/action.go
new file mode 100644
index 0000000..e89aa7d
--- /dev/null
+++ b/vendor/github.com/opencord/goloxi/of13/action.go
@@ -0,0 +1,6083 @@
+/*
+ * 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"
+	"encoding/json"
+	"fmt"
+	"net"
+
+	"github.com/opencord/goloxi"
+)
+
+type Action struct {
+	Type uint16
+	Len  uint16
+}
+
+type IAction interface {
+	goloxi.Serializable
+	GetType() uint16
+	GetLen() uint16
+	GetActionName() string
+	GetActionFields() map[string]interface{}
+}
+
+func (self *Action) GetType() uint16 {
+	return self.Type
+}
+
+func (self *Action) SetType(v uint16) {
+	self.Type = v
+}
+
+func (self *Action) GetLen() uint16 {
+	return self.Len
+}
+
+func (self *Action) SetLen(v uint16) {
+	self.Len = v
+}
+
+func (self *Action) Serialize(encoder *goloxi.Encoder) error {
+
+	encoder.PutUint16(uint16(self.Type))
+	encoder.PutUint16(uint16(self.Len))
+
+	return nil
+}
+
+func DecodeAction(decoder *goloxi.Decoder) (goloxi.IAction, error) {
+	_action := &Action{}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("Action packet too short: %d < 4", decoder.Length())
+	}
+	_action.Type = uint16(decoder.ReadUint16())
+	_action.Len = uint16(decoder.ReadUint16())
+	oldDecoder := decoder
+	defer func() { decoder = oldDecoder }()
+	decoder = decoder.SliceDecoder(int(_action.Len), 2+2)
+
+	switch _action.Type {
+	case 0:
+		return DecodeActionOutput(_action, decoder)
+	case 11:
+		return DecodeActionCopyTtlOut(_action, decoder)
+	case 12:
+		return DecodeActionCopyTtlIn(_action, decoder)
+	case 15:
+		return DecodeActionSetMplsTtl(_action, decoder)
+	case 16:
+		return DecodeActionDecMplsTtl(_action, decoder)
+	case 17:
+		return DecodeActionPushVlan(_action, decoder)
+	case 18:
+		return DecodeActionPopVlan(_action, decoder)
+	case 19:
+		return DecodeActionPushMpls(_action, decoder)
+	case 20:
+		return DecodeActionPopMpls(_action, decoder)
+	case 21:
+		return DecodeActionSetQueue(_action, decoder)
+	case 22:
+		return DecodeActionGroup(_action, decoder)
+	case 23:
+		return DecodeActionSetNwTtl(_action, decoder)
+	case 24:
+		return DecodeActionDecNwTtl(_action, decoder)
+	case 25:
+		return DecodeActionSetField(_action, decoder)
+	case 26:
+		return DecodeActionPushPbb(_action, decoder)
+	case 27:
+		return DecodeActionPopPbb(_action, decoder)
+	case 65535:
+		return DecodeActionExperimenter(_action, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'Action'", _action.Type)
+	}
+}
+
+func NewAction(_type uint16) *Action {
+	obj := &Action{}
+	obj.Type = _type
+	return obj
+}
+
+type ActionExperimenter struct {
+	*Action
+	Experimenter uint32
+}
+
+type IActionExperimenter interface {
+	goloxi.IAction
+	GetExperimenter() uint32
+}
+
+func (self *ActionExperimenter) GetExperimenter() uint32 {
+	return self.Experimenter
+}
+
+func (self *ActionExperimenter) SetExperimenter(v uint32) {
+	self.Experimenter = v
+}
+
+func (self *ActionExperimenter) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Experimenter))
+
+	return nil
+}
+
+func DecodeActionExperimenter(parent *Action, decoder *goloxi.Decoder) (IActionExperimenter, error) {
+	_actionexperimenter := &ActionExperimenter{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionExperimenter packet too short: %d < 4", decoder.Length())
+	}
+	_actionexperimenter.Experimenter = uint32(decoder.ReadUint32())
+
+	switch _actionexperimenter.Experimenter {
+	case 8992:
+		return DecodeActionNicira(_actionexperimenter, decoder)
+	case 6035143:
+		return DecodeActionBsn(_actionexperimenter, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'ActionExperimenter'", _actionexperimenter.Experimenter)
+	}
+}
+
+func NewActionExperimenter(_experimenter uint32) *ActionExperimenter {
+	obj := &ActionExperimenter{
+		Action: NewAction(65535),
+	}
+	obj.Experimenter = _experimenter
+	return obj
+}
+func (self *ActionExperimenter) GetActionName() string {
+	return "experimenter"
+}
+
+func (self *ActionExperimenter) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Experimenter": self.Experimenter,
+	}
+}
+
+func (self *ActionExperimenter) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionBsn struct {
+	*ActionExperimenter
+	Subtype uint32
+}
+
+type IActionBsn interface {
+	IActionExperimenter
+	GetSubtype() uint32
+}
+
+func (self *ActionBsn) GetSubtype() uint32 {
+	return self.Subtype
+}
+
+func (self *ActionBsn) SetSubtype(v uint32) {
+	self.Subtype = v
+}
+
+func (self *ActionBsn) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ActionExperimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Subtype))
+
+	return nil
+}
+
+func DecodeActionBsn(parent *ActionExperimenter, decoder *goloxi.Decoder) (IActionBsn, error) {
+	_actionbsn := &ActionBsn{ActionExperimenter: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionBsn packet too short: %d < 4", decoder.Length())
+	}
+	_actionbsn.Subtype = uint32(decoder.ReadUint32())
+
+	switch _actionbsn.Subtype {
+	case 1:
+		return DecodeActionBsnMirror(_actionbsn, decoder)
+	case 2:
+		return DecodeActionBsnSetTunnelDst(_actionbsn, decoder)
+	case 4:
+		return DecodeActionBsnChecksum(_actionbsn, decoder)
+	case 5:
+		return DecodeActionBsnGentable(_actionbsn, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'ActionBsn'", _actionbsn.Subtype)
+	}
+}
+
+func NewActionBsn(_subtype uint32) *ActionBsn {
+	obj := &ActionBsn{
+		ActionExperimenter: NewActionExperimenter(6035143),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+func (self *ActionBsn) GetActionName() string {
+	return "bsn"
+}
+
+func (self *ActionBsn) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Subtype": self.Subtype,
+	}
+}
+
+func (self *ActionBsn) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionBsnChecksum struct {
+	*ActionBsn
+	Checksum Checksum128
+}
+
+type IActionBsnChecksum interface {
+	IActionBsn
+	GetChecksum() Checksum128
+}
+
+func (self *ActionBsnChecksum) GetChecksum() Checksum128 {
+	return self.Checksum
+}
+
+func (self *ActionBsnChecksum) SetChecksum(v Checksum128) {
+	self.Checksum = v
+}
+
+func (self *ActionBsnChecksum) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.Checksum.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionBsnChecksum(parent *ActionBsn, decoder *goloxi.Decoder) (*ActionBsnChecksum, error) {
+	_actionbsnchecksum := &ActionBsnChecksum{ActionBsn: parent}
+	if decoder.Length() < 16 {
+		return nil, fmt.Errorf("ActionBsnChecksum packet too short: %d < 16", decoder.Length())
+	}
+	_actionbsnchecksum.Checksum.Decode(decoder)
+	return _actionbsnchecksum, nil
+}
+
+func NewActionBsnChecksum() *ActionBsnChecksum {
+	obj := &ActionBsnChecksum{
+		ActionBsn: NewActionBsn(4),
+	}
+	return obj
+}
+func (self *ActionBsnChecksum) GetActionName() string {
+	return "bsn_checksum"
+}
+
+func (self *ActionBsnChecksum) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Checksum": self.Checksum,
+	}
+}
+
+func (self *ActionBsnChecksum) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionBsnGentable struct {
+	*ActionBsn
+	TableId uint32
+	Key     []IBsnTlv
+}
+
+type IActionBsnGentable interface {
+	IActionBsn
+	GetTableId() uint32
+	GetKey() []IBsnTlv
+}
+
+func (self *ActionBsnGentable) GetTableId() uint32 {
+	return self.TableId
+}
+
+func (self *ActionBsnGentable) SetTableId(v uint32) {
+	self.TableId = v
+}
+
+func (self *ActionBsnGentable) GetKey() []IBsnTlv {
+	return self.Key
+}
+
+func (self *ActionBsnGentable) SetKey(v []IBsnTlv) {
+	self.Key = v
+}
+
+func (self *ActionBsnGentable) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.TableId))
+	for _, obj := range self.Key {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionBsnGentable(parent *ActionBsn, decoder *goloxi.Decoder) (*ActionBsnGentable, error) {
+	_actionbsngentable := &ActionBsnGentable{ActionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionBsnGentable packet too short: %d < 4", decoder.Length())
+	}
+	_actionbsngentable.TableId = uint32(decoder.ReadUint32())
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeBsnTlv(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_actionbsngentable.Key = append(_actionbsngentable.Key, item)
+		}
+	}
+	return _actionbsngentable, nil
+}
+
+func NewActionBsnGentable() *ActionBsnGentable {
+	obj := &ActionBsnGentable{
+		ActionBsn: NewActionBsn(5),
+	}
+	return obj
+}
+func (self *ActionBsnGentable) GetActionName() string {
+	return "bsn_gentable"
+}
+
+func (self *ActionBsnGentable) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"TableId": self.TableId,
+		"Key":     self.Key,
+	}
+}
+
+func (self *ActionBsnGentable) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionBsnMirror struct {
+	*ActionBsn
+	DestPort  uint32
+	VlanTag   uint32
+	CopyStage uint8
+}
+
+type IActionBsnMirror interface {
+	IActionBsn
+	GetDestPort() uint32
+	GetVlanTag() uint32
+	GetCopyStage() uint8
+}
+
+func (self *ActionBsnMirror) GetDestPort() uint32 {
+	return self.DestPort
+}
+
+func (self *ActionBsnMirror) SetDestPort(v uint32) {
+	self.DestPort = v
+}
+
+func (self *ActionBsnMirror) GetVlanTag() uint32 {
+	return self.VlanTag
+}
+
+func (self *ActionBsnMirror) SetVlanTag(v uint32) {
+	self.VlanTag = v
+}
+
+func (self *ActionBsnMirror) GetCopyStage() uint8 {
+	return self.CopyStage
+}
+
+func (self *ActionBsnMirror) SetCopyStage(v uint8) {
+	self.CopyStage = v
+}
+
+func (self *ActionBsnMirror) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.DestPort))
+	encoder.PutUint32(uint32(self.VlanTag))
+	encoder.PutUint8(uint8(self.CopyStage))
+	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 DecodeActionBsnMirror(parent *ActionBsn, decoder *goloxi.Decoder) (*ActionBsnMirror, error) {
+	_actionbsnmirror := &ActionBsnMirror{ActionBsn: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("ActionBsnMirror packet too short: %d < 12", decoder.Length())
+	}
+	_actionbsnmirror.DestPort = uint32(decoder.ReadUint32())
+	_actionbsnmirror.VlanTag = uint32(decoder.ReadUint32())
+	_actionbsnmirror.CopyStage = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _actionbsnmirror, nil
+}
+
+func NewActionBsnMirror() *ActionBsnMirror {
+	obj := &ActionBsnMirror{
+		ActionBsn: NewActionBsn(1),
+	}
+	return obj
+}
+func (self *ActionBsnMirror) GetActionName() string {
+	return "bsn_mirror"
+}
+
+func (self *ActionBsnMirror) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"DestPort":  self.DestPort,
+		"VlanTag":   self.VlanTag,
+		"CopyStage": self.CopyStage,
+	}
+}
+
+func (self *ActionBsnMirror) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionBsnSetTunnelDst struct {
+	*ActionBsn
+	Dst uint32
+}
+
+type IActionBsnSetTunnelDst interface {
+	IActionBsn
+	GetDst() uint32
+}
+
+func (self *ActionBsnSetTunnelDst) GetDst() uint32 {
+	return self.Dst
+}
+
+func (self *ActionBsnSetTunnelDst) SetDst(v uint32) {
+	self.Dst = v
+}
+
+func (self *ActionBsnSetTunnelDst) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionBsn.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.Dst))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionBsnSetTunnelDst(parent *ActionBsn, decoder *goloxi.Decoder) (*ActionBsnSetTunnelDst, error) {
+	_actionbsnsettunneldst := &ActionBsnSetTunnelDst{ActionBsn: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionBsnSetTunnelDst packet too short: %d < 4", decoder.Length())
+	}
+	_actionbsnsettunneldst.Dst = uint32(decoder.ReadUint32())
+	return _actionbsnsettunneldst, nil
+}
+
+func NewActionBsnSetTunnelDst() *ActionBsnSetTunnelDst {
+	obj := &ActionBsnSetTunnelDst{
+		ActionBsn: NewActionBsn(2),
+	}
+	return obj
+}
+func (self *ActionBsnSetTunnelDst) GetActionName() string {
+	return "bsn_set_tunnel_dst"
+}
+
+func (self *ActionBsnSetTunnelDst) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Dst": self.Dst,
+	}
+}
+
+func (self *ActionBsnSetTunnelDst) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionCopyTtlIn struct {
+	*Action
+}
+
+type IActionCopyTtlIn interface {
+	goloxi.IAction
+}
+
+func (self *ActionCopyTtlIn) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.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 DecodeActionCopyTtlIn(parent *Action, decoder *goloxi.Decoder) (*ActionCopyTtlIn, error) {
+	_actioncopyttlin := &ActionCopyTtlIn{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionCopyTtlIn packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _actioncopyttlin, nil
+}
+
+func NewActionCopyTtlIn() *ActionCopyTtlIn {
+	obj := &ActionCopyTtlIn{
+		Action: NewAction(12),
+	}
+	return obj
+}
+func (self *ActionCopyTtlIn) GetActionName() string {
+	return "copy_ttl_in"
+}
+
+func (self *ActionCopyTtlIn) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionCopyTtlIn) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionCopyTtlOut struct {
+	*Action
+}
+
+type IActionCopyTtlOut interface {
+	goloxi.IAction
+}
+
+func (self *ActionCopyTtlOut) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.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 DecodeActionCopyTtlOut(parent *Action, decoder *goloxi.Decoder) (*ActionCopyTtlOut, error) {
+	_actioncopyttlout := &ActionCopyTtlOut{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionCopyTtlOut packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _actioncopyttlout, nil
+}
+
+func NewActionCopyTtlOut() *ActionCopyTtlOut {
+	obj := &ActionCopyTtlOut{
+		Action: NewAction(11),
+	}
+	return obj
+}
+func (self *ActionCopyTtlOut) GetActionName() string {
+	return "copy_ttl_out"
+}
+
+func (self *ActionCopyTtlOut) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionCopyTtlOut) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionDecMplsTtl struct {
+	*Action
+}
+
+type IActionDecMplsTtl interface {
+	goloxi.IAction
+}
+
+func (self *ActionDecMplsTtl) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.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 DecodeActionDecMplsTtl(parent *Action, decoder *goloxi.Decoder) (*ActionDecMplsTtl, error) {
+	_actiondecmplsttl := &ActionDecMplsTtl{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionDecMplsTtl packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _actiondecmplsttl, nil
+}
+
+func NewActionDecMplsTtl() *ActionDecMplsTtl {
+	obj := &ActionDecMplsTtl{
+		Action: NewAction(16),
+	}
+	return obj
+}
+func (self *ActionDecMplsTtl) GetActionName() string {
+	return "dec_mpls_ttl"
+}
+
+func (self *ActionDecMplsTtl) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionDecMplsTtl) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionDecNwTtl struct {
+	*Action
+}
+
+type IActionDecNwTtl interface {
+	goloxi.IAction
+}
+
+func (self *ActionDecNwTtl) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.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 DecodeActionDecNwTtl(parent *Action, decoder *goloxi.Decoder) (*ActionDecNwTtl, error) {
+	_actiondecnwttl := &ActionDecNwTtl{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionDecNwTtl packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _actiondecnwttl, nil
+}
+
+func NewActionDecNwTtl() *ActionDecNwTtl {
+	obj := &ActionDecNwTtl{
+		Action: NewAction(24),
+	}
+	return obj
+}
+func (self *ActionDecNwTtl) GetActionName() string {
+	return "dec_nw_ttl"
+}
+
+func (self *ActionDecNwTtl) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionDecNwTtl) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionGroup struct {
+	*Action
+	GroupId uint32
+}
+
+type IActionGroup interface {
+	goloxi.IAction
+	GetGroupId() uint32
+}
+
+func (self *ActionGroup) GetGroupId() uint32 {
+	return self.GroupId
+}
+
+func (self *ActionGroup) SetGroupId(v uint32) {
+	self.GroupId = v
+}
+
+func (self *ActionGroup) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.GroupId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionGroup(parent *Action, decoder *goloxi.Decoder) (*ActionGroup, error) {
+	_actiongroup := &ActionGroup{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionGroup packet too short: %d < 4", decoder.Length())
+	}
+	_actiongroup.GroupId = uint32(decoder.ReadUint32())
+	return _actiongroup, nil
+}
+
+func NewActionGroup() *ActionGroup {
+	obj := &ActionGroup{
+		Action: NewAction(22),
+	}
+	return obj
+}
+func (self *ActionGroup) GetActionName() string {
+	return "group"
+}
+
+func (self *ActionGroup) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"GroupId": self.GroupId,
+	}
+}
+
+func (self *ActionGroup) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNicira struct {
+	*ActionExperimenter
+	Subtype uint16
+}
+
+type IActionNicira interface {
+	IActionExperimenter
+	GetSubtype() uint16
+}
+
+func (self *ActionNicira) GetSubtype() uint16 {
+	return self.Subtype
+}
+
+func (self *ActionNicira) SetSubtype(v uint16) {
+	self.Subtype = v
+}
+
+func (self *ActionNicira) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ActionExperimenter.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Subtype))
+
+	return nil
+}
+
+func DecodeActionNicira(parent *ActionExperimenter, decoder *goloxi.Decoder) (IActionNicira, error) {
+	_actionnicira := &ActionNicira{ActionExperimenter: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("ActionNicira packet too short: %d < 2", decoder.Length())
+	}
+	_actionnicira.Subtype = uint16(decoder.ReadUint16())
+
+	switch _actionnicira.Subtype {
+	case 1:
+		return DecodeActionNxResubmit(_actionnicira, decoder)
+	case 2:
+		return DecodeActionNxSetTunnel(_actionnicira, decoder)
+	case 4:
+		return DecodeActionNxSetQueue(_actionnicira, decoder)
+	case 5:
+		return DecodeActionNxPopQueue(_actionnicira, decoder)
+	case 6:
+		return DecodeActionNxRegMove(_actionnicira, decoder)
+	case 7:
+		return DecodeActionNxRegLoad(_actionnicira, decoder)
+	case 8:
+		return DecodeActionNxNote(_actionnicira, decoder)
+	case 9:
+		return DecodeActionNxSetTunnel64(_actionnicira, decoder)
+	case 10:
+		return DecodeActionNxMultipath(_actionnicira, decoder)
+	case 12:
+		return DecodeActionNxBundle(_actionnicira, decoder)
+	case 13:
+		return DecodeActionNxBundleLoadInPort(_actionnicira, decoder)
+	case 14:
+		return DecodeActionResubmit(_actionnicira, decoder)
+	case 15:
+		return DecodeActionNxOutputReg(_actionnicira, decoder)
+	case 16:
+		return DecodeActionNxLearn(_actionnicira, decoder)
+	case 17:
+		return DecodeActionNxExit(_actionnicira, decoder)
+	case 18:
+		return DecodeActionNiciraDecTtl(_actionnicira, decoder)
+	case 19:
+		return DecodeActionNxFinTimeout(_actionnicira, decoder)
+	case 20:
+		return DecodeActionNxController(_actionnicira, decoder)
+	case 21:
+		return DecodeActionNxDecTtlCntIds(_actionnicira, decoder)
+	case 22:
+		return DecodeActionNxWriteMetadata(_actionnicira, decoder)
+	case 23:
+		return DecodeActionNxPushMpls(_actionnicira, decoder)
+	case 24:
+		return DecodeActionNxPopMpls(_actionnicira, decoder)
+	case 25:
+		return DecodeActionNxSetMplsTtl(_actionnicira, decoder)
+	case 26:
+		return DecodeActionNxDecMplsTtl(_actionnicira, decoder)
+	case 27:
+		return DecodeActionNxStackPush(_actionnicira, decoder)
+	case 28:
+		return DecodeActionNxStackPop(_actionnicira, decoder)
+	case 29:
+		return DecodeActionNxSample(_actionnicira, decoder)
+	case 30:
+		return DecodeActionNxSetMplsLabel(_actionnicira, decoder)
+	case 31:
+		return DecodeActionNxSetMplsTc(_actionnicira, decoder)
+	case 32:
+		return DecodeActionNxOutputReg2(_actionnicira, decoder)
+	case 33:
+		return DecodeActionNxRegLoad2(_actionnicira, decoder)
+	case 34:
+		return DecodeActionNxConjunction(_actionnicira, decoder)
+	case 35:
+		return DecodeActionNxCt(_actionnicira, decoder)
+	case 36:
+		return DecodeActionNxNat(_actionnicira, decoder)
+	case 37:
+		return DecodeActionNxController2(_actionnicira, decoder)
+	case 38:
+		return DecodeActionNxSample2(_actionnicira, decoder)
+	case 39:
+		return DecodeActionNxOutputTrunc(_actionnicira, decoder)
+	case 40:
+		return DecodeActionNxGroup(_actionnicira, decoder)
+	case 41:
+		return DecodeActionNxSample3(_actionnicira, decoder)
+	case 42:
+		return DecodeActionNxClone(_actionnicira, decoder)
+	case 43:
+		return DecodeActionNxCtClear(_actionnicira, decoder)
+	case 44:
+		return DecodeActionNxResubmitTableCt(_actionnicira, decoder)
+	case 45:
+		return DecodeActionNxLearn2(_actionnicira, decoder)
+	case 46:
+		return DecodeActionNxEncap(_actionnicira, decoder)
+	case 47:
+		return DecodeActionNxDecap(_actionnicira, decoder)
+	case 48:
+		return DecodeActionNxDecNshTtl(_actionnicira, decoder)
+	case 254:
+		return DecodeActionNxDebugSlow(_actionnicira, decoder)
+	case 255:
+		return DecodeActionNxDebugRecirc(_actionnicira, decoder)
+	default:
+		return nil, fmt.Errorf("Invalid type '%d' for 'ActionNicira'", _actionnicira.Subtype)
+	}
+}
+
+func NewActionNicira(_subtype uint16) *ActionNicira {
+	obj := &ActionNicira{
+		ActionExperimenter: NewActionExperimenter(8992),
+	}
+	obj.Subtype = _subtype
+	return obj
+}
+func (self *ActionNicira) GetActionName() string {
+	return "nicira"
+}
+
+func (self *ActionNicira) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Subtype": self.Subtype,
+	}
+}
+
+func (self *ActionNicira) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNiciraDecTtl struct {
+	*ActionNicira
+}
+
+type IActionNiciraDecTtl interface {
+	IActionNicira
+}
+
+func (self *ActionNiciraDecTtl) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	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 DecodeActionNiciraDecTtl(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNiciraDecTtl, error) {
+	_actionniciradecttl := &ActionNiciraDecTtl{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNiciraDecTtl packet too short: %d < 6", decoder.Length())
+	}
+	decoder.Skip(2)
+	decoder.Skip(4)
+	return _actionniciradecttl, nil
+}
+
+func NewActionNiciraDecTtl() *ActionNiciraDecTtl {
+	obj := &ActionNiciraDecTtl{
+		ActionNicira: NewActionNicira(18),
+	}
+	return obj
+}
+func (self *ActionNiciraDecTtl) GetActionName() string {
+	return "nicira_dec_ttl"
+}
+
+func (self *ActionNiciraDecTtl) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNiciraDecTtl) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxBundle struct {
+	*ActionNicira
+	Algorithm uint16
+	Fields    NxHashFields
+	Basis     uint16
+	SlaveType ActionNxBundleSlaveType
+	NSlaves   uint16
+	OfsNbits  uint16
+	Dst       goloxi.IOxmId
+}
+
+type IActionNxBundle interface {
+	IActionNicira
+	GetAlgorithm() uint16
+	GetFields() NxHashFields
+	GetBasis() uint16
+	GetSlaveType() ActionNxBundleSlaveType
+	GetNSlaves() uint16
+	GetOfsNbits() uint16
+	GetDst() goloxi.IOxmId
+}
+
+func (self *ActionNxBundle) GetAlgorithm() uint16 {
+	return self.Algorithm
+}
+
+func (self *ActionNxBundle) SetAlgorithm(v uint16) {
+	self.Algorithm = v
+}
+
+func (self *ActionNxBundle) GetFields() NxHashFields {
+	return self.Fields
+}
+
+func (self *ActionNxBundle) SetFields(v NxHashFields) {
+	self.Fields = v
+}
+
+func (self *ActionNxBundle) GetBasis() uint16 {
+	return self.Basis
+}
+
+func (self *ActionNxBundle) SetBasis(v uint16) {
+	self.Basis = v
+}
+
+func (self *ActionNxBundle) GetSlaveType() ActionNxBundleSlaveType {
+	return self.SlaveType
+}
+
+func (self *ActionNxBundle) SetSlaveType(v ActionNxBundleSlaveType) {
+	self.SlaveType = v
+}
+
+func (self *ActionNxBundle) GetNSlaves() uint16 {
+	return self.NSlaves
+}
+
+func (self *ActionNxBundle) SetNSlaves(v uint16) {
+	self.NSlaves = v
+}
+
+func (self *ActionNxBundle) GetOfsNbits() uint16 {
+	return self.OfsNbits
+}
+
+func (self *ActionNxBundle) SetOfsNbits(v uint16) {
+	self.OfsNbits = v
+}
+
+func (self *ActionNxBundle) GetDst() goloxi.IOxmId {
+	return self.Dst
+}
+
+func (self *ActionNxBundle) SetDst(v goloxi.IOxmId) {
+	self.Dst = v
+}
+
+func (self *ActionNxBundle) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Algorithm))
+	encoder.PutUint16(uint16(self.Fields))
+	encoder.PutUint16(uint16(self.Basis))
+	encoder.PutUint32(uint32(self.SlaveType))
+	encoder.PutUint16(uint16(self.NSlaves))
+	encoder.PutUint16(uint16(self.OfsNbits))
+	self.Dst.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxBundle(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxBundle, error) {
+	_actionnxbundle := &ActionNxBundle{ActionNicira: parent}
+	if decoder.Length() < 22 {
+		return nil, fmt.Errorf("ActionNxBundle packet too short: %d < 22", decoder.Length())
+	}
+	_actionnxbundle.Algorithm = uint16(decoder.ReadUint16())
+	_actionnxbundle.Fields = NxHashFields(decoder.ReadUint16())
+	_actionnxbundle.Basis = uint16(decoder.ReadUint16())
+	_actionnxbundle.SlaveType = ActionNxBundleSlaveType(decoder.ReadUint32())
+	_actionnxbundle.NSlaves = uint16(decoder.ReadUint16())
+	_actionnxbundle.OfsNbits = uint16(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxbundle.Dst = obj
+	}
+
+	decoder.Skip(4)
+	return _actionnxbundle, nil
+}
+
+func NewActionNxBundle() *ActionNxBundle {
+	obj := &ActionNxBundle{
+		ActionNicira: NewActionNicira(12),
+	}
+	return obj
+}
+func (self *ActionNxBundle) GetActionName() string {
+	return "nx_bundle"
+}
+
+func (self *ActionNxBundle) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Algorithm": self.Algorithm,
+		"Fields":    self.Fields,
+		"Basis":     self.Basis,
+		"SlaveType": self.SlaveType,
+		"NSlaves":   self.NSlaves,
+		"OfsNbits":  self.OfsNbits,
+		"Dst":       self.Dst,
+	}
+}
+
+func (self *ActionNxBundle) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxBundleLoad struct {
+	*ActionNicira
+	Algorithm NxBdAlgorithms
+	Fields    NxHashFields
+	Basis     uint16
+	SlaveType ActionNxBundleSlaveType
+	NSlaves   uint16
+	OfsNbits  uint16
+	Dst       goloxi.IOxmId
+}
+
+type IActionNxBundleLoad interface {
+	IActionNicira
+	GetAlgorithm() NxBdAlgorithms
+	GetFields() NxHashFields
+	GetBasis() uint16
+	GetSlaveType() ActionNxBundleSlaveType
+	GetNSlaves() uint16
+	GetOfsNbits() uint16
+	GetDst() goloxi.IOxmId
+}
+
+func (self *ActionNxBundleLoad) GetAlgorithm() NxBdAlgorithms {
+	return self.Algorithm
+}
+
+func (self *ActionNxBundleLoad) SetAlgorithm(v NxBdAlgorithms) {
+	self.Algorithm = v
+}
+
+func (self *ActionNxBundleLoad) GetFields() NxHashFields {
+	return self.Fields
+}
+
+func (self *ActionNxBundleLoad) SetFields(v NxHashFields) {
+	self.Fields = v
+}
+
+func (self *ActionNxBundleLoad) GetBasis() uint16 {
+	return self.Basis
+}
+
+func (self *ActionNxBundleLoad) SetBasis(v uint16) {
+	self.Basis = v
+}
+
+func (self *ActionNxBundleLoad) GetSlaveType() ActionNxBundleSlaveType {
+	return self.SlaveType
+}
+
+func (self *ActionNxBundleLoad) SetSlaveType(v ActionNxBundleSlaveType) {
+	self.SlaveType = v
+}
+
+func (self *ActionNxBundleLoad) GetNSlaves() uint16 {
+	return self.NSlaves
+}
+
+func (self *ActionNxBundleLoad) SetNSlaves(v uint16) {
+	self.NSlaves = v
+}
+
+func (self *ActionNxBundleLoad) GetOfsNbits() uint16 {
+	return self.OfsNbits
+}
+
+func (self *ActionNxBundleLoad) SetOfsNbits(v uint16) {
+	self.OfsNbits = v
+}
+
+func (self *ActionNxBundleLoad) GetDst() goloxi.IOxmId {
+	return self.Dst
+}
+
+func (self *ActionNxBundleLoad) SetDst(v goloxi.IOxmId) {
+	self.Dst = v
+}
+
+func (self *ActionNxBundleLoad) Serialize(encoder *goloxi.Encoder) error {
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Algorithm))
+	encoder.PutUint16(uint16(self.Fields))
+	encoder.PutUint16(uint16(self.Basis))
+	encoder.PutUint32(uint32(self.SlaveType))
+	encoder.PutUint16(uint16(self.NSlaves))
+	encoder.PutUint16(uint16(self.OfsNbits))
+	self.Dst.Serialize(encoder)
+
+	return nil
+}
+
+func DecodeActionNxBundleLoad(parent *ActionNicira, decoder *goloxi.Decoder) (IActionNxBundleLoad, error) {
+	_actionnxbundleload := &ActionNxBundleLoad{ActionNicira: parent}
+	if decoder.Length() < 18 {
+		return nil, fmt.Errorf("ActionNxBundleLoad packet too short: %d < 18", decoder.Length())
+	}
+	_actionnxbundleload.Algorithm = NxBdAlgorithms(decoder.ReadUint16())
+	_actionnxbundleload.Fields = NxHashFields(decoder.ReadUint16())
+	_actionnxbundleload.Basis = uint16(decoder.ReadUint16())
+	_actionnxbundleload.SlaveType = ActionNxBundleSlaveType(decoder.ReadUint32())
+	_actionnxbundleload.NSlaves = uint16(decoder.ReadUint16())
+	_actionnxbundleload.OfsNbits = uint16(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxbundleload.Dst = obj
+	}
+
+	return _actionnxbundleload, nil
+}
+
+func NewActionNxBundleLoad(_slave_type ActionNxBundleSlaveType) *ActionNxBundleLoad {
+	obj := &ActionNxBundleLoad{
+		ActionNicira: NewActionNicira(13),
+	}
+	obj.SlaveType = _slave_type
+	return obj
+}
+func (self *ActionNxBundleLoad) GetActionName() string {
+	return "nx_bundle_load"
+}
+
+func (self *ActionNxBundleLoad) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Algorithm": self.Algorithm,
+		"Fields":    self.Fields,
+		"Basis":     self.Basis,
+		"SlaveType": self.SlaveType,
+		"NSlaves":   self.NSlaves,
+		"OfsNbits":  self.OfsNbits,
+		"Dst":       self.Dst,
+	}
+}
+
+func (self *ActionNxBundleLoad) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxBundleLoadInPort struct {
+	*ActionNicira
+	Algorithm NxBdAlgorithms
+	Fields    NxHashFields
+	Basis     uint16
+	SlaveType ActionNxBundleSlaveType
+	NSlaves   uint16
+	OfsNbits  uint16
+	Dst       goloxi.IOxmId
+	InPorts   []*ActionNxBundleLoadSlave
+}
+
+type IActionNxBundleLoadInPort interface {
+	IActionNicira
+	GetAlgorithm() NxBdAlgorithms
+	GetFields() NxHashFields
+	GetBasis() uint16
+	GetSlaveType() ActionNxBundleSlaveType
+	GetNSlaves() uint16
+	GetOfsNbits() uint16
+	GetDst() goloxi.IOxmId
+	GetInPorts() []*ActionNxBundleLoadSlave
+}
+
+func (self *ActionNxBundleLoadInPort) GetAlgorithm() NxBdAlgorithms {
+	return self.Algorithm
+}
+
+func (self *ActionNxBundleLoadInPort) SetAlgorithm(v NxBdAlgorithms) {
+	self.Algorithm = v
+}
+
+func (self *ActionNxBundleLoadInPort) GetFields() NxHashFields {
+	return self.Fields
+}
+
+func (self *ActionNxBundleLoadInPort) SetFields(v NxHashFields) {
+	self.Fields = v
+}
+
+func (self *ActionNxBundleLoadInPort) GetBasis() uint16 {
+	return self.Basis
+}
+
+func (self *ActionNxBundleLoadInPort) SetBasis(v uint16) {
+	self.Basis = v
+}
+
+func (self *ActionNxBundleLoadInPort) GetSlaveType() ActionNxBundleSlaveType {
+	return self.SlaveType
+}
+
+func (self *ActionNxBundleLoadInPort) SetSlaveType(v ActionNxBundleSlaveType) {
+	self.SlaveType = v
+}
+
+func (self *ActionNxBundleLoadInPort) GetNSlaves() uint16 {
+	return self.NSlaves
+}
+
+func (self *ActionNxBundleLoadInPort) SetNSlaves(v uint16) {
+	self.NSlaves = v
+}
+
+func (self *ActionNxBundleLoadInPort) GetOfsNbits() uint16 {
+	return self.OfsNbits
+}
+
+func (self *ActionNxBundleLoadInPort) SetOfsNbits(v uint16) {
+	self.OfsNbits = v
+}
+
+func (self *ActionNxBundleLoadInPort) GetDst() goloxi.IOxmId {
+	return self.Dst
+}
+
+func (self *ActionNxBundleLoadInPort) SetDst(v goloxi.IOxmId) {
+	self.Dst = v
+}
+
+func (self *ActionNxBundleLoadInPort) GetInPorts() []*ActionNxBundleLoadSlave {
+	return self.InPorts
+}
+
+func (self *ActionNxBundleLoadInPort) SetInPorts(v []*ActionNxBundleLoadSlave) {
+	self.InPorts = v
+}
+
+func (self *ActionNxBundleLoadInPort) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Algorithm))
+	encoder.PutUint16(uint16(self.Fields))
+	encoder.PutUint16(uint16(self.Basis))
+	encoder.PutUint32(uint32(self.SlaveType))
+	encoder.PutUint16(uint16(self.NSlaves))
+	encoder.PutUint16(uint16(self.OfsNbits))
+	self.Dst.Serialize(encoder)
+	encoder.Write(bytes.Repeat([]byte{0}, 4))
+	for _, obj := range self.InPorts {
+		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 DecodeActionNxBundleLoadInPort(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxBundleLoadInPort, error) {
+	_actionnxbundleloadinport := &ActionNxBundleLoadInPort{ActionNicira: parent}
+	if decoder.Length() < 22 {
+		return nil, fmt.Errorf("ActionNxBundleLoadInPort packet too short: %d < 22", decoder.Length())
+	}
+	_actionnxbundleloadinport.Algorithm = NxBdAlgorithms(decoder.ReadUint16())
+	_actionnxbundleloadinport.Fields = NxHashFields(decoder.ReadUint16())
+	_actionnxbundleloadinport.Basis = uint16(decoder.ReadUint16())
+	_actionnxbundleloadinport.SlaveType = ActionNxBundleSlaveType(decoder.ReadUint32())
+	_actionnxbundleloadinport.NSlaves = uint16(decoder.ReadUint16())
+	_actionnxbundleloadinport.OfsNbits = uint16(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxbundleloadinport.Dst = obj
+	}
+
+	decoder.Skip(4)
+
+	end := decoder.Offset() + int(_actionnxbundleloadinport.NSlaves)
+	for decoder.Offset() < end {
+		item, err := DecodeActionNxBundleLoadSlave(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_actionnxbundleloadinport.InPorts = append(_actionnxbundleloadinport.InPorts, item)
+		}
+	}
+	return _actionnxbundleloadinport, nil
+}
+
+func NewActionNxBundleLoadInPort() *ActionNxBundleLoadInPort {
+	obj := &ActionNxBundleLoadInPort{
+		ActionNicira: NewActionNicira(13),
+	}
+	return obj
+}
+func (self *ActionNxBundleLoadInPort) GetActionName() string {
+	return "nx_bundle_load_in_port"
+}
+
+func (self *ActionNxBundleLoadInPort) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Algorithm": self.Algorithm,
+		"Fields":    self.Fields,
+		"Basis":     self.Basis,
+		"SlaveType": self.SlaveType,
+		"NSlaves":   self.NSlaves,
+		"OfsNbits":  self.OfsNbits,
+		"Dst":       self.Dst,
+		"InPorts":   self.InPorts,
+	}
+}
+
+func (self *ActionNxBundleLoadInPort) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxClone struct {
+	*ActionNicira
+	Actions []goloxi.IAction
+}
+
+type IActionNxClone interface {
+	IActionNicira
+	GetActions() []goloxi.IAction
+}
+
+func (self *ActionNxClone) GetActions() []goloxi.IAction {
+	return self.Actions
+}
+
+func (self *ActionNxClone) SetActions(v []goloxi.IAction) {
+	self.Actions = v
+}
+
+func (self *ActionNxClone) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 6))
+	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 DecodeActionNxClone(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxClone, error) {
+	_actionnxclone := &ActionNxClone{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxClone packet too short: %d < 6", decoder.Length())
+	}
+	decoder.Skip(6)
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeAction(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_actionnxclone.Actions = append(_actionnxclone.Actions, item)
+		}
+	}
+	return _actionnxclone, nil
+}
+
+func NewActionNxClone() *ActionNxClone {
+	obj := &ActionNxClone{
+		ActionNicira: NewActionNicira(42),
+	}
+	return obj
+}
+func (self *ActionNxClone) GetActionName() string {
+	return "nx_clone"
+}
+
+func (self *ActionNxClone) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Actions": self.Actions,
+	}
+}
+
+func (self *ActionNxClone) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxConjunction struct {
+	*ActionNicira
+	Clause   uint8
+	NClauses uint8
+	Id       uint32
+}
+
+type IActionNxConjunction interface {
+	IActionNicira
+	GetClause() uint8
+	GetNClauses() uint8
+	GetId() uint32
+}
+
+func (self *ActionNxConjunction) GetClause() uint8 {
+	return self.Clause
+}
+
+func (self *ActionNxConjunction) SetClause(v uint8) {
+	self.Clause = v
+}
+
+func (self *ActionNxConjunction) GetNClauses() uint8 {
+	return self.NClauses
+}
+
+func (self *ActionNxConjunction) SetNClauses(v uint8) {
+	self.NClauses = v
+}
+
+func (self *ActionNxConjunction) GetId() uint32 {
+	return self.Id
+}
+
+func (self *ActionNxConjunction) SetId(v uint32) {
+	self.Id = v
+}
+
+func (self *ActionNxConjunction) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Clause))
+	encoder.PutUint8(uint8(self.NClauses))
+	encoder.PutUint32(uint32(self.Id))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxConjunction(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxConjunction, error) {
+	_actionnxconjunction := &ActionNxConjunction{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxConjunction packet too short: %d < 6", decoder.Length())
+	}
+	_actionnxconjunction.Clause = uint8(decoder.ReadByte())
+	_actionnxconjunction.NClauses = uint8(decoder.ReadByte())
+	_actionnxconjunction.Id = uint32(decoder.ReadUint32())
+	return _actionnxconjunction, nil
+}
+
+func NewActionNxConjunction() *ActionNxConjunction {
+	obj := &ActionNxConjunction{
+		ActionNicira: NewActionNicira(34),
+	}
+	return obj
+}
+func (self *ActionNxConjunction) GetActionName() string {
+	return "nx_conjunction"
+}
+
+func (self *ActionNxConjunction) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Clause":   self.Clause,
+		"NClauses": self.NClauses,
+		"Id":       self.Id,
+	}
+}
+
+func (self *ActionNxConjunction) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxController struct {
+	*ActionNicira
+	MaxLen       uint16
+	ControllerId uint16
+	Reason       uint8
+}
+
+type IActionNxController interface {
+	IActionNicira
+	GetMaxLen() uint16
+	GetControllerId() uint16
+	GetReason() uint8
+}
+
+func (self *ActionNxController) GetMaxLen() uint16 {
+	return self.MaxLen
+}
+
+func (self *ActionNxController) SetMaxLen(v uint16) {
+	self.MaxLen = v
+}
+
+func (self *ActionNxController) GetControllerId() uint16 {
+	return self.ControllerId
+}
+
+func (self *ActionNxController) SetControllerId(v uint16) {
+	self.ControllerId = v
+}
+
+func (self *ActionNxController) GetReason() uint8 {
+	return self.Reason
+}
+
+func (self *ActionNxController) SetReason(v uint8) {
+	self.Reason = v
+}
+
+func (self *ActionNxController) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.MaxLen))
+	encoder.PutUint16(uint16(self.ControllerId))
+	encoder.PutUint8(uint8(self.Reason))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxController(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxController, error) {
+	_actionnxcontroller := &ActionNxController{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxController packet too short: %d < 6", decoder.Length())
+	}
+	_actionnxcontroller.MaxLen = uint16(decoder.ReadUint16())
+	_actionnxcontroller.ControllerId = uint16(decoder.ReadUint16())
+	_actionnxcontroller.Reason = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	return _actionnxcontroller, nil
+}
+
+func NewActionNxController() *ActionNxController {
+	obj := &ActionNxController{
+		ActionNicira: NewActionNicira(20),
+	}
+	return obj
+}
+func (self *ActionNxController) GetActionName() string {
+	return "nx_controller"
+}
+
+func (self *ActionNxController) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"MaxLen":       self.MaxLen,
+		"ControllerId": self.ControllerId,
+		"Reason":       self.Reason,
+	}
+}
+
+func (self *ActionNxController) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxController2 struct {
+	*ActionNicira
+	Properties []IActionNxController2Property
+}
+
+type IActionNxController2 interface {
+	IActionNicira
+	GetProperties() []IActionNxController2Property
+}
+
+func (self *ActionNxController2) GetProperties() []IActionNxController2Property {
+	return self.Properties
+}
+
+func (self *ActionNxController2) SetProperties(v []IActionNxController2Property) {
+	self.Properties = v
+}
+
+func (self *ActionNxController2) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 6))
+	for _, obj := range self.Properties {
+		if err := obj.Serialize(encoder); err != nil {
+			return err
+		}
+	}
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxController2(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxController2, error) {
+	_actionnxcontroller2 := &ActionNxController2{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxController2 packet too short: %d < 6", decoder.Length())
+	}
+	decoder.Skip(6)
+
+	for decoder.Length() >= 2 {
+		item, err := DecodeActionNxController2Property(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_actionnxcontroller2.Properties = append(_actionnxcontroller2.Properties, item)
+		}
+	}
+	return _actionnxcontroller2, nil
+}
+
+func NewActionNxController2() *ActionNxController2 {
+	obj := &ActionNxController2{
+		ActionNicira: NewActionNicira(37),
+	}
+	return obj
+}
+func (self *ActionNxController2) GetActionName() string {
+	return "nx_controller2"
+}
+
+func (self *ActionNxController2) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Properties": self.Properties,
+	}
+}
+
+func (self *ActionNxController2) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxCt struct {
+	*ActionNicira
+	Flags       NxConntrackFlags
+	ZoneSrc     goloxi.IOxmId
+	Value       uint16
+	RecircTable uint8
+	Alg         uint16
+	Actions     []goloxi.IAction
+}
+
+type IActionNxCt interface {
+	IActionNicira
+	GetFlags() NxConntrackFlags
+	GetZoneSrc() goloxi.IOxmId
+	GetValue() uint16
+	GetRecircTable() uint8
+	GetAlg() uint16
+	GetActions() []goloxi.IAction
+}
+
+func (self *ActionNxCt) GetFlags() NxConntrackFlags {
+	return self.Flags
+}
+
+func (self *ActionNxCt) SetFlags(v NxConntrackFlags) {
+	self.Flags = v
+}
+
+func (self *ActionNxCt) GetZoneSrc() goloxi.IOxmId {
+	return self.ZoneSrc
+}
+
+func (self *ActionNxCt) SetZoneSrc(v goloxi.IOxmId) {
+	self.ZoneSrc = v
+}
+
+func (self *ActionNxCt) GetValue() uint16 {
+	return self.Value
+}
+
+func (self *ActionNxCt) SetValue(v uint16) {
+	self.Value = v
+}
+
+func (self *ActionNxCt) GetRecircTable() uint8 {
+	return self.RecircTable
+}
+
+func (self *ActionNxCt) SetRecircTable(v uint8) {
+	self.RecircTable = v
+}
+
+func (self *ActionNxCt) GetAlg() uint16 {
+	return self.Alg
+}
+
+func (self *ActionNxCt) SetAlg(v uint16) {
+	self.Alg = v
+}
+
+func (self *ActionNxCt) GetActions() []goloxi.IAction {
+	return self.Actions
+}
+
+func (self *ActionNxCt) SetActions(v []goloxi.IAction) {
+	self.Actions = v
+}
+
+func (self *ActionNxCt) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Flags))
+	self.ZoneSrc.Serialize(encoder)
+	encoder.PutUint16(uint16(self.Value))
+	encoder.PutUint8(uint8(self.RecircTable))
+	encoder.Write(bytes.Repeat([]byte{0}, 3))
+	encoder.PutUint16(uint16(self.Alg))
+	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 DecodeActionNxCt(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxCt, error) {
+	_actionnxct := &ActionNxCt{ActionNicira: parent}
+	if decoder.Length() < 14 {
+		return nil, fmt.Errorf("ActionNxCt packet too short: %d < 14", decoder.Length())
+	}
+	_actionnxct.Flags = NxConntrackFlags(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxct.ZoneSrc = obj
+	}
+
+	_actionnxct.Value = uint16(decoder.ReadUint16())
+	_actionnxct.RecircTable = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	_actionnxct.Alg = uint16(decoder.ReadUint16())
+
+	for decoder.Length() >= 8 {
+		item, err := DecodeAction(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_actionnxct.Actions = append(_actionnxct.Actions, item)
+		}
+	}
+	return _actionnxct, nil
+}
+
+func NewActionNxCt() *ActionNxCt {
+	obj := &ActionNxCt{
+		ActionNicira: NewActionNicira(35),
+	}
+	return obj
+}
+func (self *ActionNxCt) GetActionName() string {
+	return "nx_ct"
+}
+
+func (self *ActionNxCt) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Flags":       self.Flags,
+		"ZoneSrc":     self.ZoneSrc,
+		"Value":       self.Value,
+		"RecircTable": self.RecircTable,
+		"Alg":         self.Alg,
+		"Actions":     self.Actions,
+	}
+}
+
+func (self *ActionNxCt) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxCtClear struct {
+	*ActionNicira
+}
+
+type IActionNxCtClear interface {
+	IActionNicira
+}
+
+func (self *ActionNxCtClear) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxCtClear(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxCtClear, error) {
+	_actionnxctclear := &ActionNxCtClear{ActionNicira: parent}
+	return _actionnxctclear, nil
+}
+
+func NewActionNxCtClear() *ActionNxCtClear {
+	obj := &ActionNxCtClear{
+		ActionNicira: NewActionNicira(43),
+	}
+	return obj
+}
+func (self *ActionNxCtClear) GetActionName() string {
+	return "nx_ct_clear"
+}
+
+func (self *ActionNxCtClear) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxCtClear) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxDebugRecirc struct {
+	*ActionNicira
+}
+
+type IActionNxDebugRecirc interface {
+	IActionNicira
+}
+
+func (self *ActionNxDebugRecirc) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxDebugRecirc(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxDebugRecirc, error) {
+	_actionnxdebugrecirc := &ActionNxDebugRecirc{ActionNicira: parent}
+	return _actionnxdebugrecirc, nil
+}
+
+func NewActionNxDebugRecirc() *ActionNxDebugRecirc {
+	obj := &ActionNxDebugRecirc{
+		ActionNicira: NewActionNicira(255),
+	}
+	return obj
+}
+func (self *ActionNxDebugRecirc) GetActionName() string {
+	return "nx_debug_recirc"
+}
+
+func (self *ActionNxDebugRecirc) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxDebugRecirc) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxDebugSlow struct {
+	*ActionNicira
+}
+
+type IActionNxDebugSlow interface {
+	IActionNicira
+}
+
+func (self *ActionNxDebugSlow) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxDebugSlow(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxDebugSlow, error) {
+	_actionnxdebugslow := &ActionNxDebugSlow{ActionNicira: parent}
+	return _actionnxdebugslow, nil
+}
+
+func NewActionNxDebugSlow() *ActionNxDebugSlow {
+	obj := &ActionNxDebugSlow{
+		ActionNicira: NewActionNicira(254),
+	}
+	return obj
+}
+func (self *ActionNxDebugSlow) GetActionName() string {
+	return "nx_debug_slow"
+}
+
+func (self *ActionNxDebugSlow) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxDebugSlow) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxDecMplsTtl struct {
+	*ActionNicira
+}
+
+type IActionNxDecMplsTtl interface {
+	IActionNicira
+}
+
+func (self *ActionNxDecMplsTtl) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxDecMplsTtl(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxDecMplsTtl, error) {
+	_actionnxdecmplsttl := &ActionNxDecMplsTtl{ActionNicira: parent}
+	return _actionnxdecmplsttl, nil
+}
+
+func NewActionNxDecMplsTtl() *ActionNxDecMplsTtl {
+	obj := &ActionNxDecMplsTtl{
+		ActionNicira: NewActionNicira(26),
+	}
+	return obj
+}
+func (self *ActionNxDecMplsTtl) GetActionName() string {
+	return "nx_dec_mpls_ttl"
+}
+
+func (self *ActionNxDecMplsTtl) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxDecMplsTtl) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxDecNshTtl struct {
+	*ActionNicira
+}
+
+type IActionNxDecNshTtl interface {
+	IActionNicira
+}
+
+func (self *ActionNxDecNshTtl) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxDecNshTtl(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxDecNshTtl, error) {
+	_actionnxdecnshttl := &ActionNxDecNshTtl{ActionNicira: parent}
+	return _actionnxdecnshttl, nil
+}
+
+func NewActionNxDecNshTtl() *ActionNxDecNshTtl {
+	obj := &ActionNxDecNshTtl{
+		ActionNicira: NewActionNicira(48),
+	}
+	return obj
+}
+func (self *ActionNxDecNshTtl) GetActionName() string {
+	return "nx_dec_nsh_ttl"
+}
+
+func (self *ActionNxDecNshTtl) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxDecNshTtl) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxDecTtlCntIds struct {
+	*ActionNicira
+	NControllers uint16
+}
+
+type IActionNxDecTtlCntIds interface {
+	IActionNicira
+	GetNControllers() uint16
+}
+
+func (self *ActionNxDecTtlCntIds) GetNControllers() uint16 {
+	return self.NControllers
+}
+
+func (self *ActionNxDecTtlCntIds) SetNControllers(v uint16) {
+	self.NControllers = v
+}
+
+func (self *ActionNxDecTtlCntIds) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.NControllers))
+	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 DecodeActionNxDecTtlCntIds(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxDecTtlCntIds, error) {
+	_actionnxdecttlcntids := &ActionNxDecTtlCntIds{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxDecTtlCntIds packet too short: %d < 6", decoder.Length())
+	}
+	_actionnxdecttlcntids.NControllers = uint16(decoder.ReadUint16())
+	decoder.Skip(4)
+	return _actionnxdecttlcntids, nil
+}
+
+func NewActionNxDecTtlCntIds() *ActionNxDecTtlCntIds {
+	obj := &ActionNxDecTtlCntIds{
+		ActionNicira: NewActionNicira(21),
+	}
+	return obj
+}
+func (self *ActionNxDecTtlCntIds) GetActionName() string {
+	return "nx_dec_ttl_cnt_ids"
+}
+
+func (self *ActionNxDecTtlCntIds) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"NControllers": self.NControllers,
+	}
+}
+
+func (self *ActionNxDecTtlCntIds) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxDecap struct {
+	*ActionNicira
+	NewPktType uint32
+}
+
+type IActionNxDecap interface {
+	IActionNicira
+	GetNewPktType() uint32
+}
+
+func (self *ActionNxDecap) GetNewPktType() uint32 {
+	return self.NewPktType
+}
+
+func (self *ActionNxDecap) SetNewPktType(v uint32) {
+	self.NewPktType = v
+}
+
+func (self *ActionNxDecap) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint32(uint32(self.NewPktType))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxDecap(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxDecap, error) {
+	_actionnxdecap := &ActionNxDecap{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxDecap packet too short: %d < 6", decoder.Length())
+	}
+	decoder.Skip(2)
+	_actionnxdecap.NewPktType = uint32(decoder.ReadUint32())
+	return _actionnxdecap, nil
+}
+
+func NewActionNxDecap() *ActionNxDecap {
+	obj := &ActionNxDecap{
+		ActionNicira: NewActionNicira(47),
+	}
+	return obj
+}
+func (self *ActionNxDecap) GetActionName() string {
+	return "nx_decap"
+}
+
+func (self *ActionNxDecap) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"NewPktType": self.NewPktType,
+	}
+}
+
+func (self *ActionNxDecap) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxEncap struct {
+	*ActionNicira
+	HdrSize    uint16
+	PacketType PacketType
+	Props      []IEdPropHeader
+}
+
+type IActionNxEncap interface {
+	IActionNicira
+	GetHdrSize() uint16
+	GetPacketType() PacketType
+	GetProps() []IEdPropHeader
+}
+
+func (self *ActionNxEncap) GetHdrSize() uint16 {
+	return self.HdrSize
+}
+
+func (self *ActionNxEncap) SetHdrSize(v uint16) {
+	self.HdrSize = v
+}
+
+func (self *ActionNxEncap) GetPacketType() PacketType {
+	return self.PacketType
+}
+
+func (self *ActionNxEncap) SetPacketType(v PacketType) {
+	self.PacketType = v
+}
+
+func (self *ActionNxEncap) GetProps() []IEdPropHeader {
+	return self.Props
+}
+
+func (self *ActionNxEncap) SetProps(v []IEdPropHeader) {
+	self.Props = v
+}
+
+func (self *ActionNxEncap) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.HdrSize))
+	encoder.PutUint32(uint32(self.PacketType))
+	for _, obj := range self.Props {
+		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 DecodeActionNxEncap(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxEncap, error) {
+	_actionnxencap := &ActionNxEncap{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxEncap packet too short: %d < 6", decoder.Length())
+	}
+	_actionnxencap.HdrSize = uint16(decoder.ReadUint16())
+	_actionnxencap.PacketType = PacketType(decoder.ReadUint32())
+
+	for decoder.Length() >= 4 {
+		item, err := DecodeEdPropHeader(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_actionnxencap.Props = append(_actionnxencap.Props, item)
+		}
+	}
+	return _actionnxencap, nil
+}
+
+func NewActionNxEncap() *ActionNxEncap {
+	obj := &ActionNxEncap{
+		ActionNicira: NewActionNicira(46),
+	}
+	return obj
+}
+func (self *ActionNxEncap) GetActionName() string {
+	return "nx_encap"
+}
+
+func (self *ActionNxEncap) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"HdrSize":    self.HdrSize,
+		"PacketType": self.PacketType,
+		"Props":      self.Props,
+	}
+}
+
+func (self *ActionNxEncap) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxExit struct {
+	*ActionNicira
+}
+
+type IActionNxExit interface {
+	IActionNicira
+}
+
+func (self *ActionNxExit) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxExit(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxExit, error) {
+	_actionnxexit := &ActionNxExit{ActionNicira: parent}
+	return _actionnxexit, nil
+}
+
+func NewActionNxExit() *ActionNxExit {
+	obj := &ActionNxExit{
+		ActionNicira: NewActionNicira(17),
+	}
+	return obj
+}
+func (self *ActionNxExit) GetActionName() string {
+	return "nx_exit"
+}
+
+func (self *ActionNxExit) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxExit) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxFinTimeout struct {
+	*ActionNicira
+	FinIdleTimeout uint16
+	FinHardTimeout uint16
+}
+
+type IActionNxFinTimeout interface {
+	IActionNicira
+	GetFinIdleTimeout() uint16
+	GetFinHardTimeout() uint16
+}
+
+func (self *ActionNxFinTimeout) GetFinIdleTimeout() uint16 {
+	return self.FinIdleTimeout
+}
+
+func (self *ActionNxFinTimeout) SetFinIdleTimeout(v uint16) {
+	self.FinIdleTimeout = v
+}
+
+func (self *ActionNxFinTimeout) GetFinHardTimeout() uint16 {
+	return self.FinHardTimeout
+}
+
+func (self *ActionNxFinTimeout) SetFinHardTimeout(v uint16) {
+	self.FinHardTimeout = v
+}
+
+func (self *ActionNxFinTimeout) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.FinIdleTimeout))
+	encoder.PutUint16(uint16(self.FinHardTimeout))
+	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 DecodeActionNxFinTimeout(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxFinTimeout, error) {
+	_actionnxfintimeout := &ActionNxFinTimeout{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxFinTimeout packet too short: %d < 6", decoder.Length())
+	}
+	_actionnxfintimeout.FinIdleTimeout = uint16(decoder.ReadUint16())
+	_actionnxfintimeout.FinHardTimeout = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	return _actionnxfintimeout, nil
+}
+
+func NewActionNxFinTimeout() *ActionNxFinTimeout {
+	obj := &ActionNxFinTimeout{
+		ActionNicira: NewActionNicira(19),
+	}
+	return obj
+}
+func (self *ActionNxFinTimeout) GetActionName() string {
+	return "nx_fin_timeout"
+}
+
+func (self *ActionNxFinTimeout) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"FinIdleTimeout": self.FinIdleTimeout,
+		"FinHardTimeout": self.FinHardTimeout,
+	}
+}
+
+func (self *ActionNxFinTimeout) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxGroup struct {
+	*ActionNicira
+	Value uint32
+}
+
+type IActionNxGroup interface {
+	IActionNicira
+	GetValue() uint32
+}
+
+func (self *ActionNxGroup) GetValue() uint32 {
+	return self.Value
+}
+
+func (self *ActionNxGroup) SetValue(v uint32) {
+	self.Value = v
+}
+
+func (self *ActionNxGroup) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxGroup(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxGroup, error) {
+	_actionnxgroup := &ActionNxGroup{ActionNicira: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionNxGroup packet too short: %d < 4", decoder.Length())
+	}
+	_actionnxgroup.Value = uint32(decoder.ReadUint32())
+	return _actionnxgroup, nil
+}
+
+func NewActionNxGroup() *ActionNxGroup {
+	obj := &ActionNxGroup{
+		ActionNicira: NewActionNicira(40),
+	}
+	return obj
+}
+func (self *ActionNxGroup) GetActionName() string {
+	return "nx_group"
+}
+
+func (self *ActionNxGroup) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxGroup) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxLearn struct {
+	*ActionNicira
+	IdleTimeout    uint16
+	HardTimeout    uint16
+	Priority       uint16
+	Cookie         uint64
+	Flags          uint16
+	TableId        uint8
+	FinIdleTimeout uint16
+	FinHardTimeout uint16
+	FlowMods       []IFlowModSpec
+}
+
+type IActionNxLearn interface {
+	IActionNicira
+	GetIdleTimeout() uint16
+	GetHardTimeout() uint16
+	GetPriority() uint16
+	GetCookie() uint64
+	GetFlags() uint16
+	GetTableId() uint8
+	GetFinIdleTimeout() uint16
+	GetFinHardTimeout() uint16
+	GetFlowMods() []IFlowModSpec
+}
+
+func (self *ActionNxLearn) GetIdleTimeout() uint16 {
+	return self.IdleTimeout
+}
+
+func (self *ActionNxLearn) SetIdleTimeout(v uint16) {
+	self.IdleTimeout = v
+}
+
+func (self *ActionNxLearn) GetHardTimeout() uint16 {
+	return self.HardTimeout
+}
+
+func (self *ActionNxLearn) SetHardTimeout(v uint16) {
+	self.HardTimeout = v
+}
+
+func (self *ActionNxLearn) GetPriority() uint16 {
+	return self.Priority
+}
+
+func (self *ActionNxLearn) SetPriority(v uint16) {
+	self.Priority = v
+}
+
+func (self *ActionNxLearn) GetCookie() uint64 {
+	return self.Cookie
+}
+
+func (self *ActionNxLearn) SetCookie(v uint64) {
+	self.Cookie = v
+}
+
+func (self *ActionNxLearn) GetFlags() uint16 {
+	return self.Flags
+}
+
+func (self *ActionNxLearn) SetFlags(v uint16) {
+	self.Flags = v
+}
+
+func (self *ActionNxLearn) GetTableId() uint8 {
+	return self.TableId
+}
+
+func (self *ActionNxLearn) SetTableId(v uint8) {
+	self.TableId = v
+}
+
+func (self *ActionNxLearn) GetFinIdleTimeout() uint16 {
+	return self.FinIdleTimeout
+}
+
+func (self *ActionNxLearn) SetFinIdleTimeout(v uint16) {
+	self.FinIdleTimeout = v
+}
+
+func (self *ActionNxLearn) GetFinHardTimeout() uint16 {
+	return self.FinHardTimeout
+}
+
+func (self *ActionNxLearn) SetFinHardTimeout(v uint16) {
+	self.FinHardTimeout = v
+}
+
+func (self *ActionNxLearn) GetFlowMods() []IFlowModSpec {
+	return self.FlowMods
+}
+
+func (self *ActionNxLearn) SetFlowMods(v []IFlowModSpec) {
+	self.FlowMods = v
+}
+
+func (self *ActionNxLearn) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.IdleTimeout))
+	encoder.PutUint16(uint16(self.HardTimeout))
+	encoder.PutUint16(uint16(self.Priority))
+	encoder.PutUint64(uint64(self.Cookie))
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.PutUint8(uint8(self.TableId))
+	encoder.Write(bytes.Repeat([]byte{0}, 1))
+	encoder.PutUint16(uint16(self.FinIdleTimeout))
+	encoder.PutUint16(uint16(self.FinHardTimeout))
+	for _, obj := range self.FlowMods {
+		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 DecodeActionNxLearn(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxLearn, error) {
+	_actionnxlearn := &ActionNxLearn{ActionNicira: parent}
+	if decoder.Length() < 22 {
+		return nil, fmt.Errorf("ActionNxLearn packet too short: %d < 22", decoder.Length())
+	}
+	_actionnxlearn.IdleTimeout = uint16(decoder.ReadUint16())
+	_actionnxlearn.HardTimeout = uint16(decoder.ReadUint16())
+	_actionnxlearn.Priority = uint16(decoder.ReadUint16())
+	_actionnxlearn.Cookie = uint64(decoder.ReadUint64())
+	_actionnxlearn.Flags = uint16(decoder.ReadUint16())
+	_actionnxlearn.TableId = uint8(decoder.ReadByte())
+	decoder.Skip(1)
+	_actionnxlearn.FinIdleTimeout = uint16(decoder.ReadUint16())
+	_actionnxlearn.FinHardTimeout = uint16(decoder.ReadUint16())
+
+	for decoder.Length() >= 2 {
+		item, err := DecodeFlowModSpec(decoder)
+		if err != nil {
+			return nil, err
+		}
+		if item != nil {
+			_actionnxlearn.FlowMods = append(_actionnxlearn.FlowMods, item)
+		}
+	}
+	return _actionnxlearn, nil
+}
+
+func NewActionNxLearn() *ActionNxLearn {
+	obj := &ActionNxLearn{
+		ActionNicira: NewActionNicira(16),
+	}
+	return obj
+}
+func (self *ActionNxLearn) GetActionName() string {
+	return "nx_learn"
+}
+
+func (self *ActionNxLearn) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"IdleTimeout":    self.IdleTimeout,
+		"HardTimeout":    self.HardTimeout,
+		"Priority":       self.Priority,
+		"Cookie":         self.Cookie,
+		"Flags":          self.Flags,
+		"TableId":        self.TableId,
+		"FinIdleTimeout": self.FinIdleTimeout,
+		"FinHardTimeout": self.FinHardTimeout,
+		"FlowMods":       self.FlowMods,
+	}
+}
+
+func (self *ActionNxLearn) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxLearn2 struct {
+	*ActionNicira
+}
+
+type IActionNxLearn2 interface {
+	IActionNicira
+}
+
+func (self *ActionNxLearn2) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxLearn2(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxLearn2, error) {
+	_actionnxlearn2 := &ActionNxLearn2{ActionNicira: parent}
+	return _actionnxlearn2, nil
+}
+
+func NewActionNxLearn2() *ActionNxLearn2 {
+	obj := &ActionNxLearn2{
+		ActionNicira: NewActionNicira(45),
+	}
+	return obj
+}
+func (self *ActionNxLearn2) GetActionName() string {
+	return "nx_learn2"
+}
+
+func (self *ActionNxLearn2) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxLearn2) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxMultipath struct {
+	*ActionNicira
+	Fields    NxHashFields
+	Basis     uint16
+	Algorithm NxMpAlgorithm
+	MaxLink   uint16
+	Arg       uint32
+	OfsNbits  uint16
+	Dst       goloxi.IOxmId
+}
+
+type IActionNxMultipath interface {
+	IActionNicira
+	GetFields() NxHashFields
+	GetBasis() uint16
+	GetAlgorithm() NxMpAlgorithm
+	GetMaxLink() uint16
+	GetArg() uint32
+	GetOfsNbits() uint16
+	GetDst() goloxi.IOxmId
+}
+
+func (self *ActionNxMultipath) GetFields() NxHashFields {
+	return self.Fields
+}
+
+func (self *ActionNxMultipath) SetFields(v NxHashFields) {
+	self.Fields = v
+}
+
+func (self *ActionNxMultipath) GetBasis() uint16 {
+	return self.Basis
+}
+
+func (self *ActionNxMultipath) SetBasis(v uint16) {
+	self.Basis = v
+}
+
+func (self *ActionNxMultipath) GetAlgorithm() NxMpAlgorithm {
+	return self.Algorithm
+}
+
+func (self *ActionNxMultipath) SetAlgorithm(v NxMpAlgorithm) {
+	self.Algorithm = v
+}
+
+func (self *ActionNxMultipath) GetMaxLink() uint16 {
+	return self.MaxLink
+}
+
+func (self *ActionNxMultipath) SetMaxLink(v uint16) {
+	self.MaxLink = v
+}
+
+func (self *ActionNxMultipath) GetArg() uint32 {
+	return self.Arg
+}
+
+func (self *ActionNxMultipath) SetArg(v uint32) {
+	self.Arg = v
+}
+
+func (self *ActionNxMultipath) GetOfsNbits() uint16 {
+	return self.OfsNbits
+}
+
+func (self *ActionNxMultipath) SetOfsNbits(v uint16) {
+	self.OfsNbits = v
+}
+
+func (self *ActionNxMultipath) GetDst() goloxi.IOxmId {
+	return self.Dst
+}
+
+func (self *ActionNxMultipath) SetDst(v goloxi.IOxmId) {
+	self.Dst = v
+}
+
+func (self *ActionNxMultipath) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Fields))
+	encoder.PutUint16(uint16(self.Basis))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint16(uint16(self.Algorithm))
+	encoder.PutUint16(uint16(self.MaxLink))
+	encoder.PutUint32(uint32(self.Arg))
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint16(uint16(self.OfsNbits))
+	self.Dst.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxMultipath(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxMultipath, error) {
+	_actionnxmultipath := &ActionNxMultipath{ActionNicira: parent}
+	if decoder.Length() < 22 {
+		return nil, fmt.Errorf("ActionNxMultipath packet too short: %d < 22", decoder.Length())
+	}
+	_actionnxmultipath.Fields = NxHashFields(decoder.ReadUint16())
+	_actionnxmultipath.Basis = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	_actionnxmultipath.Algorithm = NxMpAlgorithm(decoder.ReadUint16())
+	_actionnxmultipath.MaxLink = uint16(decoder.ReadUint16())
+	_actionnxmultipath.Arg = uint32(decoder.ReadUint32())
+	decoder.Skip(2)
+	_actionnxmultipath.OfsNbits = uint16(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxmultipath.Dst = obj
+	}
+
+	return _actionnxmultipath, nil
+}
+
+func NewActionNxMultipath() *ActionNxMultipath {
+	obj := &ActionNxMultipath{
+		ActionNicira: NewActionNicira(10),
+	}
+	return obj
+}
+func (self *ActionNxMultipath) GetActionName() string {
+	return "nx_multipath"
+}
+
+func (self *ActionNxMultipath) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Fields":    self.Fields,
+		"Basis":     self.Basis,
+		"Algorithm": self.Algorithm,
+		"MaxLink":   self.MaxLink,
+		"Arg":       self.Arg,
+		"OfsNbits":  self.OfsNbits,
+		"Dst":       self.Dst,
+	}
+}
+
+func (self *ActionNxMultipath) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxNat struct {
+	*ActionNicira
+	Flags        uint16
+	RangePresent NxNatRange
+	Ipv4Min      net.IP
+	Ipv4Max      net.IP
+	Ipv6Min      net.IP
+	Ipv6Max      net.IP
+	ProtoMin     uint32
+	ProtoMax     uint32
+}
+
+type IActionNxNat interface {
+	IActionNicira
+	GetFlags() uint16
+	GetRangePresent() NxNatRange
+	GetIpv4Min() net.IP
+	GetIpv4Max() net.IP
+	GetIpv6Min() net.IP
+	GetIpv6Max() net.IP
+	GetProtoMin() uint32
+	GetProtoMax() uint32
+}
+
+func (self *ActionNxNat) GetFlags() uint16 {
+	return self.Flags
+}
+
+func (self *ActionNxNat) SetFlags(v uint16) {
+	self.Flags = v
+}
+
+func (self *ActionNxNat) GetRangePresent() NxNatRange {
+	return self.RangePresent
+}
+
+func (self *ActionNxNat) SetRangePresent(v NxNatRange) {
+	self.RangePresent = v
+}
+
+func (self *ActionNxNat) GetIpv4Min() net.IP {
+	return self.Ipv4Min
+}
+
+func (self *ActionNxNat) SetIpv4Min(v net.IP) {
+	self.Ipv4Min = v
+}
+
+func (self *ActionNxNat) GetIpv4Max() net.IP {
+	return self.Ipv4Max
+}
+
+func (self *ActionNxNat) SetIpv4Max(v net.IP) {
+	self.Ipv4Max = v
+}
+
+func (self *ActionNxNat) GetIpv6Min() net.IP {
+	return self.Ipv6Min
+}
+
+func (self *ActionNxNat) SetIpv6Min(v net.IP) {
+	self.Ipv6Min = v
+}
+
+func (self *ActionNxNat) GetIpv6Max() net.IP {
+	return self.Ipv6Max
+}
+
+func (self *ActionNxNat) SetIpv6Max(v net.IP) {
+	self.Ipv6Max = v
+}
+
+func (self *ActionNxNat) GetProtoMin() uint32 {
+	return self.ProtoMin
+}
+
+func (self *ActionNxNat) SetProtoMin(v uint32) {
+	self.ProtoMin = v
+}
+
+func (self *ActionNxNat) GetProtoMax() uint32 {
+	return self.ProtoMax
+}
+
+func (self *ActionNxNat) SetProtoMax(v uint32) {
+	self.ProtoMax = v
+}
+
+func (self *ActionNxNat) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 2))
+	encoder.PutUint16(uint16(self.Flags))
+	encoder.PutUint16(uint16(self.RangePresent))
+	encoder.Write(self.Ipv4Min.To4())
+	encoder.Write(self.Ipv4Max.To4())
+	encoder.Write(self.Ipv6Min.To16())
+	encoder.Write(self.Ipv6Max.To16())
+	encoder.PutUint32(uint32(self.ProtoMin))
+	encoder.PutUint32(uint32(self.ProtoMax))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxNat(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxNat, error) {
+	_actionnxnat := &ActionNxNat{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxNat packet too short: %d < 6", decoder.Length())
+	}
+	decoder.Skip(2)
+	_actionnxnat.Flags = uint16(decoder.ReadUint16())
+	_actionnxnat.RangePresent = NxNatRange(decoder.ReadUint16())
+	if _actionnxnat.RangePresent&1 == 1 {
+		_actionnxnat.Ipv4Min = net.IP(decoder.Read(4))
+	}
+	if _actionnxnat.RangePresent&2 == 2 {
+		_actionnxnat.Ipv4Max = net.IP(decoder.Read(4))
+	}
+	if _actionnxnat.RangePresent&4 == 4 {
+		_actionnxnat.Ipv6Min = net.IP(decoder.Read(16))
+	}
+	if _actionnxnat.RangePresent&8 == 8 {
+		_actionnxnat.Ipv6Max = net.IP(decoder.Read(16))
+	}
+	if _actionnxnat.RangePresent&16 == 16 {
+		_actionnxnat.ProtoMin = uint32(decoder.ReadUint32())
+	}
+	if _actionnxnat.RangePresent&32 == 32 {
+		_actionnxnat.ProtoMax = uint32(decoder.ReadUint32())
+	}
+	return _actionnxnat, nil
+}
+
+func NewActionNxNat() *ActionNxNat {
+	obj := &ActionNxNat{
+		ActionNicira: NewActionNicira(36),
+	}
+	return obj
+}
+func (self *ActionNxNat) GetActionName() string {
+	return "nx_nat"
+}
+
+func (self *ActionNxNat) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Flags":        self.Flags,
+		"RangePresent": self.RangePresent,
+		"Ipv4Min":      self.Ipv4Min,
+		"Ipv4Max":      self.Ipv4Max,
+		"Ipv6Min":      self.Ipv6Min,
+		"Ipv6Max":      self.Ipv6Max,
+		"ProtoMin":     self.ProtoMin,
+		"ProtoMax":     self.ProtoMax,
+	}
+}
+
+func (self *ActionNxNat) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxNote struct {
+	*ActionNicira
+	Note []byte
+}
+
+type IActionNxNote interface {
+	IActionNicira
+	GetNote() []byte
+}
+
+func (self *ActionNxNote) GetNote() []byte {
+	return self.Note
+}
+
+func (self *ActionNxNote) SetNote(v []byte) {
+	self.Note = v
+}
+
+func (self *ActionNxNote) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(self.Note)
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxNote(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxNote, error) {
+	_actionnxnote := &ActionNxNote{ActionNicira: parent}
+	_actionnxnote.Note = decoder.Read(int(decoder.Length()))
+	return _actionnxnote, nil
+}
+
+func NewActionNxNote() *ActionNxNote {
+	obj := &ActionNxNote{
+		ActionNicira: NewActionNicira(8),
+	}
+	return obj
+}
+func (self *ActionNxNote) GetActionName() string {
+	return "nx_note"
+}
+
+func (self *ActionNxNote) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Note": self.Note,
+	}
+}
+
+func (self *ActionNxNote) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxOutputReg struct {
+	*ActionNicira
+	OfsNbits uint16
+	Src      uint32
+	MaxLen   uint16
+}
+
+type IActionNxOutputReg interface {
+	IActionNicira
+	GetOfsNbits() uint16
+	GetSrc() uint32
+	GetMaxLen() uint16
+}
+
+func (self *ActionNxOutputReg) GetOfsNbits() uint16 {
+	return self.OfsNbits
+}
+
+func (self *ActionNxOutputReg) SetOfsNbits(v uint16) {
+	self.OfsNbits = v
+}
+
+func (self *ActionNxOutputReg) GetSrc() uint32 {
+	return self.Src
+}
+
+func (self *ActionNxOutputReg) SetSrc(v uint32) {
+	self.Src = v
+}
+
+func (self *ActionNxOutputReg) GetMaxLen() uint16 {
+	return self.MaxLen
+}
+
+func (self *ActionNxOutputReg) SetMaxLen(v uint16) {
+	self.MaxLen = v
+}
+
+func (self *ActionNxOutputReg) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.OfsNbits))
+	encoder.PutUint32(uint32(self.Src))
+	encoder.PutUint16(uint16(self.MaxLen))
+	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 DecodeActionNxOutputReg(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxOutputReg, error) {
+	_actionnxoutputreg := &ActionNxOutputReg{ActionNicira: parent}
+	if decoder.Length() < 14 {
+		return nil, fmt.Errorf("ActionNxOutputReg packet too short: %d < 14", decoder.Length())
+	}
+	_actionnxoutputreg.OfsNbits = uint16(decoder.ReadUint16())
+	_actionnxoutputreg.Src = uint32(decoder.ReadUint32())
+	_actionnxoutputreg.MaxLen = uint16(decoder.ReadUint16())
+	decoder.Skip(6)
+	return _actionnxoutputreg, nil
+}
+
+func NewActionNxOutputReg() *ActionNxOutputReg {
+	obj := &ActionNxOutputReg{
+		ActionNicira: NewActionNicira(15),
+	}
+	return obj
+}
+func (self *ActionNxOutputReg) GetActionName() string {
+	return "nx_output_reg"
+}
+
+func (self *ActionNxOutputReg) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"OfsNbits": self.OfsNbits,
+		"Src":      self.Src,
+		"MaxLen":   self.MaxLen,
+	}
+}
+
+func (self *ActionNxOutputReg) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxOutputReg2 struct {
+	*ActionNicira
+	OfsNbits uint16
+	MaxLen   uint16
+}
+
+type IActionNxOutputReg2 interface {
+	IActionNicira
+	GetOfsNbits() uint16
+	GetMaxLen() uint16
+}
+
+func (self *ActionNxOutputReg2) GetOfsNbits() uint16 {
+	return self.OfsNbits
+}
+
+func (self *ActionNxOutputReg2) SetOfsNbits(v uint16) {
+	self.OfsNbits = v
+}
+
+func (self *ActionNxOutputReg2) GetMaxLen() uint16 {
+	return self.MaxLen
+}
+
+func (self *ActionNxOutputReg2) SetMaxLen(v uint16) {
+	self.MaxLen = v
+}
+
+func (self *ActionNxOutputReg2) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.OfsNbits))
+	encoder.PutUint16(uint16(self.MaxLen))
+	encoder.Write(bytes.Repeat([]byte{0}, 10))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxOutputReg2(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxOutputReg2, error) {
+	_actionnxoutputreg2 := &ActionNxOutputReg2{ActionNicira: parent}
+	if decoder.Length() < 14 {
+		return nil, fmt.Errorf("ActionNxOutputReg2 packet too short: %d < 14", decoder.Length())
+	}
+	_actionnxoutputreg2.OfsNbits = uint16(decoder.ReadUint16())
+	_actionnxoutputreg2.MaxLen = uint16(decoder.ReadUint16())
+	decoder.Skip(10)
+	return _actionnxoutputreg2, nil
+}
+
+func NewActionNxOutputReg2() *ActionNxOutputReg2 {
+	obj := &ActionNxOutputReg2{
+		ActionNicira: NewActionNicira(32),
+	}
+	return obj
+}
+func (self *ActionNxOutputReg2) GetActionName() string {
+	return "nx_output_reg2"
+}
+
+func (self *ActionNxOutputReg2) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"OfsNbits": self.OfsNbits,
+		"MaxLen":   self.MaxLen,
+	}
+}
+
+func (self *ActionNxOutputReg2) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxOutputTrunc struct {
+	*ActionNicira
+	Port   uint16
+	MaxLen uint32
+}
+
+type IActionNxOutputTrunc interface {
+	IActionNicira
+	GetPort() uint16
+	GetMaxLen() uint32
+}
+
+func (self *ActionNxOutputTrunc) GetPort() uint16 {
+	return self.Port
+}
+
+func (self *ActionNxOutputTrunc) SetPort(v uint16) {
+	self.Port = v
+}
+
+func (self *ActionNxOutputTrunc) GetMaxLen() uint32 {
+	return self.MaxLen
+}
+
+func (self *ActionNxOutputTrunc) SetMaxLen(v uint32) {
+	self.MaxLen = v
+}
+
+func (self *ActionNxOutputTrunc) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Port))
+	encoder.PutUint32(uint32(self.MaxLen))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxOutputTrunc(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxOutputTrunc, error) {
+	_actionnxoutputtrunc := &ActionNxOutputTrunc{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxOutputTrunc packet too short: %d < 6", decoder.Length())
+	}
+	_actionnxoutputtrunc.Port = uint16(decoder.ReadUint16())
+	_actionnxoutputtrunc.MaxLen = uint32(decoder.ReadUint32())
+	return _actionnxoutputtrunc, nil
+}
+
+func NewActionNxOutputTrunc() *ActionNxOutputTrunc {
+	obj := &ActionNxOutputTrunc{
+		ActionNicira: NewActionNicira(39),
+	}
+	return obj
+}
+func (self *ActionNxOutputTrunc) GetActionName() string {
+	return "nx_output_trunc"
+}
+
+func (self *ActionNxOutputTrunc) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Port":   self.Port,
+		"MaxLen": self.MaxLen,
+	}
+}
+
+func (self *ActionNxOutputTrunc) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxPopMpls struct {
+	*ActionNicira
+	Value uint16
+}
+
+type IActionNxPopMpls interface {
+	IActionNicira
+	GetValue() uint16
+}
+
+func (self *ActionNxPopMpls) GetValue() uint16 {
+	return self.Value
+}
+
+func (self *ActionNxPopMpls) SetValue(v uint16) {
+	self.Value = v
+}
+
+func (self *ActionNxPopMpls) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Value))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxPopMpls(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxPopMpls, error) {
+	_actionnxpopmpls := &ActionNxPopMpls{ActionNicira: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("ActionNxPopMpls packet too short: %d < 2", decoder.Length())
+	}
+	_actionnxpopmpls.Value = uint16(decoder.ReadUint16())
+	return _actionnxpopmpls, nil
+}
+
+func NewActionNxPopMpls() *ActionNxPopMpls {
+	obj := &ActionNxPopMpls{
+		ActionNicira: NewActionNicira(24),
+	}
+	return obj
+}
+func (self *ActionNxPopMpls) GetActionName() string {
+	return "nx_pop_mpls"
+}
+
+func (self *ActionNxPopMpls) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxPopMpls) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxPopQueue struct {
+	*ActionNicira
+}
+
+type IActionNxPopQueue interface {
+	IActionNicira
+}
+
+func (self *ActionNxPopQueue) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxPopQueue(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxPopQueue, error) {
+	_actionnxpopqueue := &ActionNxPopQueue{ActionNicira: parent}
+	return _actionnxpopqueue, nil
+}
+
+func NewActionNxPopQueue() *ActionNxPopQueue {
+	obj := &ActionNxPopQueue{
+		ActionNicira: NewActionNicira(5),
+	}
+	return obj
+}
+func (self *ActionNxPopQueue) GetActionName() string {
+	return "nx_pop_queue"
+}
+
+func (self *ActionNxPopQueue) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxPopQueue) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxPushMpls struct {
+	*ActionNicira
+	Value uint16
+}
+
+type IActionNxPushMpls interface {
+	IActionNicira
+	GetValue() uint16
+}
+
+func (self *ActionNxPushMpls) GetValue() uint16 {
+	return self.Value
+}
+
+func (self *ActionNxPushMpls) SetValue(v uint16) {
+	self.Value = v
+}
+
+func (self *ActionNxPushMpls) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Value))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxPushMpls(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxPushMpls, error) {
+	_actionnxpushmpls := &ActionNxPushMpls{ActionNicira: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("ActionNxPushMpls packet too short: %d < 2", decoder.Length())
+	}
+	_actionnxpushmpls.Value = uint16(decoder.ReadUint16())
+	return _actionnxpushmpls, nil
+}
+
+func NewActionNxPushMpls() *ActionNxPushMpls {
+	obj := &ActionNxPushMpls{
+		ActionNicira: NewActionNicira(23),
+	}
+	return obj
+}
+func (self *ActionNxPushMpls) GetActionName() string {
+	return "nx_push_mpls"
+}
+
+func (self *ActionNxPushMpls) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxPushMpls) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxRegLoad struct {
+	*ActionNicira
+	OfsNbits uint16
+	SrcField goloxi.IOxmId
+	Value    uint64
+}
+
+type IActionNxRegLoad interface {
+	IActionNicira
+	GetOfsNbits() uint16
+	GetSrcField() goloxi.IOxmId
+	GetValue() uint64
+}
+
+func (self *ActionNxRegLoad) GetOfsNbits() uint16 {
+	return self.OfsNbits
+}
+
+func (self *ActionNxRegLoad) SetOfsNbits(v uint16) {
+	self.OfsNbits = v
+}
+
+func (self *ActionNxRegLoad) GetSrcField() goloxi.IOxmId {
+	return self.SrcField
+}
+
+func (self *ActionNxRegLoad) SetSrcField(v goloxi.IOxmId) {
+	self.SrcField = v
+}
+
+func (self *ActionNxRegLoad) GetValue() uint64 {
+	return self.Value
+}
+
+func (self *ActionNxRegLoad) SetValue(v uint64) {
+	self.Value = v
+}
+
+func (self *ActionNxRegLoad) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.OfsNbits))
+	self.SrcField.Serialize(encoder)
+	encoder.PutUint64(uint64(self.Value))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxRegLoad(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxRegLoad, error) {
+	_actionnxregload := &ActionNxRegLoad{ActionNicira: parent}
+	if decoder.Length() < 14 {
+		return nil, fmt.Errorf("ActionNxRegLoad packet too short: %d < 14", decoder.Length())
+	}
+	_actionnxregload.OfsNbits = uint16(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxregload.SrcField = obj
+	}
+
+	_actionnxregload.Value = uint64(decoder.ReadUint64())
+	return _actionnxregload, nil
+}
+
+func NewActionNxRegLoad() *ActionNxRegLoad {
+	obj := &ActionNxRegLoad{
+		ActionNicira: NewActionNicira(7),
+	}
+	return obj
+}
+func (self *ActionNxRegLoad) GetActionName() string {
+	return "nx_reg_load"
+}
+
+func (self *ActionNxRegLoad) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"OfsNbits": self.OfsNbits,
+		"SrcField": self.SrcField,
+		"Value":    self.Value,
+	}
+}
+
+func (self *ActionNxRegLoad) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxRegLoad2 struct {
+	*ActionNicira
+}
+
+type IActionNxRegLoad2 interface {
+	IActionNicira
+}
+
+func (self *ActionNxRegLoad2) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	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 DecodeActionNxRegLoad2(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxRegLoad2, error) {
+	_actionnxregload2 := &ActionNxRegLoad2{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxRegLoad2 packet too short: %d < 6", decoder.Length())
+	}
+	decoder.Skip(6)
+	return _actionnxregload2, nil
+}
+
+func NewActionNxRegLoad2() *ActionNxRegLoad2 {
+	obj := &ActionNxRegLoad2{
+		ActionNicira: NewActionNicira(33),
+	}
+	return obj
+}
+func (self *ActionNxRegLoad2) GetActionName() string {
+	return "nx_reg_load2"
+}
+
+func (self *ActionNxRegLoad2) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionNxRegLoad2) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxRegMove struct {
+	*ActionNicira
+	NBits  uint16
+	SrcOfs uint16
+	DstOfs uint16
+	Src    goloxi.IOxmId
+	Dst    goloxi.IOxmId
+}
+
+type IActionNxRegMove interface {
+	IActionNicira
+	GetNBits() uint16
+	GetSrcOfs() uint16
+	GetDstOfs() uint16
+	GetSrc() goloxi.IOxmId
+	GetDst() goloxi.IOxmId
+}
+
+func (self *ActionNxRegMove) GetNBits() uint16 {
+	return self.NBits
+}
+
+func (self *ActionNxRegMove) SetNBits(v uint16) {
+	self.NBits = v
+}
+
+func (self *ActionNxRegMove) GetSrcOfs() uint16 {
+	return self.SrcOfs
+}
+
+func (self *ActionNxRegMove) SetSrcOfs(v uint16) {
+	self.SrcOfs = v
+}
+
+func (self *ActionNxRegMove) GetDstOfs() uint16 {
+	return self.DstOfs
+}
+
+func (self *ActionNxRegMove) SetDstOfs(v uint16) {
+	self.DstOfs = v
+}
+
+func (self *ActionNxRegMove) GetSrc() goloxi.IOxmId {
+	return self.Src
+}
+
+func (self *ActionNxRegMove) SetSrc(v goloxi.IOxmId) {
+	self.Src = v
+}
+
+func (self *ActionNxRegMove) GetDst() goloxi.IOxmId {
+	return self.Dst
+}
+
+func (self *ActionNxRegMove) SetDst(v goloxi.IOxmId) {
+	self.Dst = v
+}
+
+func (self *ActionNxRegMove) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.NBits))
+	encoder.PutUint16(uint16(self.SrcOfs))
+	encoder.PutUint16(uint16(self.DstOfs))
+	self.Src.Serialize(encoder)
+	self.Dst.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+	alignedLength := ((length + 7) / 8 * 8)
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	encoder.Write(bytes.Repeat([]byte{0}, alignedLength-length))
+
+	return nil
+}
+
+func DecodeActionNxRegMove(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxRegMove, error) {
+	_actionnxregmove := &ActionNxRegMove{ActionNicira: parent}
+	if decoder.Length() < 14 {
+		return nil, fmt.Errorf("ActionNxRegMove packet too short: %d < 14", decoder.Length())
+	}
+	_actionnxregmove.NBits = uint16(decoder.ReadUint16())
+	_actionnxregmove.SrcOfs = uint16(decoder.ReadUint16())
+	_actionnxregmove.DstOfs = uint16(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxregmove.Src = obj
+	}
+
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxregmove.Dst = obj
+	}
+
+	return _actionnxregmove, nil
+}
+
+func NewActionNxRegMove() *ActionNxRegMove {
+	obj := &ActionNxRegMove{
+		ActionNicira: NewActionNicira(6),
+	}
+	return obj
+}
+func (self *ActionNxRegMove) GetActionName() string {
+	return "nx_reg_move"
+}
+
+func (self *ActionNxRegMove) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"NBits":  self.NBits,
+		"SrcOfs": self.SrcOfs,
+		"DstOfs": self.DstOfs,
+		"Src":    self.Src,
+		"Dst":    self.Dst,
+	}
+}
+
+func (self *ActionNxRegMove) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxResubmit struct {
+	*ActionNicira
+	Value uint16
+}
+
+type IActionNxResubmit interface {
+	IActionNicira
+	GetValue() uint16
+}
+
+func (self *ActionNxResubmit) GetValue() uint16 {
+	return self.Value
+}
+
+func (self *ActionNxResubmit) SetValue(v uint16) {
+	self.Value = v
+}
+
+func (self *ActionNxResubmit) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Value))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxResubmit(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxResubmit, error) {
+	_actionnxresubmit := &ActionNxResubmit{ActionNicira: parent}
+	if decoder.Length() < 2 {
+		return nil, fmt.Errorf("ActionNxResubmit packet too short: %d < 2", decoder.Length())
+	}
+	_actionnxresubmit.Value = uint16(decoder.ReadUint16())
+	return _actionnxresubmit, nil
+}
+
+func NewActionNxResubmit() *ActionNxResubmit {
+	obj := &ActionNxResubmit{
+		ActionNicira: NewActionNicira(1),
+	}
+	return obj
+}
+func (self *ActionNxResubmit) GetActionName() string {
+	return "nx_resubmit"
+}
+
+func (self *ActionNxResubmit) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxResubmit) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxResubmitTable struct {
+	*ActionNicira
+	InPort uint16
+	Table  uint8
+}
+
+type IActionNxResubmitTable interface {
+	IActionNicira
+	GetInPort() uint16
+	GetTable() uint8
+}
+
+func (self *ActionNxResubmitTable) GetInPort() uint16 {
+	return self.InPort
+}
+
+func (self *ActionNxResubmitTable) SetInPort(v uint16) {
+	self.InPort = v
+}
+
+func (self *ActionNxResubmitTable) GetTable() uint8 {
+	return self.Table
+}
+
+func (self *ActionNxResubmitTable) SetTable(v uint8) {
+	self.Table = v
+}
+
+func (self *ActionNxResubmitTable) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.InPort))
+	encoder.PutUint8(uint8(self.Table))
+	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 DecodeActionNxResubmitTable(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxResubmitTable, error) {
+	_actionnxresubmittable := &ActionNxResubmitTable{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxResubmitTable packet too short: %d < 6", decoder.Length())
+	}
+	_actionnxresubmittable.InPort = uint16(decoder.ReadUint16())
+	_actionnxresubmittable.Table = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _actionnxresubmittable, nil
+}
+
+func NewActionNxResubmitTable() *ActionNxResubmitTable {
+	obj := &ActionNxResubmitTable{
+		ActionNicira: NewActionNicira(14),
+	}
+	return obj
+}
+func (self *ActionNxResubmitTable) GetActionName() string {
+	return "nx_resubmit_table"
+}
+
+func (self *ActionNxResubmitTable) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"InPort": self.InPort,
+		"Table":  self.Table,
+	}
+}
+
+func (self *ActionNxResubmitTable) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxResubmitTableCt struct {
+	*ActionNicira
+	InPort uint16
+	Table  uint8
+}
+
+type IActionNxResubmitTableCt interface {
+	IActionNicira
+	GetInPort() uint16
+	GetTable() uint8
+}
+
+func (self *ActionNxResubmitTableCt) GetInPort() uint16 {
+	return self.InPort
+}
+
+func (self *ActionNxResubmitTableCt) SetInPort(v uint16) {
+	self.InPort = v
+}
+
+func (self *ActionNxResubmitTableCt) GetTable() uint8 {
+	return self.Table
+}
+
+func (self *ActionNxResubmitTableCt) SetTable(v uint8) {
+	self.Table = v
+}
+
+func (self *ActionNxResubmitTableCt) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.InPort))
+	encoder.PutUint8(uint8(self.Table))
+	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 DecodeActionNxResubmitTableCt(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxResubmitTableCt, error) {
+	_actionnxresubmittablect := &ActionNxResubmitTableCt{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionNxResubmitTableCt packet too short: %d < 6", decoder.Length())
+	}
+	_actionnxresubmittablect.InPort = uint16(decoder.ReadUint16())
+	_actionnxresubmittablect.Table = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _actionnxresubmittablect, nil
+}
+
+func NewActionNxResubmitTableCt() *ActionNxResubmitTableCt {
+	obj := &ActionNxResubmitTableCt{
+		ActionNicira: NewActionNicira(44),
+	}
+	return obj
+}
+func (self *ActionNxResubmitTableCt) GetActionName() string {
+	return "nx_resubmit_table_ct"
+}
+
+func (self *ActionNxResubmitTableCt) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"InPort": self.InPort,
+		"Table":  self.Table,
+	}
+}
+
+func (self *ActionNxResubmitTableCt) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSample struct {
+	*ActionNicira
+	Probability    uint16
+	CollectorSetId uint32
+	ObsDomainId    uint32
+	ObsPointId     uint32
+}
+
+type IActionNxSample interface {
+	IActionNicira
+	GetProbability() uint16
+	GetCollectorSetId() uint32
+	GetObsDomainId() uint32
+	GetObsPointId() uint32
+}
+
+func (self *ActionNxSample) GetProbability() uint16 {
+	return self.Probability
+}
+
+func (self *ActionNxSample) SetProbability(v uint16) {
+	self.Probability = v
+}
+
+func (self *ActionNxSample) GetCollectorSetId() uint32 {
+	return self.CollectorSetId
+}
+
+func (self *ActionNxSample) SetCollectorSetId(v uint32) {
+	self.CollectorSetId = v
+}
+
+func (self *ActionNxSample) GetObsDomainId() uint32 {
+	return self.ObsDomainId
+}
+
+func (self *ActionNxSample) SetObsDomainId(v uint32) {
+	self.ObsDomainId = v
+}
+
+func (self *ActionNxSample) GetObsPointId() uint32 {
+	return self.ObsPointId
+}
+
+func (self *ActionNxSample) SetObsPointId(v uint32) {
+	self.ObsPointId = v
+}
+
+func (self *ActionNxSample) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Probability))
+	encoder.PutUint32(uint32(self.CollectorSetId))
+	encoder.PutUint32(uint32(self.ObsDomainId))
+	encoder.PutUint32(uint32(self.ObsPointId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxSample(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSample, error) {
+	_actionnxsample := &ActionNxSample{ActionNicira: parent}
+	if decoder.Length() < 14 {
+		return nil, fmt.Errorf("ActionNxSample packet too short: %d < 14", decoder.Length())
+	}
+	_actionnxsample.Probability = uint16(decoder.ReadUint16())
+	_actionnxsample.CollectorSetId = uint32(decoder.ReadUint32())
+	_actionnxsample.ObsDomainId = uint32(decoder.ReadUint32())
+	_actionnxsample.ObsPointId = uint32(decoder.ReadUint32())
+	return _actionnxsample, nil
+}
+
+func NewActionNxSample() *ActionNxSample {
+	obj := &ActionNxSample{
+		ActionNicira: NewActionNicira(29),
+	}
+	return obj
+}
+func (self *ActionNxSample) GetActionName() string {
+	return "nx_sample"
+}
+
+func (self *ActionNxSample) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Probability":    self.Probability,
+		"CollectorSetId": self.CollectorSetId,
+		"ObsDomainId":    self.ObsDomainId,
+		"ObsPointId":     self.ObsPointId,
+	}
+}
+
+func (self *ActionNxSample) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSample2 struct {
+	*ActionNicira
+	Probability    uint16
+	CollectorSetId uint32
+	ObsDomainId    uint32
+	ObsPointId     uint32
+	SamplingPort   uint16
+	Direction      uint8
+}
+
+type IActionNxSample2 interface {
+	IActionNicira
+	GetProbability() uint16
+	GetCollectorSetId() uint32
+	GetObsDomainId() uint32
+	GetObsPointId() uint32
+	GetSamplingPort() uint16
+	GetDirection() uint8
+}
+
+func (self *ActionNxSample2) GetProbability() uint16 {
+	return self.Probability
+}
+
+func (self *ActionNxSample2) SetProbability(v uint16) {
+	self.Probability = v
+}
+
+func (self *ActionNxSample2) GetCollectorSetId() uint32 {
+	return self.CollectorSetId
+}
+
+func (self *ActionNxSample2) SetCollectorSetId(v uint32) {
+	self.CollectorSetId = v
+}
+
+func (self *ActionNxSample2) GetObsDomainId() uint32 {
+	return self.ObsDomainId
+}
+
+func (self *ActionNxSample2) SetObsDomainId(v uint32) {
+	self.ObsDomainId = v
+}
+
+func (self *ActionNxSample2) GetObsPointId() uint32 {
+	return self.ObsPointId
+}
+
+func (self *ActionNxSample2) SetObsPointId(v uint32) {
+	self.ObsPointId = v
+}
+
+func (self *ActionNxSample2) GetSamplingPort() uint16 {
+	return self.SamplingPort
+}
+
+func (self *ActionNxSample2) SetSamplingPort(v uint16) {
+	self.SamplingPort = v
+}
+
+func (self *ActionNxSample2) GetDirection() uint8 {
+	return self.Direction
+}
+
+func (self *ActionNxSample2) SetDirection(v uint8) {
+	self.Direction = v
+}
+
+func (self *ActionNxSample2) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Probability))
+	encoder.PutUint32(uint32(self.CollectorSetId))
+	encoder.PutUint32(uint32(self.ObsDomainId))
+	encoder.PutUint32(uint32(self.ObsPointId))
+	encoder.PutUint16(uint16(self.SamplingPort))
+	encoder.PutUint8(uint8(self.Direction))
+	encoder.Write(bytes.Repeat([]byte{0}, 5))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxSample2(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSample2, error) {
+	_actionnxsample2 := &ActionNxSample2{ActionNicira: parent}
+	if decoder.Length() < 22 {
+		return nil, fmt.Errorf("ActionNxSample2 packet too short: %d < 22", decoder.Length())
+	}
+	_actionnxsample2.Probability = uint16(decoder.ReadUint16())
+	_actionnxsample2.CollectorSetId = uint32(decoder.ReadUint32())
+	_actionnxsample2.ObsDomainId = uint32(decoder.ReadUint32())
+	_actionnxsample2.ObsPointId = uint32(decoder.ReadUint32())
+	_actionnxsample2.SamplingPort = uint16(decoder.ReadUint16())
+	_actionnxsample2.Direction = uint8(decoder.ReadByte())
+	decoder.Skip(5)
+	return _actionnxsample2, nil
+}
+
+func NewActionNxSample2() *ActionNxSample2 {
+	obj := &ActionNxSample2{
+		ActionNicira: NewActionNicira(38),
+	}
+	return obj
+}
+func (self *ActionNxSample2) GetActionName() string {
+	return "nx_sample2"
+}
+
+func (self *ActionNxSample2) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Probability":    self.Probability,
+		"CollectorSetId": self.CollectorSetId,
+		"ObsDomainId":    self.ObsDomainId,
+		"ObsPointId":     self.ObsPointId,
+		"SamplingPort":   self.SamplingPort,
+		"Direction":      self.Direction,
+	}
+}
+
+func (self *ActionNxSample2) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSample3 struct {
+	*ActionNicira
+	Probability    uint16
+	CollectorSetId uint32
+	ObsDomainId    uint32
+	ObsPointId     uint32
+	SamplingPort   uint16
+	Direction      uint8
+}
+
+type IActionNxSample3 interface {
+	IActionNicira
+	GetProbability() uint16
+	GetCollectorSetId() uint32
+	GetObsDomainId() uint32
+	GetObsPointId() uint32
+	GetSamplingPort() uint16
+	GetDirection() uint8
+}
+
+func (self *ActionNxSample3) GetProbability() uint16 {
+	return self.Probability
+}
+
+func (self *ActionNxSample3) SetProbability(v uint16) {
+	self.Probability = v
+}
+
+func (self *ActionNxSample3) GetCollectorSetId() uint32 {
+	return self.CollectorSetId
+}
+
+func (self *ActionNxSample3) SetCollectorSetId(v uint32) {
+	self.CollectorSetId = v
+}
+
+func (self *ActionNxSample3) GetObsDomainId() uint32 {
+	return self.ObsDomainId
+}
+
+func (self *ActionNxSample3) SetObsDomainId(v uint32) {
+	self.ObsDomainId = v
+}
+
+func (self *ActionNxSample3) GetObsPointId() uint32 {
+	return self.ObsPointId
+}
+
+func (self *ActionNxSample3) SetObsPointId(v uint32) {
+	self.ObsPointId = v
+}
+
+func (self *ActionNxSample3) GetSamplingPort() uint16 {
+	return self.SamplingPort
+}
+
+func (self *ActionNxSample3) SetSamplingPort(v uint16) {
+	self.SamplingPort = v
+}
+
+func (self *ActionNxSample3) GetDirection() uint8 {
+	return self.Direction
+}
+
+func (self *ActionNxSample3) SetDirection(v uint8) {
+	self.Direction = v
+}
+
+func (self *ActionNxSample3) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Probability))
+	encoder.PutUint32(uint32(self.CollectorSetId))
+	encoder.PutUint32(uint32(self.ObsDomainId))
+	encoder.PutUint32(uint32(self.ObsPointId))
+	encoder.PutUint16(uint16(self.SamplingPort))
+	encoder.PutUint8(uint8(self.Direction))
+	encoder.Write(bytes.Repeat([]byte{0}, 5))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxSample3(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSample3, error) {
+	_actionnxsample3 := &ActionNxSample3{ActionNicira: parent}
+	if decoder.Length() < 22 {
+		return nil, fmt.Errorf("ActionNxSample3 packet too short: %d < 22", decoder.Length())
+	}
+	_actionnxsample3.Probability = uint16(decoder.ReadUint16())
+	_actionnxsample3.CollectorSetId = uint32(decoder.ReadUint32())
+	_actionnxsample3.ObsDomainId = uint32(decoder.ReadUint32())
+	_actionnxsample3.ObsPointId = uint32(decoder.ReadUint32())
+	_actionnxsample3.SamplingPort = uint16(decoder.ReadUint16())
+	_actionnxsample3.Direction = uint8(decoder.ReadByte())
+	decoder.Skip(5)
+	return _actionnxsample3, nil
+}
+
+func NewActionNxSample3() *ActionNxSample3 {
+	obj := &ActionNxSample3{
+		ActionNicira: NewActionNicira(41),
+	}
+	return obj
+}
+func (self *ActionNxSample3) GetActionName() string {
+	return "nx_sample3"
+}
+
+func (self *ActionNxSample3) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Probability":    self.Probability,
+		"CollectorSetId": self.CollectorSetId,
+		"ObsDomainId":    self.ObsDomainId,
+		"ObsPointId":     self.ObsPointId,
+		"SamplingPort":   self.SamplingPort,
+		"Direction":      self.Direction,
+	}
+}
+
+func (self *ActionNxSample3) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSetMplsLabel struct {
+	*ActionNicira
+	Value uint32
+}
+
+type IActionNxSetMplsLabel interface {
+	IActionNicira
+	GetValue() uint32
+}
+
+func (self *ActionNxSetMplsLabel) GetValue() uint32 {
+	return self.Value
+}
+
+func (self *ActionNxSetMplsLabel) SetValue(v uint32) {
+	self.Value = v
+}
+
+func (self *ActionNxSetMplsLabel) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxSetMplsLabel(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSetMplsLabel, error) {
+	_actionnxsetmplslabel := &ActionNxSetMplsLabel{ActionNicira: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionNxSetMplsLabel packet too short: %d < 4", decoder.Length())
+	}
+	_actionnxsetmplslabel.Value = uint32(decoder.ReadUint32())
+	return _actionnxsetmplslabel, nil
+}
+
+func NewActionNxSetMplsLabel() *ActionNxSetMplsLabel {
+	obj := &ActionNxSetMplsLabel{
+		ActionNicira: NewActionNicira(30),
+	}
+	return obj
+}
+func (self *ActionNxSetMplsLabel) GetActionName() string {
+	return "nx_set_mpls_label"
+}
+
+func (self *ActionNxSetMplsLabel) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxSetMplsLabel) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSetMplsTc struct {
+	*ActionNicira
+	Value uint8
+}
+
+type IActionNxSetMplsTc interface {
+	IActionNicira
+	GetValue() uint8
+}
+
+func (self *ActionNxSetMplsTc) GetValue() uint8 {
+	return self.Value
+}
+
+func (self *ActionNxSetMplsTc) SetValue(v uint8) {
+	self.Value = v
+}
+
+func (self *ActionNxSetMplsTc) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Value))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxSetMplsTc(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSetMplsTc, error) {
+	_actionnxsetmplstc := &ActionNxSetMplsTc{ActionNicira: parent}
+	if decoder.Length() < 1 {
+		return nil, fmt.Errorf("ActionNxSetMplsTc packet too short: %d < 1", decoder.Length())
+	}
+	_actionnxsetmplstc.Value = uint8(decoder.ReadByte())
+	return _actionnxsetmplstc, nil
+}
+
+func NewActionNxSetMplsTc() *ActionNxSetMplsTc {
+	obj := &ActionNxSetMplsTc{
+		ActionNicira: NewActionNicira(31),
+	}
+	return obj
+}
+func (self *ActionNxSetMplsTc) GetActionName() string {
+	return "nx_set_mpls_tc"
+}
+
+func (self *ActionNxSetMplsTc) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxSetMplsTc) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSetMplsTtl struct {
+	*ActionNicira
+	Value uint8
+}
+
+type IActionNxSetMplsTtl interface {
+	IActionNicira
+	GetValue() uint8
+}
+
+func (self *ActionNxSetMplsTtl) GetValue() uint8 {
+	return self.Value
+}
+
+func (self *ActionNxSetMplsTtl) SetValue(v uint8) {
+	self.Value = v
+}
+
+func (self *ActionNxSetMplsTtl) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.Value))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxSetMplsTtl(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSetMplsTtl, error) {
+	_actionnxsetmplsttl := &ActionNxSetMplsTtl{ActionNicira: parent}
+	if decoder.Length() < 1 {
+		return nil, fmt.Errorf("ActionNxSetMplsTtl packet too short: %d < 1", decoder.Length())
+	}
+	_actionnxsetmplsttl.Value = uint8(decoder.ReadByte())
+	return _actionnxsetmplsttl, nil
+}
+
+func NewActionNxSetMplsTtl() *ActionNxSetMplsTtl {
+	obj := &ActionNxSetMplsTtl{
+		ActionNicira: NewActionNicira(25),
+	}
+	return obj
+}
+func (self *ActionNxSetMplsTtl) GetActionName() string {
+	return "nx_set_mpls_ttl"
+}
+
+func (self *ActionNxSetMplsTtl) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxSetMplsTtl) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSetQueue struct {
+	*ActionNicira
+	Value uint32
+}
+
+type IActionNxSetQueue interface {
+	IActionNicira
+	GetValue() uint32
+}
+
+func (self *ActionNxSetQueue) GetValue() uint32 {
+	return self.Value
+}
+
+func (self *ActionNxSetQueue) SetValue(v uint32) {
+	self.Value = v
+}
+
+func (self *ActionNxSetQueue) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxSetQueue(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSetQueue, error) {
+	_actionnxsetqueue := &ActionNxSetQueue{ActionNicira: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionNxSetQueue packet too short: %d < 4", decoder.Length())
+	}
+	_actionnxsetqueue.Value = uint32(decoder.ReadUint32())
+	return _actionnxsetqueue, nil
+}
+
+func NewActionNxSetQueue() *ActionNxSetQueue {
+	obj := &ActionNxSetQueue{
+		ActionNicira: NewActionNicira(4),
+	}
+	return obj
+}
+func (self *ActionNxSetQueue) GetActionName() string {
+	return "nx_set_queue"
+}
+
+func (self *ActionNxSetQueue) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxSetQueue) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSetTunnel struct {
+	*ActionNicira
+	Value uint32
+}
+
+type IActionNxSetTunnel interface {
+	IActionNicira
+	GetValue() uint32
+}
+
+func (self *ActionNxSetTunnel) GetValue() uint32 {
+	return self.Value
+}
+
+func (self *ActionNxSetTunnel) SetValue(v uint32) {
+	self.Value = v
+}
+
+func (self *ActionNxSetTunnel) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.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 DecodeActionNxSetTunnel(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSetTunnel, error) {
+	_actionnxsettunnel := &ActionNxSetTunnel{ActionNicira: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionNxSetTunnel packet too short: %d < 4", decoder.Length())
+	}
+	_actionnxsettunnel.Value = uint32(decoder.ReadUint32())
+	return _actionnxsettunnel, nil
+}
+
+func NewActionNxSetTunnel() *ActionNxSetTunnel {
+	obj := &ActionNxSetTunnel{
+		ActionNicira: NewActionNicira(2),
+	}
+	return obj
+}
+func (self *ActionNxSetTunnel) GetActionName() string {
+	return "nx_set_tunnel"
+}
+
+func (self *ActionNxSetTunnel) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxSetTunnel) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxSetTunnel64 struct {
+	*ActionNicira
+	Value uint64
+}
+
+type IActionNxSetTunnel64 interface {
+	IActionNicira
+	GetValue() uint64
+}
+
+func (self *ActionNxSetTunnel64) GetValue() uint64 {
+	return self.Value
+}
+
+func (self *ActionNxSetTunnel64) SetValue(v uint64) {
+	self.Value = v
+}
+
+func (self *ActionNxSetTunnel64) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint64(uint64(self.Value))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxSetTunnel64(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxSetTunnel64, error) {
+	_actionnxsettunnel64 := &ActionNxSetTunnel64{ActionNicira: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("ActionNxSetTunnel64 packet too short: %d < 8", decoder.Length())
+	}
+	_actionnxsettunnel64.Value = uint64(decoder.ReadUint64())
+	return _actionnxsettunnel64, nil
+}
+
+func NewActionNxSetTunnel64() *ActionNxSetTunnel64 {
+	obj := &ActionNxSetTunnel64{
+		ActionNicira: NewActionNicira(9),
+	}
+	return obj
+}
+func (self *ActionNxSetTunnel64) GetActionName() string {
+	return "nx_set_tunnel64"
+}
+
+func (self *ActionNxSetTunnel64) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Value": self.Value,
+	}
+}
+
+func (self *ActionNxSetTunnel64) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxStackPop struct {
+	*ActionNicira
+	Offset uint16
+	Field  goloxi.IOxmId
+	NBits  uint16
+}
+
+type IActionNxStackPop interface {
+	IActionNicira
+	GetOffset() uint16
+	GetField() goloxi.IOxmId
+	GetNBits() uint16
+}
+
+func (self *ActionNxStackPop) GetOffset() uint16 {
+	return self.Offset
+}
+
+func (self *ActionNxStackPop) SetOffset(v uint16) {
+	self.Offset = v
+}
+
+func (self *ActionNxStackPop) GetField() goloxi.IOxmId {
+	return self.Field
+}
+
+func (self *ActionNxStackPop) SetField(v goloxi.IOxmId) {
+	self.Field = v
+}
+
+func (self *ActionNxStackPop) GetNBits() uint16 {
+	return self.NBits
+}
+
+func (self *ActionNxStackPop) SetNBits(v uint16) {
+	self.NBits = v
+}
+
+func (self *ActionNxStackPop) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Offset))
+	self.Field.Serialize(encoder)
+	encoder.PutUint16(uint16(self.NBits))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxStackPop(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxStackPop, error) {
+	_actionnxstackpop := &ActionNxStackPop{ActionNicira: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("ActionNxStackPop packet too short: %d < 8", decoder.Length())
+	}
+	_actionnxstackpop.Offset = uint16(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxstackpop.Field = obj
+	}
+
+	_actionnxstackpop.NBits = uint16(decoder.ReadUint16())
+	return _actionnxstackpop, nil
+}
+
+func NewActionNxStackPop() *ActionNxStackPop {
+	obj := &ActionNxStackPop{
+		ActionNicira: NewActionNicira(28),
+	}
+	return obj
+}
+func (self *ActionNxStackPop) GetActionName() string {
+	return "nx_stack_pop"
+}
+
+func (self *ActionNxStackPop) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Offset": self.Offset,
+		"Field":  self.Field,
+		"NBits":  self.NBits,
+	}
+}
+
+func (self *ActionNxStackPop) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxStackPush struct {
+	*ActionNicira
+	Offset uint16
+	Field  goloxi.IOxmId
+	NBits  uint16
+}
+
+type IActionNxStackPush interface {
+	IActionNicira
+	GetOffset() uint16
+	GetField() goloxi.IOxmId
+	GetNBits() uint16
+}
+
+func (self *ActionNxStackPush) GetOffset() uint16 {
+	return self.Offset
+}
+
+func (self *ActionNxStackPush) SetOffset(v uint16) {
+	self.Offset = v
+}
+
+func (self *ActionNxStackPush) GetField() goloxi.IOxmId {
+	return self.Field
+}
+
+func (self *ActionNxStackPush) SetField(v goloxi.IOxmId) {
+	self.Field = v
+}
+
+func (self *ActionNxStackPush) GetNBits() uint16 {
+	return self.NBits
+}
+
+func (self *ActionNxStackPush) SetNBits(v uint16) {
+	self.NBits = v
+}
+
+func (self *ActionNxStackPush) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Offset))
+	self.Field.Serialize(encoder)
+	encoder.PutUint16(uint16(self.NBits))
+	length := len(encoder.Bytes()) - startIndex
+	alignedLength := ((length + 23) / 24 * 24)
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	encoder.Write(bytes.Repeat([]byte{0}, alignedLength-length))
+
+	return nil
+}
+
+func DecodeActionNxStackPush(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxStackPush, error) {
+	_actionnxstackpush := &ActionNxStackPush{ActionNicira: parent}
+	if decoder.Length() < 8 {
+		return nil, fmt.Errorf("ActionNxStackPush packet too short: %d < 8", decoder.Length())
+	}
+	_actionnxstackpush.Offset = uint16(decoder.ReadUint16())
+	if obj, err := DecodeOxmId(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionnxstackpush.Field = obj
+	}
+
+	_actionnxstackpush.NBits = uint16(decoder.ReadUint16())
+	return _actionnxstackpush, nil
+}
+
+func NewActionNxStackPush() *ActionNxStackPush {
+	obj := &ActionNxStackPush{
+		ActionNicira: NewActionNicira(27),
+	}
+	return obj
+}
+func (self *ActionNxStackPush) GetActionName() string {
+	return "nx_stack_push"
+}
+
+func (self *ActionNxStackPush) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Offset": self.Offset,
+		"Field":  self.Field,
+		"NBits":  self.NBits,
+	}
+}
+
+func (self *ActionNxStackPush) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionNxWriteMetadata struct {
+	*ActionNicira
+	Metadata uint64
+	Mask     uint64
+}
+
+type IActionNxWriteMetadata interface {
+	IActionNicira
+	GetMetadata() uint64
+	GetMask() uint64
+}
+
+func (self *ActionNxWriteMetadata) GetMetadata() uint64 {
+	return self.Metadata
+}
+
+func (self *ActionNxWriteMetadata) SetMetadata(v uint64) {
+	self.Metadata = v
+}
+
+func (self *ActionNxWriteMetadata) GetMask() uint64 {
+	return self.Mask
+}
+
+func (self *ActionNxWriteMetadata) SetMask(v uint64) {
+	self.Mask = v
+}
+
+func (self *ActionNxWriteMetadata) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.Write(bytes.Repeat([]byte{0}, 6))
+	encoder.PutUint64(uint64(self.Metadata))
+	encoder.PutUint64(uint64(self.Mask))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionNxWriteMetadata(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionNxWriteMetadata, error) {
+	_actionnxwritemetadata := &ActionNxWriteMetadata{ActionNicira: parent}
+	if decoder.Length() < 22 {
+		return nil, fmt.Errorf("ActionNxWriteMetadata packet too short: %d < 22", decoder.Length())
+	}
+	decoder.Skip(6)
+	_actionnxwritemetadata.Metadata = uint64(decoder.ReadUint64())
+	_actionnxwritemetadata.Mask = uint64(decoder.ReadUint64())
+	return _actionnxwritemetadata, nil
+}
+
+func NewActionNxWriteMetadata() *ActionNxWriteMetadata {
+	obj := &ActionNxWriteMetadata{
+		ActionNicira: NewActionNicira(22),
+	}
+	return obj
+}
+func (self *ActionNxWriteMetadata) GetActionName() string {
+	return "nx_write_metadata"
+}
+
+func (self *ActionNxWriteMetadata) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Metadata": self.Metadata,
+		"Mask":     self.Mask,
+	}
+}
+
+func (self *ActionNxWriteMetadata) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionOutput struct {
+	*Action
+	Port   Port
+	MaxLen uint16
+}
+
+type IActionOutput interface {
+	goloxi.IAction
+	GetPort() Port
+	GetMaxLen() uint16
+}
+
+func (self *ActionOutput) GetPort() Port {
+	return self.Port
+}
+
+func (self *ActionOutput) SetPort(v Port) {
+	self.Port = v
+}
+
+func (self *ActionOutput) GetMaxLen() uint16 {
+	return self.MaxLen
+}
+
+func (self *ActionOutput) SetMaxLen(v uint16) {
+	self.MaxLen = v
+}
+
+func (self *ActionOutput) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.Port.Serialize(encoder)
+	encoder.PutUint16(uint16(self.MaxLen))
+	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 DecodeActionOutput(parent *Action, decoder *goloxi.Decoder) (*ActionOutput, error) {
+	_actionoutput := &ActionOutput{Action: parent}
+	if decoder.Length() < 12 {
+		return nil, fmt.Errorf("ActionOutput packet too short: %d < 12", decoder.Length())
+	}
+	_actionoutput.Port.Decode(decoder)
+	_actionoutput.MaxLen = uint16(decoder.ReadUint16())
+	decoder.Skip(6)
+	return _actionoutput, nil
+}
+
+func NewActionOutput() *ActionOutput {
+	obj := &ActionOutput{
+		Action: NewAction(0),
+	}
+	return obj
+}
+func (self *ActionOutput) GetActionName() string {
+	return "output"
+}
+
+func (self *ActionOutput) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Port":   self.Port,
+		"MaxLen": self.MaxLen,
+	}
+}
+
+func (self *ActionOutput) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionPopMpls struct {
+	*Action
+	Ethertype uint16
+}
+
+type IActionPopMpls interface {
+	goloxi.IAction
+	GetEthertype() uint16
+}
+
+func (self *ActionPopMpls) GetEthertype() uint16 {
+	return self.Ethertype
+}
+
+func (self *ActionPopMpls) SetEthertype(v uint16) {
+	self.Ethertype = v
+}
+
+func (self *ActionPopMpls) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Ethertype))
+	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 DecodeActionPopMpls(parent *Action, decoder *goloxi.Decoder) (*ActionPopMpls, error) {
+	_actionpopmpls := &ActionPopMpls{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionPopMpls packet too short: %d < 4", decoder.Length())
+	}
+	_actionpopmpls.Ethertype = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	return _actionpopmpls, nil
+}
+
+func NewActionPopMpls() *ActionPopMpls {
+	obj := &ActionPopMpls{
+		Action: NewAction(20),
+	}
+	return obj
+}
+func (self *ActionPopMpls) GetActionName() string {
+	return "pop_mpls"
+}
+
+func (self *ActionPopMpls) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Ethertype": self.Ethertype,
+	}
+}
+
+func (self *ActionPopMpls) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionPopPbb struct {
+	*Action
+}
+
+type IActionPopPbb interface {
+	goloxi.IAction
+}
+
+func (self *ActionPopPbb) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.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 DecodeActionPopPbb(parent *Action, decoder *goloxi.Decoder) (*ActionPopPbb, error) {
+	_actionpoppbb := &ActionPopPbb{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionPopPbb packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _actionpoppbb, nil
+}
+
+func NewActionPopPbb() *ActionPopPbb {
+	obj := &ActionPopPbb{
+		Action: NewAction(27),
+	}
+	return obj
+}
+func (self *ActionPopPbb) GetActionName() string {
+	return "pop_pbb"
+}
+
+func (self *ActionPopPbb) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionPopPbb) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionPopVlan struct {
+	*Action
+}
+
+type IActionPopVlan interface {
+	goloxi.IAction
+}
+
+func (self *ActionPopVlan) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.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 DecodeActionPopVlan(parent *Action, decoder *goloxi.Decoder) (*ActionPopVlan, error) {
+	_actionpopvlan := &ActionPopVlan{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionPopVlan packet too short: %d < 4", decoder.Length())
+	}
+	decoder.Skip(4)
+	return _actionpopvlan, nil
+}
+
+func NewActionPopVlan() *ActionPopVlan {
+	obj := &ActionPopVlan{
+		Action: NewAction(18),
+	}
+	return obj
+}
+func (self *ActionPopVlan) GetActionName() string {
+	return "pop_vlan"
+}
+
+func (self *ActionPopVlan) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{}
+}
+
+func (self *ActionPopVlan) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionPushMpls struct {
+	*Action
+	Ethertype uint16
+}
+
+type IActionPushMpls interface {
+	goloxi.IAction
+	GetEthertype() uint16
+}
+
+func (self *ActionPushMpls) GetEthertype() uint16 {
+	return self.Ethertype
+}
+
+func (self *ActionPushMpls) SetEthertype(v uint16) {
+	self.Ethertype = v
+}
+
+func (self *ActionPushMpls) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Ethertype))
+	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 DecodeActionPushMpls(parent *Action, decoder *goloxi.Decoder) (*ActionPushMpls, error) {
+	_actionpushmpls := &ActionPushMpls{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionPushMpls packet too short: %d < 4", decoder.Length())
+	}
+	_actionpushmpls.Ethertype = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	return _actionpushmpls, nil
+}
+
+func NewActionPushMpls() *ActionPushMpls {
+	obj := &ActionPushMpls{
+		Action: NewAction(19),
+	}
+	return obj
+}
+func (self *ActionPushMpls) GetActionName() string {
+	return "push_mpls"
+}
+
+func (self *ActionPushMpls) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Ethertype": self.Ethertype,
+	}
+}
+
+func (self *ActionPushMpls) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionPushPbb struct {
+	*Action
+	Ethertype uint16
+}
+
+type IActionPushPbb interface {
+	goloxi.IAction
+	GetEthertype() uint16
+}
+
+func (self *ActionPushPbb) GetEthertype() uint16 {
+	return self.Ethertype
+}
+
+func (self *ActionPushPbb) SetEthertype(v uint16) {
+	self.Ethertype = v
+}
+
+func (self *ActionPushPbb) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Ethertype))
+	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 DecodeActionPushPbb(parent *Action, decoder *goloxi.Decoder) (*ActionPushPbb, error) {
+	_actionpushpbb := &ActionPushPbb{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionPushPbb packet too short: %d < 4", decoder.Length())
+	}
+	_actionpushpbb.Ethertype = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	return _actionpushpbb, nil
+}
+
+func NewActionPushPbb() *ActionPushPbb {
+	obj := &ActionPushPbb{
+		Action: NewAction(26),
+	}
+	return obj
+}
+func (self *ActionPushPbb) GetActionName() string {
+	return "push_pbb"
+}
+
+func (self *ActionPushPbb) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Ethertype": self.Ethertype,
+	}
+}
+
+func (self *ActionPushPbb) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionPushVlan struct {
+	*Action
+	Ethertype uint16
+}
+
+type IActionPushVlan interface {
+	goloxi.IAction
+	GetEthertype() uint16
+}
+
+func (self *ActionPushVlan) GetEthertype() uint16 {
+	return self.Ethertype
+}
+
+func (self *ActionPushVlan) SetEthertype(v uint16) {
+	self.Ethertype = v
+}
+
+func (self *ActionPushVlan) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.Ethertype))
+	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 DecodeActionPushVlan(parent *Action, decoder *goloxi.Decoder) (*ActionPushVlan, error) {
+	_actionpushvlan := &ActionPushVlan{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionPushVlan packet too short: %d < 4", decoder.Length())
+	}
+	_actionpushvlan.Ethertype = uint16(decoder.ReadUint16())
+	decoder.Skip(2)
+	return _actionpushvlan, nil
+}
+
+func NewActionPushVlan() *ActionPushVlan {
+	obj := &ActionPushVlan{
+		Action: NewAction(17),
+	}
+	return obj
+}
+func (self *ActionPushVlan) GetActionName() string {
+	return "push_vlan"
+}
+
+func (self *ActionPushVlan) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Ethertype": self.Ethertype,
+	}
+}
+
+func (self *ActionPushVlan) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionResubmit struct {
+	*ActionNicira
+	InPort uint16
+	Table  uint8
+}
+
+type IActionResubmit interface {
+	IActionNicira
+	GetInPort() uint16
+	GetTable() uint8
+}
+
+func (self *ActionResubmit) GetInPort() uint16 {
+	return self.InPort
+}
+
+func (self *ActionResubmit) SetInPort(v uint16) {
+	self.InPort = v
+}
+
+func (self *ActionResubmit) GetTable() uint8 {
+	return self.Table
+}
+
+func (self *ActionResubmit) SetTable(v uint8) {
+	self.Table = v
+}
+
+func (self *ActionResubmit) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.ActionNicira.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint16(uint16(self.InPort))
+	encoder.PutUint8(uint8(self.Table))
+	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 DecodeActionResubmit(parent *ActionNicira, decoder *goloxi.Decoder) (*ActionResubmit, error) {
+	_actionresubmit := &ActionResubmit{ActionNicira: parent}
+	if decoder.Length() < 6 {
+		return nil, fmt.Errorf("ActionResubmit packet too short: %d < 6", decoder.Length())
+	}
+	_actionresubmit.InPort = uint16(decoder.ReadUint16())
+	_actionresubmit.Table = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _actionresubmit, nil
+}
+
+func NewActionResubmit() *ActionResubmit {
+	obj := &ActionResubmit{
+		ActionNicira: NewActionNicira(14),
+	}
+	return obj
+}
+func (self *ActionResubmit) GetActionName() string {
+	return "resubmit"
+}
+
+func (self *ActionResubmit) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"InPort": self.InPort,
+		"Table":  self.Table,
+	}
+}
+
+func (self *ActionResubmit) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionSetField struct {
+	*Action
+	Field goloxi.IOxm
+}
+
+type IActionSetField interface {
+	goloxi.IAction
+	GetField() goloxi.IOxm
+}
+
+func (self *ActionSetField) GetField() goloxi.IOxm {
+	return self.Field
+}
+
+func (self *ActionSetField) SetField(v goloxi.IOxm) {
+	self.Field = v
+}
+
+func (self *ActionSetField) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	self.Field.Serialize(encoder)
+	length := len(encoder.Bytes()) - startIndex
+	alignedLength := ((length + 7) / 8 * 8)
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(alignedLength))
+
+	encoder.Write(bytes.Repeat([]byte{0}, alignedLength-length))
+
+	return nil
+}
+
+func DecodeActionSetField(parent *Action, decoder *goloxi.Decoder) (*ActionSetField, error) {
+	_actionsetfield := &ActionSetField{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionSetField packet too short: %d < 4", decoder.Length())
+	}
+	if obj, err := DecodeOxm(decoder); err != nil {
+		return nil, err
+	} else {
+		_actionsetfield.Field = obj
+	}
+
+	return _actionsetfield, nil
+}
+
+func NewActionSetField() *ActionSetField {
+	obj := &ActionSetField{
+		Action: NewAction(25),
+	}
+	return obj
+}
+func (self *ActionSetField) GetActionName() string {
+	return "set_field"
+}
+
+func (self *ActionSetField) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"Field": self.Field,
+	}
+}
+
+func (self *ActionSetField) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionSetMplsTtl struct {
+	*Action
+	MplsTtl uint8
+}
+
+type IActionSetMplsTtl interface {
+	goloxi.IAction
+	GetMplsTtl() uint8
+}
+
+func (self *ActionSetMplsTtl) GetMplsTtl() uint8 {
+	return self.MplsTtl
+}
+
+func (self *ActionSetMplsTtl) SetMplsTtl(v uint8) {
+	self.MplsTtl = v
+}
+
+func (self *ActionSetMplsTtl) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.MplsTtl))
+	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 DecodeActionSetMplsTtl(parent *Action, decoder *goloxi.Decoder) (*ActionSetMplsTtl, error) {
+	_actionsetmplsttl := &ActionSetMplsTtl{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionSetMplsTtl packet too short: %d < 4", decoder.Length())
+	}
+	_actionsetmplsttl.MplsTtl = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _actionsetmplsttl, nil
+}
+
+func NewActionSetMplsTtl() *ActionSetMplsTtl {
+	obj := &ActionSetMplsTtl{
+		Action: NewAction(15),
+	}
+	return obj
+}
+func (self *ActionSetMplsTtl) GetActionName() string {
+	return "set_mpls_ttl"
+}
+
+func (self *ActionSetMplsTtl) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"MplsTtl": self.MplsTtl,
+	}
+}
+
+func (self *ActionSetMplsTtl) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionSetNwTtl struct {
+	*Action
+	NwTtl uint8
+}
+
+type IActionSetNwTtl interface {
+	goloxi.IAction
+	GetNwTtl() uint8
+}
+
+func (self *ActionSetNwTtl) GetNwTtl() uint8 {
+	return self.NwTtl
+}
+
+func (self *ActionSetNwTtl) SetNwTtl(v uint8) {
+	self.NwTtl = v
+}
+
+func (self *ActionSetNwTtl) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint8(uint8(self.NwTtl))
+	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 DecodeActionSetNwTtl(parent *Action, decoder *goloxi.Decoder) (*ActionSetNwTtl, error) {
+	_actionsetnwttl := &ActionSetNwTtl{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionSetNwTtl packet too short: %d < 4", decoder.Length())
+	}
+	_actionsetnwttl.NwTtl = uint8(decoder.ReadByte())
+	decoder.Skip(3)
+	return _actionsetnwttl, nil
+}
+
+func NewActionSetNwTtl() *ActionSetNwTtl {
+	obj := &ActionSetNwTtl{
+		Action: NewAction(23),
+	}
+	return obj
+}
+func (self *ActionSetNwTtl) GetActionName() string {
+	return "set_nw_ttl"
+}
+
+func (self *ActionSetNwTtl) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"NwTtl": self.NwTtl,
+	}
+}
+
+func (self *ActionSetNwTtl) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
+
+type ActionSetQueue struct {
+	*Action
+	QueueId uint32
+}
+
+type IActionSetQueue interface {
+	goloxi.IAction
+	GetQueueId() uint32
+}
+
+func (self *ActionSetQueue) GetQueueId() uint32 {
+	return self.QueueId
+}
+
+func (self *ActionSetQueue) SetQueueId(v uint32) {
+	self.QueueId = v
+}
+
+func (self *ActionSetQueue) Serialize(encoder *goloxi.Encoder) error {
+	startIndex := len(encoder.Bytes())
+	if err := self.Action.Serialize(encoder); err != nil {
+		return err
+	}
+
+	encoder.PutUint32(uint32(self.QueueId))
+	length := len(encoder.Bytes()) - startIndex
+
+	binary.BigEndian.PutUint16(encoder.Bytes()[startIndex+2:startIndex+4], uint16(length))
+
+	return nil
+}
+
+func DecodeActionSetQueue(parent *Action, decoder *goloxi.Decoder) (*ActionSetQueue, error) {
+	_actionsetqueue := &ActionSetQueue{Action: parent}
+	if decoder.Length() < 4 {
+		return nil, fmt.Errorf("ActionSetQueue packet too short: %d < 4", decoder.Length())
+	}
+	_actionsetqueue.QueueId = uint32(decoder.ReadUint32())
+	return _actionsetqueue, nil
+}
+
+func NewActionSetQueue() *ActionSetQueue {
+	obj := &ActionSetQueue{
+		Action: NewAction(21),
+	}
+	return obj
+}
+func (self *ActionSetQueue) GetActionName() string {
+	return "set_queue"
+}
+
+func (self *ActionSetQueue) GetActionFields() map[string]interface{} {
+	return map[string]interface{}{
+		"QueueId": self.QueueId,
+	}
+}
+
+func (self *ActionSetQueue) MarshalJSON() ([]byte, error) {
+	jsonValue, err := json.Marshal(self.GetActionFields())
+	if err != nil {
+		return nil, err
+	}
+	return []byte(fmt.Sprintf("{\"Type\":\"%s\",\"Arguments\":%s}", self.GetActionName(), string(jsonValue))), nil
+}
