backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / ofproto / nx_actions.py
diff --git a/ryu/build/lib.linux-armv7l-2.7/ryu/ofproto/nx_actions.py b/ryu/build/lib.linux-armv7l-2.7/ryu/ofproto/nx_actions.py
new file mode 100644 (file)
index 0000000..7f54347
--- /dev/null
@@ -0,0 +1,3095 @@
+# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
+# Copyright (C) 2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import six
+
+import struct
+
+from ryu import utils
+from ryu.lib import type_desc
+from ryu.ofproto import nicira_ext
+from ryu.ofproto import ofproto_common
+from ryu.lib.pack_utils import msg_pack_into
+from ryu.ofproto.ofproto_parser import StringifyMixin
+
+
+def generate(ofp_name, ofpp_name):
+    import sys
+
+    ofp = sys.modules[ofp_name]
+    ofpp = sys.modules[ofpp_name]
+
+    class _NXFlowSpec(StringifyMixin):
+        _hdr_fmt_str = '!H'  # 2 bit 0s, 1 bit src, 2 bit dst, 11 bit n_bits
+        _dst_type = None
+        _subclasses = {}
+        _TYPE = {
+            'nx-flow-spec-field': [
+                'src',
+                'dst',
+            ]
+        }
+
+        def __init__(self, src, dst, n_bits):
+            self.src = src
+            self.dst = dst
+            self.n_bits = n_bits
+
+        @classmethod
+        def register(cls, subcls):
+            assert issubclass(subcls, cls)
+            assert subcls._dst_type not in cls._subclasses
+            cls._subclasses[subcls._dst_type] = subcls
+
+        @classmethod
+        def parse(cls, buf):
+            (hdr,) = struct.unpack_from(cls._hdr_fmt_str, buf, 0)
+            rest = buf[struct.calcsize(cls._hdr_fmt_str):]
+            if hdr == 0:
+                return None, rest  # all-0 header is no-op for padding
+            src_type = (hdr >> 13) & 0x1
+            dst_type = (hdr >> 11) & 0x3
+            n_bits = hdr & 0x3ff
+            subcls = cls._subclasses[dst_type]
+            if src_type == 0:  # subfield
+                src = cls._parse_subfield(rest)
+                rest = rest[6:]
+            elif src_type == 1:  # immediate
+                src_len = (n_bits + 15) // 16 * 2
+                src_bin = rest[:src_len]
+                src = type_desc.IntDescr(size=src_len).to_user(src_bin)
+                rest = rest[src_len:]
+            if dst_type == 0:  # match
+                dst = cls._parse_subfield(rest)
+                rest = rest[6:]
+            elif dst_type == 1:  # load
+                dst = cls._parse_subfield(rest)
+                rest = rest[6:]
+            elif dst_type == 2:  # output
+                dst = ''  # empty
+            return subcls(src=src, dst=dst, n_bits=n_bits), rest
+
+        def serialize(self):
+            buf = bytearray()
+            if isinstance(self.src, tuple):
+                src_type = 0  # subfield
+            else:
+                src_type = 1  # immediate
+            # header
+            val = (src_type << 13) | (self._dst_type << 11) | self.n_bits
+            msg_pack_into(self._hdr_fmt_str, buf, 0, val)
+            # src
+            if src_type == 0:  # subfield
+                buf += self._serialize_subfield(self.src)
+            elif src_type == 1:  # immediate
+                src_len = (self.n_bits + 15) // 16 * 2
+                buf += type_desc.IntDescr(size=src_len).from_user(self.src)
+            # dst
+            if self._dst_type == 0:  # match
+                buf += self._serialize_subfield(self.dst)
+            elif self._dst_type == 1:  # load
+                buf += self._serialize_subfield(self.dst)
+            elif self._dst_type == 2:  # output
+                pass  # empty
+            return buf
+
+        @staticmethod
+        def _parse_subfield(buf):
+            (n, len) = ofp.oxm_parse_header(buf, 0)
+            assert len == 4  # only 4-bytes NXM/OXM are defined
+            field = ofp.oxm_to_user_header(n)
+            rest = buf[len:]
+            (ofs,) = struct.unpack_from('!H', rest, 0)
+            return (field, ofs)
+
+        @staticmethod
+        def _serialize_subfield(subfield):
+            (field, ofs) = subfield
+            buf = bytearray()
+            n = ofp.oxm_from_user_header(field)
+            ofp.oxm_serialize_header(n, buf, 0)
+            assert len(buf) == 4  # only 4-bytes NXM/OXM are defined
+            msg_pack_into('!H', buf, 4, ofs)
+            return buf
+
+    class NXFlowSpecMatch(_NXFlowSpec):
+        """
+        Specification for adding match criterion
+
+        This class is used by ``NXActionLearn``.
+
+        For the usage of this class, please refer to ``NXActionLearn``.
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        src              OXM/NXM header and Start bit for source field
+        dst              OXM/NXM header and Start bit for destination field
+        n_bits           The number of bits from the start bit
+        ================ ======================================================
+        """
+        # Add a match criteria
+        # an example of the corresponding ovs-ofctl syntax:
+        #    NXM_OF_VLAN_TCI[0..11]
+        _dst_type = 0
+
+    class NXFlowSpecLoad(_NXFlowSpec):
+        """
+        Add NXAST_REG_LOAD actions
+
+        This class is used by ``NXActionLearn``.
+
+        For the usage of this class, please refer to ``NXActionLearn``.
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        src              OXM/NXM header and Start bit for source field
+        dst              OXM/NXM header and Start bit for destination field
+        n_bits           The number of bits from the start bit
+        ================ ======================================================
+        """
+        # Add NXAST_REG_LOAD actions
+        # an example of the corresponding ovs-ofctl syntax:
+        #    NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]
+        _dst_type = 1
+
+    class NXFlowSpecOutput(_NXFlowSpec):
+        """
+        Add an OFPAT_OUTPUT action
+
+        This class is used by ``NXActionLearn``.
+
+        For the usage of this class, please refer to ``NXActionLearn``.
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        src              OXM/NXM header and Start bit for source field
+        dst              Must be ''
+        n_bits           The number of bits from the start bit
+        ================ ======================================================
+        """
+        # Add an OFPAT_OUTPUT action
+        # an example of the corresponding ovs-ofctl syntax:
+        #    output:NXM_OF_IN_PORT[]
+        _dst_type = 2
+
+        def __init__(self, src, n_bits, dst=''):
+            assert dst == ''
+            super(NXFlowSpecOutput, self).__init__(src=src, dst=dst,
+                                                   n_bits=n_bits)
+
+    class NXAction(ofpp.OFPActionExperimenter):
+        _fmt_str = '!H'  # subtype
+        _subtypes = {}
+        _experimenter = ofproto_common.NX_EXPERIMENTER_ID
+
+        def __init__(self):
+            super(NXAction, self).__init__(self._experimenter)
+            self.subtype = self._subtype
+
+        @classmethod
+        def parse(cls, buf):
+            fmt_str = NXAction._fmt_str
+            (subtype,) = struct.unpack_from(fmt_str, buf, 0)
+            subtype_cls = cls._subtypes.get(subtype)
+            rest = buf[struct.calcsize(fmt_str):]
+            if subtype_cls is None:
+                return NXActionUnknown(subtype, rest)
+            return subtype_cls.parser(rest)
+
+        def serialize(self, buf, offset):
+            data = self.serialize_body()
+            payload_offset = (
+                ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE +
+                struct.calcsize(NXAction._fmt_str)
+            )
+            self.len = utils.round_up(payload_offset + len(data), 8)
+            super(NXAction, self).serialize(buf, offset)
+            msg_pack_into(NXAction._fmt_str,
+                          buf,
+                          offset + ofp.OFP_ACTION_EXPERIMENTER_HEADER_SIZE,
+                          self.subtype)
+            buf += data
+
+        @classmethod
+        def register(cls, subtype_cls):
+            assert subtype_cls._subtype is not cls._subtypes
+            cls._subtypes[subtype_cls._subtype] = subtype_cls
+
+    class NXActionUnknown(NXAction):
+        def __init__(self, subtype, data=None,
+                     type_=None, len_=None, experimenter=None):
+            self._subtype = subtype
+            super(NXActionUnknown, self).__init__()
+            self.data = data
+
+        @classmethod
+        def parser(cls, buf):
+            return cls(data=buf)
+
+        def serialize_body(self):
+            # fixup
+            return bytearray() if self.data is None else self.data
+
+    # For OpenFlow1.0 only
+    class NXActionSetQueue(NXAction):
+        r"""
+        Set queue action
+
+        This action sets the queue that should be used to queue
+        when packets are output.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          set_queue:queue
+        ..
+
+        +-------------------------+
+        | **set_queue**\:\ *queue*|
+        +-------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        queue_id         Queue ID for the packets
+        ================ ======================================================
+
+        .. note::
+            This actions is supported by
+            ``OFPActionSetQueue``
+            in OpenFlow1.2 or later.
+
+        Example::
+
+            actions += [parser.NXActionSetQueue(queue_id=10)]
+        """
+        _subtype = nicira_ext.NXAST_SET_QUEUE
+
+        # queue_id
+        _fmt_str = '!2xI'
+
+        def __init__(self, queue_id,
+                     type_=None, len_=None, vendor=None, subtype=None):
+            super(NXActionSetQueue, self).__init__()
+            self.queue_id = queue_id
+
+        @classmethod
+        def parser(cls, buf):
+            (queue_id,) = struct.unpack_from(cls._fmt_str, buf, 0)
+            return cls(queue_id)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0, self.queue_id)
+            return data
+
+    class NXActionPopQueue(NXAction):
+        """
+        Pop queue action
+
+        This action restors the queue to the value it was before any
+        set_queue actions were applied.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          pop_queue
+        ..
+
+        +---------------+
+        | **pop_queue** |
+        +---------------+
+
+        Example::
+
+            actions += [parser.NXActionPopQueue()]
+        """
+        _subtype = nicira_ext.NXAST_POP_QUEUE
+
+        _fmt_str = '!6x'
+
+        def __init__(self,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionPopQueue, self).__init__()
+
+        @classmethod
+        def parser(cls, buf):
+            return cls()
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0)
+            return data
+
+    class NXActionRegLoad(NXAction):
+        r"""
+        Load literal value action
+
+        This action loads a literal value into a field or part of a field.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          load:value->dst[start..end]
+        ..
+
+        +-----------------------------------------------------------------+
+        | **load**\:\ *value*\->\ *dst*\ **[**\ *start*\..\ *end*\ **]**  |
+        +-----------------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        ofs_nbits        Start and End for the OXM/NXM field.
+                         Setting method refer to the ``nicira_ext.ofs_nbits``
+        dst              OXM/NXM header for destination field
+        value            OXM/NXM value to be loaded
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionRegLoad(
+                            ofs_nbits=nicira_ext.ofs_nbits(4, 31),
+                            dst="eth_dst",
+                            value=0x112233)]
+        """
+        _subtype = nicira_ext.NXAST_REG_LOAD
+        _fmt_str = '!HIQ'  # ofs_nbits, dst, value
+        _TYPE = {
+            'ascii': [
+                'dst',
+            ]
+        }
+
+        def __init__(self, ofs_nbits, dst, value,
+                     type_=None, len_=None, experimenter=None,
+                     subtype=None):
+            super(NXActionRegLoad, self).__init__()
+            self.ofs_nbits = ofs_nbits
+            self.dst = dst
+            self.value = value
+
+        @classmethod
+        def parser(cls, buf):
+            (ofs_nbits, dst, value,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            # Right-shift instead of using oxm_parse_header for simplicity...
+            dst_name = ofp.oxm_to_user_header(dst >> 9)
+            return cls(ofs_nbits, dst_name, value)
+
+        def serialize_body(self):
+            hdr_data = bytearray()
+            n = ofp.oxm_from_user_header(self.dst)
+            ofp.oxm_serialize_header(n, hdr_data, 0)
+            (dst_num,) = struct.unpack_from('!I', six.binary_type(hdr_data), 0)
+
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.ofs_nbits, dst_num, self.value)
+            return data
+
+    class NXActionRegLoad2(NXAction):
+        r"""
+        Load literal value action
+
+        This action loads a literal value into a field or part of a field.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          set_field:value[/mask]->dst
+        ..
+
+        +------------------------------------------------------------+
+        | **set_field**\:\ *value*\ **[**\/\ *mask*\ **]**\->\ *dst* |
+        +------------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        value            OXM/NXM value to be loaded
+        mask             Mask for destination field
+        dst              OXM/NXM header for destination field
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionRegLoad2(dst="tun_ipv4_src",
+                                                value="192.168.10.0",
+                                                mask="255.255.255.0")]
+        """
+        _subtype = nicira_ext.NXAST_REG_LOAD2
+        _TYPE = {
+            'ascii': [
+                'dst',
+                'value',
+            ]
+        }
+
+        def __init__(self, dst, value, mask=None,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionRegLoad2, self).__init__()
+            self.dst = dst
+            self.value = value
+            self.mask = mask
+
+        @classmethod
+        def parser(cls, buf):
+            (n, uv, mask, _len) = ofp.oxm_parse(buf, 0)
+            dst, value = ofp.oxm_to_user(n, uv, mask)
+
+            if isinstance(value, (tuple, list)):
+                return cls(dst, value[0], value[1])
+            else:
+                return cls(dst, value, None)
+
+        def serialize_body(self):
+            data = bytearray()
+            if self.mask is None:
+                value = self.value
+            else:
+                value = (self.value, self.mask)
+                self._TYPE['ascii'].append('mask')
+
+            n, value, mask = ofp.oxm_from_user(self.dst, value)
+            len_ = ofp.oxm_serialize(n, value, mask, data, 0)
+            msg_pack_into("!%dx" % (14 - len_), data, len_)
+
+            return data
+
+    class NXActionNote(NXAction):
+        r"""
+        Note action
+
+        This action does nothing at all.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          note:[hh]..
+        ..
+
+        +-----------------------------------+
+        | **note**\:\ **[**\ *hh*\ **]**\.. |
+        +-----------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        note             A list of integer type values
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionNote(note=[0xaa,0xbb,0xcc,0xdd])]
+        """
+        _subtype = nicira_ext.NXAST_NOTE
+
+        # note
+        _fmt_str = '!%dB'
+
+        # set the integer array in a note
+        def __init__(self,
+                     note,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionNote, self).__init__()
+            self.note = note
+
+        @classmethod
+        def parser(cls, buf):
+            note = struct.unpack_from(
+                cls._fmt_str % len(buf), buf, 0)
+            return cls(list(note))
+
+        def serialize_body(self):
+            assert isinstance(self.note, (tuple, list))
+            for n in self.note:
+                assert isinstance(n, six.integer_types)
+
+            pad = (len(self.note) + nicira_ext.NX_ACTION_HEADER_0_SIZE) % 8
+            if pad:
+                self.note += [0x0 for i in range(8 - pad)]
+            note_len = len(self.note)
+            data = bytearray()
+            msg_pack_into(self._fmt_str % note_len, data, 0,
+                          *self.note)
+            return data
+
+    class _NXActionSetTunnelBase(NXAction):
+        # _subtype, _fmt_str must be attributes of subclass.
+
+        def __init__(self,
+                     tun_id,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(_NXActionSetTunnelBase, self).__init__()
+            self.tun_id = tun_id
+
+        @classmethod
+        def parser(cls, buf):
+            (tun_id,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return cls(tun_id)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.tun_id)
+            return data
+
+    class NXActionSetTunnel(_NXActionSetTunnelBase):
+        r"""
+        Set Tunnel action
+
+        This action sets the identifier (such as GRE) to the specified id.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        .. note::
+            This actions is supported by
+            ``OFPActionSetField``
+            in OpenFlow1.2 or later.
+
+        ..
+          set_tunnel:id
+        ..
+
+        +------------------------+
+        | **set_tunnel**\:\ *id* |
+        +------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        tun_id           Tunnel ID(32bits)
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionSetTunnel(tun_id=0xa)]
+        """
+        _subtype = nicira_ext.NXAST_SET_TUNNEL
+
+        # tun_id
+        _fmt_str = '!2xI'
+
+    class NXActionSetTunnel64(_NXActionSetTunnelBase):
+        r"""
+        Set Tunnel action
+
+        This action outputs to a port that encapsulates
+        the packet in a tunnel.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        .. note::
+            This actions is supported by
+            ``OFPActionSetField``
+            in OpenFlow1.2 or later.
+
+        ..
+          set_tunnel64:id
+        ..
+
+        +--------------------------+
+        | **set_tunnel64**\:\ *id* |
+        +--------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        tun_id           Tunnel ID(64bits)
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionSetTunnel64(tun_id=0xa)]
+        """
+        _subtype = nicira_ext.NXAST_SET_TUNNEL64
+
+        # tun_id
+        _fmt_str = '!6xQ'
+
+    class NXActionRegMove(NXAction):
+        r"""
+        Move register action
+
+        This action copies the src to dst.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          move:src[start..end]->dst[start..end]
+        ..
+
+        +--------------------------------------------------------+
+        | **move**\:\ *src*\ **[**\ *start*\..\ *end*\ **]**\->\ |
+        | *dst*\ **[**\ *start*\..\ *end* \ **]**                |
+        +--------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        src_field        OXM/NXM header for source field
+        dst_field        OXM/NXM header for destination field
+        n_bits           Number of bits
+        src_ofs          Starting bit offset in source
+        dst_ofs          Starting bit offset in destination
+        ================ ======================================================
+
+        .. CAUTION::
+            **src_start**\  and \ **src_end**\  difference and \ **dst_start**\
+             and \ **dst_end**\  difference must be the same.
+
+        Example::
+
+            actions += [parser.NXActionRegMove(src_field="reg0",
+                                               dst_field="reg1",
+                                               n_bits=5,
+                                               src_ofs=0
+                                               dst_ofs=10)]
+        """
+        _subtype = nicira_ext.NXAST_REG_MOVE
+        _fmt_str = '!HHH'  # n_bits, src_ofs, dst_ofs
+        # Followed by OXM fields (src, dst) and padding to 8 bytes boundary
+        _TYPE = {
+            'ascii': [
+                'src_field',
+                'dst_field',
+            ]
+        }
+
+        def __init__(self, src_field, dst_field, n_bits, src_ofs=0, dst_ofs=0,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionRegMove, self).__init__()
+            self.n_bits = n_bits
+            self.src_ofs = src_ofs
+            self.dst_ofs = dst_ofs
+            self.src_field = src_field
+            self.dst_field = dst_field
+
+        @classmethod
+        def parser(cls, buf):
+            (n_bits, src_ofs, dst_ofs,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            rest = buf[struct.calcsize(NXActionRegMove._fmt_str):]
+
+            # src field
+            (n, len) = ofp.oxm_parse_header(rest, 0)
+            src_field = ofp.oxm_to_user_header(n)
+            rest = rest[len:]
+            # dst field
+            (n, len) = ofp.oxm_parse_header(rest, 0)
+            dst_field = ofp.oxm_to_user_header(n)
+            rest = rest[len:]
+            # ignore padding
+            return cls(src_field, dst_field=dst_field, n_bits=n_bits,
+                       src_ofs=src_ofs, dst_ofs=dst_ofs)
+
+        def serialize_body(self):
+            # fixup
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.n_bits, self.src_ofs, self.dst_ofs)
+            # src field
+            n = ofp.oxm_from_user_header(self.src_field)
+            ofp.oxm_serialize_header(n, data, len(data))
+            # dst field
+            n = ofp.oxm_from_user_header(self.dst_field)
+            ofp.oxm_serialize_header(n, data, len(data))
+            return data
+
+    class NXActionResubmit(NXAction):
+        r"""
+        Resubmit action
+
+        This action searches one of the switch's flow tables.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          resubmit:port
+        ..
+
+        +------------------------+
+        | **resubmit**\:\ *port* |
+        +------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        in_port          New in_port for checking flow table
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionResubmit(in_port=8080)]
+        """
+        _subtype = nicira_ext.NXAST_RESUBMIT
+
+        # in_port
+        _fmt_str = '!H4x'
+
+        def __init__(self,
+                     in_port=0xfff8,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionResubmit, self).__init__()
+            self.in_port = in_port
+
+        @classmethod
+        def parser(cls, buf):
+            (in_port,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return cls(in_port)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.in_port)
+            return data
+
+    class NXActionResubmitTable(NXAction):
+        r"""
+        Resubmit action
+
+        This action searches one of the switch's flow tables.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          resubmit([port],[table])
+        ..
+
+        +------------------------------------------------+
+        | **resubmit(**\[\ *port*\]\,[\ *table*\]\ **)** |
+        +------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        in_port          New in_port for checking flow table
+        table_id         Checking flow tables
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionResubmit(in_port=8080,
+                                                table_id=10)]
+        """
+        _subtype = nicira_ext.NXAST_RESUBMIT_TABLE
+
+        # in_port, table_id
+        _fmt_str = '!HB3x'
+
+        def __init__(self,
+                     in_port=0xfff8,
+                     table_id=0xff,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionResubmitTable, self).__init__()
+            self.in_port = in_port
+            self.table_id = table_id
+
+        @classmethod
+        def parser(cls, buf):
+            (in_port,
+             table_id) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return cls(in_port, table_id)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.in_port, self.table_id)
+            return data
+
+    class NXActionOutputReg(NXAction):
+        r"""
+        Add output action
+
+        This action outputs the packet to the OpenFlow port number read from
+        src.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          output:src[start...end]
+        ..
+
+        +-------------------------------------------------------+
+        | **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
+        +-------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        ofs_nbits        Start and End for the OXM/NXM field.
+                         Setting method refer to the ``nicira_ext.ofs_nbits``
+        src              OXM/NXM header for source field
+        max_len          Max length to send to controller
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionOutputReg(
+                            ofs_nbits=nicira_ext.ofs_nbits(4, 31),
+                            src="reg0",
+                            max_len=1024)]
+        """
+        _subtype = nicira_ext.NXAST_OUTPUT_REG
+
+        # ofs_nbits, src, max_len
+        _fmt_str = '!H4sH6x'
+        _TYPE = {
+            'ascii': [
+                'src',
+            ]
+        }
+
+        def __init__(self,
+                     ofs_nbits,
+                     src,
+                     max_len,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionOutputReg, self).__init__()
+            self.ofs_nbits = ofs_nbits
+            self.src = src
+            self.max_len = max_len
+
+        @classmethod
+        def parser(cls, buf):
+            (ofs_nbits, oxm_data, max_len) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
+            src = ofp.oxm_to_user_header(n)
+            return cls(ofs_nbits,
+                       src,
+                       max_len)
+
+        def serialize_body(self):
+            data = bytearray()
+            src = bytearray()
+            oxm = ofp.oxm_from_user_header(self.src)
+            ofp.oxm_serialize_header(oxm, src, 0),
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.ofs_nbits,
+                          six.binary_type(src),
+                          self.max_len)
+            return data
+
+    class NXActionOutputReg2(NXAction):
+        r"""
+        Add output action
+
+        This action outputs the packet to the OpenFlow port number read from
+        src.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          output:src[start...end]
+        ..
+
+        +-------------------------------------------------------+
+        | **output**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
+        +-------------------------------------------------------+
+
+        .. NOTE::
+             Like the ``NXActionOutputReg`` but organized so
+             that there is room for a 64-bit experimenter OXM as 'src'.
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        ofs_nbits        Start and End for the OXM/NXM field.
+                         Setting method refer to the ``nicira_ext.ofs_nbits``
+        src              OXM/NXM header for source field
+        max_len          Max length to send to controller
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionOutputReg2(
+                            ofs_nbits=nicira_ext.ofs_nbits(4, 31),
+                            src="reg0",
+                            max_len=1024)]
+        """
+        _subtype = nicira_ext.NXAST_OUTPUT_REG2
+
+        # ofs_nbits, src, max_len
+        _fmt_str = '!HH4s'
+        _TYPE = {
+            'ascii': [
+                'src',
+            ]
+        }
+
+        def __init__(self,
+                     ofs_nbits,
+                     src,
+                     max_len,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionOutputReg2, self).__init__()
+            self.ofs_nbits = ofs_nbits
+            self.src = src
+            self.max_len = max_len
+
+        @classmethod
+        def parser(cls, buf):
+            (ofs_nbits,
+             max_len,
+             oxm_data) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
+            src = ofp.oxm_to_user_header(n)
+            return cls(ofs_nbits,
+                       src,
+                       max_len)
+
+        def serialize_body(self):
+            data = bytearray()
+            oxm_data = bytearray()
+            oxm = ofp.oxm_from_user_header(self.src)
+            ofp.oxm_serialize_header(oxm, oxm_data, 0),
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.ofs_nbits,
+                          self.max_len,
+                          six.binary_type(oxm_data))
+            offset = len(data)
+            msg_pack_into("!%dx" % (14 - offset), data, offset)
+            return data
+
+    class NXActionLearn(NXAction):
+        r"""
+        Adds or modifies flow action
+
+        This action adds or modifies a flow in OpenFlow table.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          learn(argument[,argument]...)
+        ..
+
+        +---------------------------------------------------+
+        | **learn(**\ *argument*\[,\ *argument*\]...\ **)** |
+        +---------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        table_id         The table in which the new flow should be inserted
+        specs            Adds a match criterion to the new flow
+
+                         Please use the
+                         ``NXFlowSpecMatch``
+                         in order to set the following format
+
+                         ..
+                           field=value
+                           field[start..end]=src[start..end]
+                           field[start..end]
+                         ..
+
+                         | *field*\=\ *value*
+                         | *field*\ **[**\ *start*\..\ *end*\ **]**\  =\
+                         *src*\ **[**\ *start*\..\ *end*\ **]**
+                         | *field*\ **[**\ *start*\..\ *end*\ **]**
+                         |
+
+                         Please use the
+                         ``NXFlowSpecLoad``
+                         in order to set the following format
+
+                         ..
+                           load:value->dst[start..end]
+                           load:src[start..end]->dst[start..end]
+                         ..
+
+                         | **load**\:\ *value*\ **->**\ *dst*\
+                         **[**\ *start*\..\ *end*\ **]**
+                         | **load**\:\ *src*\ **[**\ *start*\..\ *end*\
+                         **] ->**\ *dst*\ **[**\ *start*\..\ *end*\ **]**
+                         |
+
+                         Please use the
+                         ``NXFlowSpecOutput``
+                         in order to set the following format
+
+                         ..
+                           output:field[start..end]
+                         ..
+
+                         | **output:**\ field\ **[**\ *start*\..\ *end*\ **]**
+
+        idle_timeout     Idle time before discarding(seconds)
+        hard_timeout     Max time before discarding(seconds)
+        priority         Priority level of flow entry
+        cookie           Cookie for new flow
+        flags            send_flow_rem
+        fin_idle_timeout Idle timeout after FIN(seconds)
+        fin_hard_timeout Hard timeout after FIN(seconds)
+        ================ ======================================================
+
+        .. CAUTION::
+            The arguments specify the flow's match fields, actions,
+            and other properties, as follows.
+            At least one match criterion and one action argument
+            should ordinarily be specified.
+
+        Example::
+
+            actions += [
+                parser.NXActionLearn(able_id=10,
+                     specs=[parser.NXFlowSpecMatch(src=0x800,
+                                                   dst=('eth_type_nxm', 0),
+                                                   n_bits=16),
+                            parser.NXFlowSpecMatch(src=('reg1', 1),
+                                                   dst=('reg2', 3),
+                                                   n_bits=5),
+                            parser.NXFlowSpecMatch(src=('reg3', 1),
+                                                   dst=('reg3', 1),
+                                                   n_bits=5),
+                            parser.NXFlowSpecLoad(src=0,
+                                                  dst=('reg4', 3),
+                                                  n_bits=5),
+                            parser.NXFlowSpecLoad(src=('reg5', 1),
+                                                  dst=('reg6', 3),
+                                                  n_bits=5),
+                            parser.NXFlowSpecOutput(src=('reg7', 1),
+                                                    dst="",
+                                                    n_bits=5)],
+                     idle_timeout=180,
+                     hard_timeout=300,
+                     priority=1,
+                     cookie=0x64,
+                     flags=ofproto.OFPFF_SEND_FLOW_REM,
+                     fin_idle_timeout=180,
+                     fin_hard_timeout=300)]
+        """
+        _subtype = nicira_ext.NXAST_LEARN
+
+        # idle_timeout, hard_timeout, priority, cookie, flags,
+        # table_id, pad, fin_idle_timeout, fin_hard_timeout
+        _fmt_str = '!HHHQHBxHH'
+        # Followed by flow_mod_specs
+
+        def __init__(self,
+                     table_id,
+                     specs,
+                     idle_timeout=0,
+                     hard_timeout=0,
+                     priority=ofp.OFP_DEFAULT_PRIORITY,
+                     cookie=0,
+                     flags=0,
+                     fin_idle_timeout=0,
+                     fin_hard_timeout=0,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionLearn, self).__init__()
+            self.idle_timeout = idle_timeout
+            self.hard_timeout = hard_timeout
+            self.priority = priority
+            self.cookie = cookie
+            self.flags = flags
+            self.table_id = table_id
+            self.fin_idle_timeout = fin_idle_timeout
+            self.fin_hard_timeout = fin_hard_timeout
+            self.specs = specs
+
+        @classmethod
+        def parser(cls, buf):
+            (idle_timeout,
+             hard_timeout,
+             priority,
+             cookie,
+             flags,
+             table_id,
+             fin_idle_timeout,
+             fin_hard_timeout,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            rest = buf[struct.calcsize(cls._fmt_str):]
+            # specs
+            specs = []
+            while len(rest) > 0:
+                spec, rest = _NXFlowSpec.parse(rest)
+                if spec is None:
+                    continue
+                specs.append(spec)
+            return cls(idle_timeout=idle_timeout,
+                       hard_timeout=hard_timeout,
+                       priority=priority,
+                       cookie=cookie,
+                       flags=flags,
+                       table_id=table_id,
+                       fin_idle_timeout=fin_idle_timeout,
+                       fin_hard_timeout=fin_hard_timeout,
+                       specs=specs)
+
+        def serialize_body(self):
+            # fixup
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.idle_timeout,
+                          self.hard_timeout,
+                          self.priority,
+                          self.cookie,
+                          self.flags,
+                          self.table_id,
+                          self.fin_idle_timeout,
+                          self.fin_hard_timeout)
+            for spec in self.specs:
+                data += spec.serialize()
+            return data
+
+    class NXActionExit(NXAction):
+        """
+        Halt action
+
+        This action causes OpenvSwitch to immediately halt
+        execution of further actions.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          exit
+        ..
+
+        +----------+
+        | **exit** |
+        +----------+
+
+        Example::
+
+            actions += [parser.NXActionExit()]
+        """
+        _subtype = nicira_ext.NXAST_EXIT
+
+        _fmt_str = '!6x'
+
+        def __init__(self,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionExit, self).__init__()
+
+        @classmethod
+        def parser(cls, buf):
+            return cls()
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0)
+            return data
+
+    # For OpenFlow1.0 only
+    class NXActionDecTtl(NXAction):
+        """
+        Decrement IP TTL action
+
+        This action decrements TTL of IPv4 packet or
+        hop limit of IPv6 packet.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          dec_ttl
+        ..
+
+        +-------------+
+        | **dec_ttl** |
+        +-------------+
+
+        .. NOTE::
+            This actions is supported by
+            ``OFPActionDecNwTtl``
+            in OpenFlow1.2 or later.
+
+        Example::
+
+            actions += [parser.NXActionDecTtl()]
+        """
+        _subtype = nicira_ext.NXAST_DEC_TTL
+
+        _fmt_str = '!6x'
+
+        def __init__(self,
+                     type_=None, len_=None, vendor=None, subtype=None):
+            super(NXActionDecTtl, self).__init__()
+
+        @classmethod
+        def parser(cls, buf):
+            return cls()
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0)
+            return data
+
+    class NXActionController(NXAction):
+        r"""
+        Send packet in message action
+
+        This action sends the packet to the OpenFlow controller as
+        a packet in message.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          controller(key=value...)
+        ..
+
+        +----------------------------------------------+
+        | **controller(**\ *key*\=\ *value*\...\ **)** |
+        +----------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        max_len          Max length to send to controller
+        controller_id    Controller ID to send packet-in
+        reason           Reason for sending the message
+        ================ ======================================================
+
+        Example::
+
+            actions += [
+                parser.NXActionController(max_len=1024,
+                                          controller_id=1,
+                                          reason=ofproto.OFPR_INVALID_TTL)]
+        """
+        _subtype = nicira_ext.NXAST_CONTROLLER
+
+        # max_len, controller_id, reason
+        _fmt_str = '!HHBx'
+
+        def __init__(self,
+                     max_len,
+                     controller_id,
+                     reason,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionController, self).__init__()
+            self.max_len = max_len
+            self.controller_id = controller_id
+            self.reason = reason
+
+        @classmethod
+        def parser(cls, buf):
+            (max_len,
+             controller_id,
+             reason) = struct.unpack_from(
+                cls._fmt_str, buf)
+            return cls(max_len,
+                       controller_id,
+                       reason)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.max_len,
+                          self.controller_id,
+                          self.reason)
+            return data
+
+    class NXActionController2(NXAction):
+        r"""
+        Send packet in message action
+
+        This action sends the packet to the OpenFlow controller as
+        a packet in message.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          controller(key=value...)
+        ..
+
+        +----------------------------------------------+
+        | **controller(**\ *key*\=\ *value*\...\ **)** |
+        +----------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        max_len          Max length to send to controller
+        controller_id    Controller ID to send packet-in
+        reason           Reason for sending the message
+        userdata         Additional data to the controller in the packet-in
+                         message
+        pause            Flag to pause pipeline to resume later
+        ================ ======================================================
+
+        Example::
+
+            actions += [
+                parser.NXActionController(max_len=1024,
+                                          controller_id=1,
+                                          reason=ofproto.OFPR_INVALID_TTL,
+                                          userdata=[0xa,0xb,0xc],
+                                          pause=True)]
+        """
+        _subtype = nicira_ext.NXAST_CONTROLLER2
+        _fmt_str = '!6x'
+        _PACK_STR = '!HH'
+
+        def __init__(self,
+                     type_=None, len_=None, vendor=None, subtype=None,
+                     **kwargs):
+            super(NXActionController2, self).__init__()
+
+            for arg in kwargs:
+                if arg in NXActionController2Prop._NAMES:
+                    setattr(self, arg, kwargs[arg])
+
+        @classmethod
+        def parser(cls, buf):
+            cls_data = {}
+            offset = 6
+            buf_len = len(buf)
+            while buf_len > offset:
+                (type_, length) = struct.unpack_from(cls._PACK_STR, buf, offset)
+                offset += 4
+                try:
+                    subcls = NXActionController2Prop._TYPES[type_]
+                except KeyError:
+                    subcls = NXActionController2PropUnknown
+                data, size = subcls.parser_prop(buf[offset:], length - 4)
+                offset += size
+                cls_data[subcls._arg_name] = data
+            return cls(**cls_data)
+
+        def serialize_body(self):
+            body = bytearray()
+            msg_pack_into(self._fmt_str, body, 0)
+            prop_list = []
+            for arg in self.__dict__:
+                if arg in NXActionController2Prop._NAMES:
+                    prop_list.append((NXActionController2Prop._NAMES[arg],
+                                      self.__dict__[arg]))
+            prop_list.sort(key=lambda x: x[0].type)
+
+            for subcls, value in prop_list:
+                body += subcls.serialize_prop(value)
+
+            return body
+
+    class NXActionController2Prop(object):
+        _TYPES = {}
+        _NAMES = {}
+
+        @classmethod
+        def register_type(cls, type_):
+            def _register_type(subcls):
+                subcls.type = type_
+                NXActionController2Prop._TYPES[type_] = subcls
+                NXActionController2Prop._NAMES[subcls._arg_name] = subcls
+                return subcls
+
+            return _register_type
+
+    class NXActionController2PropUnknown(NXActionController2Prop):
+
+        @classmethod
+        def parser_prop(cls, buf, length):
+            size = 4
+            return buf, size
+
+        @classmethod
+        def serialize_prop(cls, argment):
+            data = bytearray()
+            return data
+
+    @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_MAX_LEN)
+    class NXActionController2PropMaxLen(NXActionController2Prop):
+        # max_len
+        _fmt_str = "!H2x"
+        _arg_name = "max_len"
+
+        @classmethod
+        def parser_prop(cls, buf, length):
+            size = 4
+            (max_len,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return max_len, size
+
+        @classmethod
+        def serialize_prop(cls, max_len):
+            data = bytearray()
+            msg_pack_into("!HHH2x", data, 0,
+                          nicira_ext.NXAC2PT_MAX_LEN,
+                          8,
+                          max_len)
+            return data
+
+    @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_CONTROLLER_ID)
+    class NXActionController2PropControllerId(NXActionController2Prop):
+        # controller_id
+        _fmt_str = "!H2x"
+        _arg_name = "controller_id"
+
+        @classmethod
+        def parser_prop(cls, buf, length):
+            size = 4
+            (controller_id,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return controller_id, size
+
+        @classmethod
+        def serialize_prop(cls, controller_id):
+            data = bytearray()
+            msg_pack_into("!HHH2x", data, 0,
+                          nicira_ext.NXAC2PT_CONTROLLER_ID,
+                          8,
+                          controller_id)
+            return data
+
+    @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_REASON)
+    class NXActionController2PropReason(NXActionController2Prop):
+        # reason
+        _fmt_str = "!B3x"
+        _arg_name = "reason"
+
+        @classmethod
+        def parser_prop(cls, buf, length):
+            size = 4
+            (reason,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return reason, size
+
+        @classmethod
+        def serialize_prop(cls, reason):
+            data = bytearray()
+            msg_pack_into("!HHB3x", data, 0,
+                          nicira_ext.NXAC2PT_REASON,
+                          5,
+                          reason)
+            return data
+
+    @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_USERDATA)
+    class NXActionController2PropUserData(NXActionController2Prop):
+        # userdata
+        _fmt_str = "!B"
+        _arg_name = "userdata"
+
+        @classmethod
+        def parser_prop(cls, buf, length):
+            userdata = []
+            offset = 0
+
+            while offset < length:
+                u = struct.unpack_from(cls._fmt_str, buf, offset)
+                userdata.append(u[0])
+                offset += 1
+
+            user_size = utils.round_up(length, 4)
+
+            if user_size > 4 and (user_size % 8) == 0:
+                size = utils.round_up(length, 4) + 4
+            else:
+                size = utils.round_up(length, 4)
+
+            return userdata, size
+
+        @classmethod
+        def serialize_prop(cls, userdata):
+            data = bytearray()
+            user_buf = bytearray()
+            user_offset = 0
+            for user in userdata:
+                msg_pack_into('!B', user_buf, user_offset,
+                              user)
+                user_offset += 1
+
+            msg_pack_into("!HH", data, 0,
+                          nicira_ext.NXAC2PT_USERDATA,
+                          4 + user_offset)
+            data += user_buf
+
+            if user_offset > 4:
+                user_len = utils.round_up(user_offset, 4)
+                brank_size = 0
+                if (user_len % 8) == 0:
+                    brank_size = 4
+                msg_pack_into("!%dx" % (user_len - user_offset + brank_size),
+                              data, 4 + user_offset)
+            else:
+                user_len = utils.round_up(user_offset, 4)
+
+                msg_pack_into("!%dx" % (user_len - user_offset),
+                              data, 4 + user_offset)
+            return data
+
+    @NXActionController2Prop.register_type(nicira_ext.NXAC2PT_PAUSE)
+    class NXActionController2PropPause(NXActionController2Prop):
+        _arg_name = "pause"
+
+        @classmethod
+        def parser_prop(cls, buf, length):
+            pause = True
+            size = 4
+            return pause, size
+
+        @classmethod
+        def serialize_prop(cls, pause):
+            data = bytearray()
+            msg_pack_into("!HH4x", data, 0,
+                          nicira_ext.NXAC2PT_PAUSE,
+                          4)
+            return data
+
+    class NXActionDecTtlCntIds(NXAction):
+        r"""
+        Decrement TTL action
+
+        This action decrements TTL of IPv4 packet or
+        hop limits of IPv6 packet.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          dec_ttl(id1[,id2]...)
+        ..
+
+        +-------------------------------------------+
+        | **dec_ttl(**\ *id1*\[,\ *id2*\]...\ **)** |
+        +-------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        cnt_ids          Controller ids
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionDecTtlCntIds(cnt_ids=[1,2,3])]
+
+        .. NOTE::
+            If you want to set the following ovs-ofctl command.
+            Please use ``OFPActionDecNwTtl``.
+
+        +-------------+
+        | **dec_ttl** |
+        +-------------+
+        """
+        _subtype = nicira_ext.NXAST_DEC_TTL_CNT_IDS
+
+        # controllers
+        _fmt_str = '!H4x'
+        _fmt_len = 6
+
+        def __init__(self,
+                     cnt_ids,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionDecTtlCntIds, self).__init__()
+
+            self.cnt_ids = cnt_ids
+
+        @classmethod
+        def parser(cls, buf):
+            (controllers,) = struct.unpack_from(
+                cls._fmt_str, buf)
+
+            offset = cls._fmt_len
+            cnt_ids = []
+
+            for i in range(0, controllers):
+                id_ = struct.unpack_from('!H', buf, offset)
+                cnt_ids.append(id_[0])
+                offset += 2
+
+            return cls(cnt_ids)
+
+        def serialize_body(self):
+            assert isinstance(self.cnt_ids, (tuple, list))
+            for i in self.cnt_ids:
+                assert isinstance(i, six.integer_types)
+
+            controllers = len(self.cnt_ids)
+
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          controllers)
+            offset = self._fmt_len
+
+            for id_ in self.cnt_ids:
+                msg_pack_into('!H', data, offset, id_)
+                offset += 2
+
+            id_len = (utils.round_up(controllers, 4) -
+                      controllers)
+
+            if id_len != 0:
+                msg_pack_into('%dx' % id_len * 2, data, offset)
+
+            return data
+
+    # Use in only OpenFlow1.0
+    class NXActionMplsBase(NXAction):
+        # ethertype
+        _fmt_str = '!H4x'
+
+        def __init__(self,
+                     ethertype,
+                     type_=None, len_=None, vendor=None, subtype=None):
+            super(NXActionMplsBase, self).__init__()
+            self.ethertype = ethertype
+
+        @classmethod
+        def parser(cls, buf):
+            (ethertype,) = struct.unpack_from(
+                cls._fmt_str, buf)
+            return cls(ethertype)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.ethertype)
+            return data
+
+    # For OpenFlow1.0 only
+    class NXActionPushMpls(NXActionMplsBase):
+        r"""
+        Push MPLS action
+
+        This action pushes a new MPLS header to the packet.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          push_mpls:ethertype
+        ..
+
+        +-------------------------------+
+        | **push_mpls**\:\ *ethertype*  |
+        +-------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        ethertype        Ether type(The value must be either 0x8847 or 0x8848)
+        ================ ======================================================
+
+        .. NOTE::
+            This actions is supported by
+            ``OFPActionPushMpls``
+            in OpenFlow1.2 or later.
+
+        Example::
+
+            match = parser.OFPMatch(dl_type=0x0800)
+            actions += [parser.NXActionPushMpls(ethertype=0x8847)]
+        """
+        _subtype = nicira_ext.NXAST_PUSH_MPLS
+
+    # For OpenFlow1.0 only
+    class NXActionPopMpls(NXActionMplsBase):
+        r"""
+        Pop MPLS action
+
+        This action pops the MPLS header from the packet.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          pop_mpls:ethertype
+        ..
+
+        +------------------------------+
+        | **pop_mpls**\:\ *ethertype*  |
+        +------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        ethertype        Ether type
+        ================ ======================================================
+
+        .. NOTE::
+            This actions is supported by
+            ``OFPActionPopMpls``
+            in OpenFlow1.2 or later.
+
+        Example::
+
+            match = parser.OFPMatch(dl_type=0x8847)
+            actions += [parser.NXActionPushMpls(ethertype=0x0800)]
+        """
+        _subtype = nicira_ext.NXAST_POP_MPLS
+
+    # For OpenFlow1.0 only
+    class NXActionSetMplsTtl(NXAction):
+        r"""
+        Set MPLS TTL action
+
+        This action sets the MPLS TTL.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          set_mpls_ttl:ttl
+        ..
+
+        +---------------------------+
+        | **set_mpls_ttl**\:\ *ttl* |
+        +---------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        ttl              MPLS TTL
+        ================ ======================================================
+
+        .. NOTE::
+            This actions is supported by
+            ``OFPActionSetMplsTtl``
+            in OpenFlow1.2 or later.
+
+        Example::
+
+            actions += [parser.NXActionSetMplsTil(ttl=128)]
+        """
+        _subtype = nicira_ext.NXAST_SET_MPLS_TTL
+
+        # ethertype
+        _fmt_str = '!B5x'
+
+        def __init__(self,
+                     ttl,
+                     type_=None, len_=None, vendor=None, subtype=None):
+            super(NXActionSetMplsTtl, self).__init__()
+            self.ttl = ttl
+
+        @classmethod
+        def parser(cls, buf):
+            (ttl,) = struct.unpack_from(
+                cls._fmt_str, buf)
+            return cls(ttl)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.ttl)
+            return data
+
+    # For OpenFlow1.0 only
+    class NXActionDecMplsTtl(NXAction):
+        """
+        Decrement MPLS TTL action
+
+        This action decrements the MPLS TTL.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          dec_mpls_ttl
+        ..
+
+        +------------------+
+        | **dec_mpls_ttl** |
+        +------------------+
+
+        .. NOTE::
+            This actions is supported by
+            ``OFPActionDecMplsTtl``
+            in OpenFlow1.2 or later.
+
+        Example::
+
+            actions += [parser.NXActionDecMplsTil()]
+        """
+        _subtype = nicira_ext.NXAST_DEC_MPLS_TTL
+
+        # ethertype
+        _fmt_str = '!6x'
+
+        def __init__(self,
+                     type_=None, len_=None, vendor=None, subtype=None):
+            super(NXActionDecMplsTtl, self).__init__()
+
+        @classmethod
+        def parser(cls, buf):
+            return cls()
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0)
+            return data
+
+    # For OpenFlow1.0 only
+    class NXActionSetMplsLabel(NXAction):
+        r"""
+        Set MPLS Lavel action
+
+        This action sets the MPLS Label.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          set_mpls_label:label
+        ..
+
+        +-------------------------------+
+        | **set_mpls_label**\:\ *label* |
+        +-------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        label            MPLS Label
+        ================ ======================================================
+
+        .. NOTE::
+            This actions is supported by
+            ``OFPActionSetField(mpls_label=label)``
+            in OpenFlow1.2 or later.
+
+        Example::
+
+            actions += [parser.NXActionSetMplsLabel(label=0x10)]
+        """
+        _subtype = nicira_ext.NXAST_SET_MPLS_LABEL
+
+        # ethertype
+        _fmt_str = '!2xI'
+
+        def __init__(self,
+                     label,
+                     type_=None, len_=None, vendor=None, subtype=None):
+            super(NXActionSetMplsLabel, self).__init__()
+            self.label = label
+
+        @classmethod
+        def parser(cls, buf):
+            (label,) = struct.unpack_from(
+                cls._fmt_str, buf)
+            return cls(label)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.label)
+            return data
+
+    # For OpenFlow1.0 only
+    class NXActionSetMplsTc(NXAction):
+        r"""
+        Set MPLS Tc action
+
+        This action sets the MPLS Tc.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          set_mpls_tc:tc
+        ..
+
+        +-------------------------+
+        | **set_mpls_tc**\:\ *tc* |
+        +-------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        tc               MPLS Tc
+        ================ ======================================================
+
+        .. NOTE::
+            This actions is supported by
+            ``OFPActionSetField(mpls_label=tc)``
+            in OpenFlow1.2 or later.
+
+        Example::
+
+            actions += [parser.NXActionSetMplsLabel(tc=0x10)]
+        """
+        _subtype = nicira_ext.NXAST_SET_MPLS_TC
+
+        # ethertype
+        _fmt_str = '!B5x'
+
+        def __init__(self,
+                     tc,
+                     type_=None, len_=None, vendor=None, subtype=None):
+            super(NXActionSetMplsTc, self).__init__()
+            self.tc = tc
+
+        @classmethod
+        def parser(cls, buf):
+            (tc,) = struct.unpack_from(
+                cls._fmt_str, buf)
+            return cls(tc)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.tc)
+            return data
+
+    class NXActionStackBase(NXAction):
+        # start, field, end
+        _fmt_str = '!H4sH'
+        _TYPE = {
+            'ascii': [
+                'field',
+            ]
+        }
+
+        def __init__(self,
+                     field,
+                     start,
+                     end,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionStackBase, self).__init__()
+            self.field = field
+            self.start = start
+            self.end = end
+
+        @classmethod
+        def parser(cls, buf):
+            (start, oxm_data, end) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
+            field = ofp.oxm_to_user_header(n)
+            return cls(field, start, end)
+
+        def serialize_body(self):
+            data = bytearray()
+            oxm_data = bytearray()
+            oxm = ofp.oxm_from_user_header(self.field)
+            ofp.oxm_serialize_header(oxm, oxm_data, 0)
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.start,
+                          six.binary_type(oxm_data),
+                          self.end)
+            offset = len(data)
+            msg_pack_into("!%dx" % (12 - offset), data, offset)
+            return data
+
+    class NXActionStackPush(NXActionStackBase):
+        r"""
+        Push field action
+
+        This action pushes field to top of the stack.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          pop:dst[start...end]
+        ..
+
+        +----------------------------------------------------+
+        | **pop**\:\ *dst*\ **[**\ *start*\...\ *end*\ **]** |
+        +----------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        field            OXM/NXM header for source field
+        start            Start bit for source field
+        end              End bit for source field
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionStackPush(field="reg2",
+                                                 start=0,
+                                                 end=5)]
+        """
+        _subtype = nicira_ext.NXAST_STACK_PUSH
+
+    class NXActionStackPop(NXActionStackBase):
+        r"""
+        Pop field action
+
+        This action pops field from top of the stack.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          pop:src[start...end]
+        ..
+
+        +----------------------------------------------------+
+        | **pop**\:\ *src*\ **[**\ *start*\...\ *end*\ **]** |
+        +----------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        field            OXM/NXM header for destination field
+        start            Start bit for destination field
+        end              End bit for destination field
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionStackPop(field="reg2",
+                                                start=0,
+                                                end=5)]
+        """
+        _subtype = nicira_ext.NXAST_STACK_POP
+
+    class NXActionSample(NXAction):
+        r"""
+        Sample packets action
+
+        This action samples packets and sends one sample for
+        every sampled packet.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          sample(argument[,argument]...)
+        ..
+
+        +----------------------------------------------------+
+        | **sample(**\ *argument*\[,\ *argument*\]...\ **)** |
+        +----------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        probability      The number of sampled packets
+        collector_set_id The unsigned 32-bit integer identifier of
+                         the set of sample collectors to send sampled packets
+                         to
+        obs_domain_id    The Unsigned 32-bit integer Observation Domain ID
+        obs_point_id     The unsigned 32-bit integer Observation Point ID
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionSample(probability=3,
+                                              collector_set_id=1,
+                                              obs_domain_id=2,
+                                              obs_point_id=3,)]
+        """
+        _subtype = nicira_ext.NXAST_SAMPLE
+
+        # probability, collector_set_id, obs_domain_id, obs_point_id
+        _fmt_str = '!HIII'
+
+        def __init__(self,
+                     probability,
+                     collector_set_id=0,
+                     obs_domain_id=0,
+                     obs_point_id=0,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionSample, self).__init__()
+            self.probability = probability
+            self.collector_set_id = collector_set_id
+            self.obs_domain_id = obs_domain_id
+            self.obs_point_id = obs_point_id
+
+        @classmethod
+        def parser(cls, buf):
+            (probability,
+             collector_set_id,
+             obs_domain_id,
+             obs_point_id) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return cls(probability,
+                       collector_set_id,
+                       obs_domain_id,
+                       obs_point_id)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.probability,
+                          self.collector_set_id,
+                          self.obs_domain_id,
+                          self.obs_point_id)
+            return data
+
+    class NXActionSample2(NXAction):
+        r"""
+        Sample packets action
+
+        This action samples packets and sends one sample for
+        every sampled packet.
+        'sampling_port' can be equal to ingress port or one of egress ports.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          sample(argument[,argument]...)
+        ..
+
+        +----------------------------------------------------+
+        | **sample(**\ *argument*\[,\ *argument*\]...\ **)** |
+        +----------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        probability      The number of sampled packets
+        collector_set_id The unsigned 32-bit integer identifier of
+                         the set of sample collectors to send sampled packets to
+        obs_domain_id    The Unsigned 32-bit integer Observation Domain ID
+        obs_point_id     The unsigned 32-bit integer Observation Point ID
+        sampling_port    Sampling port number
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionSample2(probability=3,
+                                               collector_set_id=1,
+                                               obs_domain_id=2,
+                                               obs_point_id=3,
+                                               sampling_port=8080)]
+        """
+        _subtype = nicira_ext.NXAST_SAMPLE2
+
+        # probability, collector_set_id, obs_domain_id,
+        # obs_point_id, sampling_port
+        _fmt_str = '!HIIIH6x'
+
+        def __init__(self,
+                     probability,
+                     collector_set_id=0,
+                     obs_domain_id=0,
+                     obs_point_id=0,
+                     sampling_port=0,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionSample2, self).__init__()
+            self.probability = probability
+            self.collector_set_id = collector_set_id
+            self.obs_domain_id = obs_domain_id
+            self.obs_point_id = obs_point_id
+            self.sampling_port = sampling_port
+
+        @classmethod
+        def parser(cls, buf):
+            (probability,
+             collector_set_id,
+             obs_domain_id,
+             obs_point_id,
+             sampling_port) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return cls(probability,
+                       collector_set_id,
+                       obs_domain_id,
+                       obs_point_id,
+                       sampling_port)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.probability,
+                          self.collector_set_id,
+                          self.obs_domain_id,
+                          self.obs_point_id,
+                          self.sampling_port)
+            return data
+
+    class NXActionFinTimeout(NXAction):
+        r"""
+        Change TCP timeout action
+
+        This action changes the idle timeout or hard timeout or
+        both, of this OpenFlow rule when the rule matches a TCP
+        packet with the FIN or RST flag.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          fin_timeout(argument[,argument]...)
+        ..
+
+        +---------------------------------------------------------+
+        | **fin_timeout(**\ *argument*\[,\ *argument*\]...\ **)** |
+        +---------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        fin_idle_timeout Causes the flow to expire after the given number
+                         of seconds of inactivity
+        fin_idle_timeout Causes the flow to expire after the given number
+                         of second, regardless of activity
+        ================ ======================================================
+
+        Example::
+
+            match = parser.OFPMatch(ip_proto=6, eth_type=0x0800)
+            actions += [parser.NXActionFinTimeout(fin_idle_timeout=30,
+                                                  fin_hard_timeout=60)]
+        """
+        _subtype = nicira_ext.NXAST_FIN_TIMEOUT
+
+        # fin_idle_timeout, fin_hard_timeout
+        _fmt_str = '!HH2x'
+
+        def __init__(self,
+                     fin_idle_timeout,
+                     fin_hard_timeout,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionFinTimeout, self).__init__()
+            self.fin_idle_timeout = fin_idle_timeout
+            self.fin_hard_timeout = fin_hard_timeout
+
+        @classmethod
+        def parser(cls, buf):
+            (fin_idle_timeout,
+             fin_hard_timeout) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return cls(fin_idle_timeout,
+                       fin_hard_timeout)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.fin_idle_timeout,
+                          self.fin_hard_timeout)
+            return data
+
+    class NXActionConjunction(NXAction):
+        r"""
+        Conjunctive matches action
+
+        This action ties groups of individual OpenFlow flows into
+        higher-level conjunctive flows.
+        Please refer to the ovs-ofctl command manual for details.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          conjunction(id,k/n)
+        ..
+
+        +--------------------------------------------------+
+        | **conjunction(**\ *id*\,\ *k*\ **/**\ *n*\ **)** |
+        +--------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        clause           Number assigned to the flow's dimension
+        n_clauses        Specify the conjunctive flow's match condition
+        id\_             Conjunction ID
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionConjunction(clause=1,
+                                                   n_clauses=2,
+                                                   id_=10)]
+        """
+        _subtype = nicira_ext.NXAST_CONJUNCTION
+
+        # clause, n_clauses, id
+        _fmt_str = '!BBI'
+
+        def __init__(self,
+                     clause,
+                     n_clauses,
+                     id_,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionConjunction, self).__init__()
+            self.clause = clause
+            self.n_clauses = n_clauses
+            self.id = id_
+
+        @classmethod
+        def parser(cls, buf):
+            (clause,
+             n_clauses,
+             id_,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return cls(clause, n_clauses, id_)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.clause,
+                          self.n_clauses,
+                          self.id)
+            return data
+
+    class NXActionMultipath(NXAction):
+        r"""
+        Select multipath link action
+
+        This action selects multipath link based on the specified parameters.
+        Please refer to the ovs-ofctl command manual for details.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          multipath(fields, basis, algorithm, n_links, arg, dst[start..end])
+        ..
+
+        +-------------------------------------------------------------+
+        | **multipath(**\ *fields*\, \ *basis*\, \ *algorithm*\,      |
+        | *n_links*\, \ *arg*\, \ *dst*\[\ *start*\..\ *end*\]\ **)** |
+        +-------------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        fields           One of NX_HASH_FIELDS_*
+        basis            Universal hash parameter
+        algorithm        One of NX_MP_ALG_*.
+        max_link         Number of output links
+        arg              Algorithm-specific argument
+        ofs_nbits        Start and End for the OXM/NXM field.
+                         Setting method refer to the ``nicira_ext.ofs_nbits``
+        dst              OXM/NXM header for source field
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionMultipath(
+                            fields=nicira_ext.NX_HASH_FIELDS_SYMMETRIC_L4,
+                            basis=1024,
+                            algorithm=nicira_ext.NX_MP_ALG_HRW,
+                            max_link=5,
+                            arg=0,
+                            ofs_nbits=nicira_ext.ofs_nbits(4, 31),
+                            dst="reg2")]
+        """
+        _subtype = nicira_ext.NXAST_MULTIPATH
+
+        # fields, basis, algorithm, max_link,
+        # arg, ofs_nbits, dst
+        _fmt_str = '!HH2xHHI2xH4s'
+        _TYPE = {
+            'ascii': [
+                'dst',
+            ]
+        }
+
+        def __init__(self,
+                     fields,
+                     basis,
+                     algorithm,
+                     max_link,
+                     arg,
+                     ofs_nbits,
+                     dst,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionMultipath, self).__init__()
+            self.fields = fields
+            self.basis = basis
+            self.algorithm = algorithm
+            self.max_link = max_link
+            self.arg = arg
+            self.ofs_nbits = ofs_nbits
+            self.dst = dst
+
+        @classmethod
+        def parser(cls, buf):
+            (fields,
+             basis,
+             algorithm,
+             max_link,
+             arg,
+             ofs_nbits,
+             oxm_data) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
+            dst = ofp.oxm_to_user_header(n)
+            return cls(fields,
+                       basis,
+                       algorithm,
+                       max_link,
+                       arg,
+                       ofs_nbits,
+                       dst)
+
+        def serialize_body(self):
+            data = bytearray()
+            dst = bytearray()
+            oxm = ofp.oxm_from_user_header(self.dst)
+            ofp.oxm_serialize_header(oxm, dst, 0),
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.fields,
+                          self.basis,
+                          self.algorithm,
+                          self.max_link,
+                          self.arg,
+                          self.ofs_nbits,
+                          six.binary_type(dst))
+
+            return data
+
+    class _NXActionBundleBase(NXAction):
+        # algorithm, fields, basis, slave_type, n_slaves
+        # ofs_nbits
+        _fmt_str = '!HHHIHH'
+
+        def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
+                     ofs_nbits, dst, slaves):
+            super(_NXActionBundleBase, self).__init__()
+            self.len = utils.round_up(
+                nicira_ext.NX_ACTION_BUNDLE_0_SIZE + len(slaves) * 2, 8)
+
+            self.algorithm = algorithm
+            self.fields = fields
+            self.basis = basis
+            self.slave_type = slave_type
+            self.n_slaves = n_slaves
+            self.ofs_nbits = ofs_nbits
+            self.dst = dst
+
+            assert isinstance(slaves, (list, tuple))
+            for s in slaves:
+                assert isinstance(s, six.integer_types)
+
+            self.slaves = slaves
+
+        @classmethod
+        def parser(cls, buf):
+            # Add dst ('I') to _fmt_str
+            (algorithm, fields, basis,
+             slave_type, n_slaves, ofs_nbits, dst) = struct.unpack_from(
+                cls._fmt_str + 'I', buf, 0)
+
+            offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
+                      nicira_ext.NX_ACTION_HEADER_0_SIZE - 8)
+
+            if dst != 0:
+                (n, len_) = ofp.oxm_parse_header(buf, offset)
+                dst = ofp.oxm_to_user_header(n)
+
+            slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
+                            nicira_ext.NX_ACTION_HEADER_0_SIZE)
+
+            slaves = []
+            for i in range(0, n_slaves):
+                s = struct.unpack_from('!H', buf, slave_offset)
+                slaves.append(s[0])
+                slave_offset += 2
+
+            return cls(algorithm, fields, basis, slave_type,
+                       n_slaves, ofs_nbits, dst, slaves)
+
+        def serialize_body(self):
+            data = bytearray()
+            slave_offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
+                            nicira_ext.NX_ACTION_HEADER_0_SIZE)
+            self.n_slaves = len(self.slaves)
+            for s in self.slaves:
+                msg_pack_into('!H', data, slave_offset, s)
+                slave_offset += 2
+            pad_len = (utils.round_up(self.n_slaves, 4) -
+                       self.n_slaves)
+
+            if pad_len != 0:
+                msg_pack_into('%dx' % pad_len * 2, data, slave_offset)
+
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.algorithm, self.fields, self.basis,
+                          self.slave_type, self.n_slaves,
+                          self.ofs_nbits)
+            offset = (nicira_ext.NX_ACTION_BUNDLE_0_SIZE -
+                      nicira_ext.NX_ACTION_HEADER_0_SIZE - 8)
+
+            if self.dst == 0:
+                msg_pack_into('I', data, offset, self.dst)
+            else:
+                oxm_data = ofp.oxm_from_user_header(self.dst)
+                ofp.oxm_serialize_header(oxm_data, data, offset)
+            return data
+
+    class NXActionBundle(_NXActionBundleBase):
+        r"""
+        Select bundle link action
+
+        This action selects bundle link based on the specified parameters.
+        Please refer to the ovs-ofctl command manual for details.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          bundle(fields, basis, algorithm, slave_type, slaves:[ s1, s2,...])
+        ..
+
+        +-----------------------------------------------------------+
+        | **bundle(**\ *fields*\, \ *basis*\, \ *algorithm*\,       |
+        | *slave_type*\, \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** |
+        +-----------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        algorithm        One of NX_MP_ALG_*.
+        fields           One of NX_HASH_FIELDS_*
+        basis            Universal hash parameter
+        slave_type       Type of slaves(must be NXM_OF_IN_PORT)
+        n_slaves         Number of slaves
+        ofs_nbits        Start and End for the OXM/NXM field. (must be zero)
+        dst              OXM/NXM header for source field(must be zero)
+        slaves           List of slaves
+        ================ ======================================================
+
+
+        Example::
+
+            actions += [parser.NXActionBundle(
+                            algorithm=nicira_ext.NX_MP_ALG_HRW,
+                            fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC,
+                            basis=0,
+                            slave_type=nicira_ext.NXM_OF_IN_PORT,
+                            n_slaves=2,
+                            ofs_nbits=0,
+                            dst=0,
+                            slaves=[2, 3])]
+        """
+        _subtype = nicira_ext.NXAST_BUNDLE
+
+        def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
+                     ofs_nbits, dst, slaves):
+            # NXAST_BUNDLE actions should have 'sofs_nbits' and 'dst' zeroed.
+            super(NXActionBundle, self).__init__(
+                algorithm, fields, basis, slave_type, n_slaves,
+                ofs_nbits=0, dst=0, slaves=slaves)
+
+    class NXActionBundleLoad(_NXActionBundleBase):
+        r"""
+        Select bundle link action
+
+        This action has the same behavior as the bundle action,
+        with one exception.
+        Please refer to the ovs-ofctl command manual for details.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          bundle_load(fields, basis, algorithm, slave_type,
+                      dst[start..end], slaves:[ s1, s2,...])
+        ..
+
+        +-----------------------------------------------------------+
+        | **bundle_load(**\ *fields*\, \ *basis*\, \ *algorithm*\,  |
+        | *slave_type*\, \ *dst*\[\ *start*\... \*emd*\],           |
+        | \ *slaves*\:[ \ *s1*\, \ *s2*\,...]\ **)** |              |
+        +-----------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        algorithm        One of NX_MP_ALG_*.
+        fields           One of NX_HASH_FIELDS_*
+        basis            Universal hash parameter
+        slave_type       Type of slaves(must be NXM_OF_IN_PORT)
+        n_slaves         Number of slaves
+        ofs_nbits        Start and End for the OXM/NXM field.
+                         Setting method refer to the ``nicira_ext.ofs_nbits``
+        dst              OXM/NXM header for source field
+        slaves           List of slaves
+        ================ ======================================================
+
+
+        Example::
+
+            actions += [parser.NXActionBundleLoad(
+                            algorithm=nicira_ext.NX_MP_ALG_HRW,
+                            fields=nicira_ext.NX_HASH_FIELDS_ETH_SRC,
+                            basis=0,
+                            slave_type=nicira_ext.NXM_OF_IN_PORT,
+                            n_slaves=2,
+                            ofs_nbits=nicira_ext.ofs_nbits(4, 31),
+                            dst="reg0",
+                            slaves=[2, 3])]
+        """
+        _subtype = nicira_ext.NXAST_BUNDLE_LOAD
+        _TYPE = {
+            'ascii': [
+                'dst',
+            ]
+        }
+
+        def __init__(self, algorithm, fields, basis, slave_type, n_slaves,
+                     ofs_nbits, dst, slaves):
+            super(NXActionBundleLoad, self).__init__(
+                algorithm, fields, basis, slave_type, n_slaves,
+                ofs_nbits, dst, slaves)
+
+    class NXActionCT(NXAction):
+        r"""
+        Pass traffic to the connection tracker action
+
+        This action sends the packet through the connection tracker.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          ct(argument[,argument]...)
+        ..
+
+        +------------------------------------------------+
+        | **ct(**\ *argument*\[,\ *argument*\]...\ **)** |
+        +------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        flags            Zero or more(Unspecified flag bits must be zero.)
+        zone_src         OXM/NXM header for source field
+        zone_ofs_nbits   Start and End for the OXM/NXM field.
+                         Setting method refer to the ``nicira_ext.ofs_nbits``.
+                         If you need set the Immediate value for zone,
+                         zone_src must be set to None or empty character string.
+        recirc_table     Recirculate to a specific table
+        alg              Well-known port number for the protocol
+        actions          Zero or more actions may immediately follow this
+                         action
+        ================ ======================================================
+
+        .. NOTE::
+
+            If you set number to zone_src,
+            Traceback occurs when you run the to_jsondict.
+
+        Example::
+
+            match = parser.OFPMatch(eth_type=0x0800, ct_state=(0,32))
+            actions += [parser.NXActionCT(
+                            flags = 1,
+                            zone_src = "reg0",
+                            zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31),
+                            recirc_table = 4,
+                            alg = 0,
+                            actions = [])]
+        """
+        _subtype = nicira_ext.NXAST_CT
+
+        # flags, zone_src, zone_ofs_nbits, recirc_table,
+        # pad, alg
+        _fmt_str = '!H4sHB3xH'
+        _TYPE = {
+            'ascii': [
+                'zone_src',
+            ]
+        }
+
+        # Followed by actions
+
+        def __init__(self,
+                     flags,
+                     zone_src,
+                     zone_ofs_nbits,
+                     recirc_table,
+                     alg,
+                     actions,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionCT, self).__init__()
+            self.flags = flags
+            self.zone_src = zone_src
+            self.zone_ofs_nbits = zone_ofs_nbits
+            self.recirc_table = recirc_table
+            self.alg = alg
+            self.actions = actions
+
+        @classmethod
+        def parser(cls, buf):
+            (flags,
+             oxm_data,
+             zone_ofs_nbits,
+             recirc_table,
+             alg,) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            rest = buf[struct.calcsize(cls._fmt_str):]
+
+            # OXM/NXM field
+            if oxm_data == b'\x00' * 4:
+                zone_src = ""
+            else:
+                (n, len_) = ofp.oxm_parse_header(oxm_data, 0)
+                zone_src = ofp.oxm_to_user_header(n)
+
+            # actions
+            actions = []
+            while len(rest) > 0:
+                action = ofpp.OFPAction.parser(rest, 0)
+                actions.append(action)
+                rest = rest[action.len:]
+
+            return cls(flags, zone_src, zone_ofs_nbits, recirc_table,
+                       alg, actions)
+
+        def serialize_body(self):
+            data = bytearray()
+            # If zone_src is zero, zone_ofs_nbits is zone_imm
+            if not self.zone_src:
+                zone_src = b'\x00' * 4
+            elif isinstance(self.zone_src, six.integer_types):
+                zone_src = struct.pack("!I", self.zone_src)
+            else:
+                zone_src = bytearray()
+                oxm = ofp.oxm_from_user_header(self.zone_src)
+                ofp.oxm_serialize_header(oxm, zone_src, 0)
+
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.flags,
+                          six.binary_type(zone_src),
+                          self.zone_ofs_nbits,
+                          self.recirc_table,
+                          self.alg)
+            for a in self.actions:
+                a.serialize(data, len(data))
+            return data
+
+    class NXActionCTClear(NXAction):
+        """
+        Clear connection tracking state action
+
+        This action clears connection tracking state from packets.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          ct_clear
+        ..
+
+        +--------------+
+        | **ct_clear** |
+        +--------------+
+
+        Example::
+
+            actions += [parser.NXActionCTClear()]
+        """
+        _subtype = nicira_ext.NXAST_CT_CLEAR
+
+        _fmt_str = '!6x'
+
+        def __init__(self,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionCTClear, self).__init__()
+
+        @classmethod
+        def parser(cls, buf):
+            return cls()
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0)
+            return data
+
+    class NXActionNAT(NXAction):
+        r"""
+        Network address translation action
+
+        This action sends the packet through the connection tracker.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        .. NOTE::
+            The following command image does not exist in ovs-ofctl command
+            manual and has been created from the command response.
+
+        ..
+          nat(src=ip_min-ip_max : proto_min-proto-max)
+        ..
+
+        +--------------------------------------------------+
+        | **nat(src**\=\ *ip_min*\ **-**\ *ip_max*\  **:** |
+        | *proto_min*\ **-**\ *proto-max*\ **)**           |
+        +--------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        flags            Zero or more(Unspecified flag bits must be zero.)
+        range_ipv4_min   Range ipv4 address minimun
+        range_ipv4_max   Range ipv4 address maximun
+        range_ipv6_min   Range ipv6 address minimun
+        range_ipv6_max   Range ipv6 address maximun
+        range_proto_min  Range protocol minimum
+        range_proto_max  Range protocol maximun
+        ================ ======================================================
+
+        .. CAUTION::
+            ``NXActionNAT`` must be defined in the actions in the
+            ``NXActionCT``.
+
+        Example::
+
+            match = parser.OFPMatch(eth_type=0x0800)
+            actions += [
+                parser.NXActionCT(
+                    flags = 1,
+                    zone_src = "reg0",
+                    zone_ofs_nbits = nicira_ext.ofs_nbits(4, 31),
+                    recirc_table = 255,
+                    alg = 0,
+                    actions = [
+                        parser.NXActionNAT(
+                            flags = 1,
+                            range_ipv4_min = "10.1.12.0",
+                            range_ipv4_max = "10.1.13.255",
+                            range_ipv6_min = "",
+                            range_ipv6_max = "",
+                            range_proto_min = 1,
+                            range_proto_max = 1023
+                        )
+                    ]
+                )
+            ]
+        """
+        _subtype = nicira_ext.NXAST_NAT
+
+        # pad, flags, range_present
+        _fmt_str = '!2xHH'
+        # Followed by optional parameters
+
+        _TYPE = {
+            'ascii': [
+                'range_ipv4_max',
+                'range_ipv4_min',
+                'range_ipv6_max',
+                'range_ipv6_min',
+            ]
+        }
+
+        def __init__(self,
+                     flags,
+                     range_ipv4_min='',
+                     range_ipv4_max='',
+                     range_ipv6_min='',
+                     range_ipv6_max='',
+                     range_proto_min=None,
+                     range_proto_max=None,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionNAT, self).__init__()
+            self.flags = flags
+            self.range_ipv4_min = range_ipv4_min
+            self.range_ipv4_max = range_ipv4_max
+            self.range_ipv6_min = range_ipv6_min
+            self.range_ipv6_max = range_ipv6_max
+            self.range_proto_min = range_proto_min
+            self.range_proto_max = range_proto_max
+
+        @classmethod
+        def parser(cls, buf):
+            (flags,
+             range_present) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            rest = buf[struct.calcsize(cls._fmt_str):]
+            # optional parameters
+            kwargs = dict()
+            if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MIN:
+                kwargs['range_ipv4_min'] = type_desc.IPv4Addr.to_user(rest[:4])
+                rest = rest[4:]
+            if range_present & nicira_ext.NX_NAT_RANGE_IPV4_MAX:
+                kwargs['range_ipv4_max'] = type_desc.IPv4Addr.to_user(rest[:4])
+                rest = rest[4:]
+            if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MIN:
+                kwargs['range_ipv6_min'] = (
+                    type_desc.IPv6Addr.to_user(rest[:16]))
+                rest = rest[16:]
+            if range_present & nicira_ext.NX_NAT_RANGE_IPV6_MAX:
+                kwargs['range_ipv6_max'] = (
+                    type_desc.IPv6Addr.to_user(rest[:16]))
+                rest = rest[16:]
+            if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MIN:
+                kwargs['range_proto_min'] = type_desc.Int2.to_user(rest[:2])
+                rest = rest[2:]
+            if range_present & nicira_ext.NX_NAT_RANGE_PROTO_MAX:
+                kwargs['range_proto_max'] = type_desc.Int2.to_user(rest[:2])
+
+            return cls(flags, **kwargs)
+
+        def serialize_body(self):
+            # Pack optional parameters first, as range_present needs
+            # to be calculated.
+            optional_data = b''
+            range_present = 0
+            if self.range_ipv4_min != '':
+                range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MIN
+                optional_data += type_desc.IPv4Addr.from_user(
+                    self.range_ipv4_min)
+            if self.range_ipv4_max != '':
+                range_present |= nicira_ext.NX_NAT_RANGE_IPV4_MAX
+                optional_data += type_desc.IPv4Addr.from_user(
+                    self.range_ipv4_max)
+            if self.range_ipv6_min != '':
+                range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MIN
+                optional_data += type_desc.IPv6Addr.from_user(
+                    self.range_ipv6_min)
+            if self.range_ipv6_max != '':
+                range_present |= nicira_ext.NX_NAT_RANGE_IPV6_MAX
+                optional_data += type_desc.IPv6Addr.from_user(
+                    self.range_ipv6_max)
+            if self.range_proto_min is not None:
+                range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MIN
+                optional_data += type_desc.Int2.from_user(
+                    self.range_proto_min)
+            if self.range_proto_max is not None:
+                range_present |= nicira_ext.NX_NAT_RANGE_PROTO_MAX
+                optional_data += type_desc.Int2.from_user(
+                    self.range_proto_max)
+
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.flags,
+                          range_present)
+            msg_pack_into('!%ds' % len(optional_data), data, len(data),
+                          optional_data)
+
+            return data
+
+    class NXActionOutputTrunc(NXAction):
+        r"""
+        Truncate output action
+
+        This action truncate a packet into the specified size and outputs it.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ..
+          output(port=port,max_len=max_len)
+        ..
+
+        +--------------------------------------------------------------+
+        | **output(port**\=\ *port*\,\ **max_len**\=\ *max_len*\ **)** |
+        +--------------------------------------------------------------+
+
+        ================ ======================================================
+        Attribute        Description
+        ================ ======================================================
+        port             Output port
+        max_len          Max bytes to send
+        ================ ======================================================
+
+        Example::
+
+            actions += [parser.NXActionOutputTrunc(port=8080,
+                                                   max_len=1024)]
+        """
+        _subtype = nicira_ext.NXAST_OUTPUT_TRUNC
+
+        # port, max_len
+        _fmt_str = '!HI'
+
+        def __init__(self,
+                     port,
+                     max_len,
+                     type_=None, len_=None, experimenter=None, subtype=None):
+            super(NXActionOutputTrunc, self).__init__()
+            self.port = port
+            self.max_len = max_len
+
+        @classmethod
+        def parser(cls, buf):
+            (port,
+             max_len) = struct.unpack_from(
+                cls._fmt_str, buf, 0)
+            return cls(port, max_len)
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0,
+                          self.port,
+                          self.max_len)
+            return data
+
+    class NXActionDecNshTtl(NXAction):
+        """
+        Decrement NSH TTL action
+
+        This action decrements the TTL in the Network Service Header(NSH).
+
+        This action was added in OVS v2.9.
+
+        And equivalent to the followings action of ovs-ofctl command.
+
+        ::
+
+            dec_nsh_ttl
+
+        Example::
+
+            actions += [parser.NXActionDecNshTtl()]
+        """
+        _subtype = nicira_ext.NXAST_DEC_NSH_TTL
+
+        _fmt_str = '!6x'
+
+        def __init__(self,
+                     type_=None, len_=None, vendor=None, subtype=None):
+            super(NXActionDecNshTtl, self).__init__()
+
+        @classmethod
+        def parser(cls, buf):
+            return cls()
+
+        def serialize_body(self):
+            data = bytearray()
+            msg_pack_into(self._fmt_str, data, 0)
+            return data
+
+    def add_attr(k, v):
+        v.__module__ = ofpp.__name__  # Necessary for stringify stuff
+        setattr(ofpp, k, v)
+
+    add_attr('NXAction', NXAction)
+    add_attr('NXActionUnknown', NXActionUnknown)
+
+    classes = [
+        'NXActionSetQueue',
+        'NXActionPopQueue',
+        'NXActionRegLoad',
+        'NXActionRegLoad2',
+        'NXActionNote',
+        'NXActionSetTunnel',
+        'NXActionSetTunnel64',
+        'NXActionRegMove',
+        'NXActionResubmit',
+        'NXActionResubmitTable',
+        'NXActionOutputReg',
+        'NXActionOutputReg2',
+        'NXActionLearn',
+        'NXActionExit',
+        'NXActionDecTtl',
+        'NXActionController',
+        'NXActionController2',
+        'NXActionDecTtlCntIds',
+        'NXActionPushMpls',
+        'NXActionPopMpls',
+        'NXActionSetMplsTtl',
+        'NXActionDecMplsTtl',
+        'NXActionSetMplsLabel',
+        'NXActionSetMplsTc',
+        'NXActionStackPush',
+        'NXActionStackPop',
+        'NXActionSample',
+        'NXActionSample2',
+        'NXActionFinTimeout',
+        'NXActionConjunction',
+        'NXActionMultipath',
+        'NXActionBundle',
+        'NXActionBundleLoad',
+        'NXActionCT',
+        'NXActionCTClear',
+        'NXActionNAT',
+        'NXActionOutputTrunc',
+        '_NXFlowSpec',  # exported for testing
+        'NXFlowSpecMatch',
+        'NXFlowSpecLoad',
+        'NXFlowSpecOutput',
+        'NXActionDecNshTtl',
+    ]
+    vars = locals()
+    for name in classes:
+        cls = vars[name]
+        add_attr(name, cls)
+        if issubclass(cls, NXAction):
+            NXAction.register(cls)
+        if issubclass(cls, _NXFlowSpec):
+            _NXFlowSpec.register(cls)