[ovs-dev] [PATCH] ovs-actions: Convert man page from xml to rST.

Roi Dayan roid at nvidia.com
Mon Aug 9 07:07:39 UTC 2021



On 2021-08-07 2:54 AM, Ilya Maximets wrote:
> This way it's easier to show it on a website as it will be updated
> automatically along with the rest of the documentation.
> 
> Sphinx doesn't render everything perfectly, but it looks good enough
> in both man and html versions.  rST is a bit easier to read and it
> takes less space.
> 
> Conversion performed manually since I didn't found any good tool
> that can actually make the process any faster.
> 
> Along the way I replaced versions like x.y.90 with x.y+1, because
> it doesn't seem correct to me to refer non-released versions of OVS
> in the docs.  Fixed a couple of small mistakes like duplicated
> paragraph and reference to a different section by incorrect name.
> Also removed bits of xml->nroff conversion code that is not needed
> anymore.
> 
> Signed-off-by: Ilya Maximets <i.maximets at ovn.org>
> ---
> 
> Checkpatch emits a warning about new doc not being added to
> Documentation/automake.mk, but that's a false-positive.
> 
>   Documentation/automake.mk           |    1 +
>   Documentation/conf.py               |    4 +-
>   Documentation/ref/index.rst         |    5 +-
>   Documentation/ref/ovs-actions.7.rst | 2332 +++++++++++++++++++
>   build-aux/extract-ofp-actions       |  136 +-
>   lib/automake.mk                     |    9 -
>   lib/ovs-actions.xml                 | 3277 ---------------------------
>   7 files changed, 2338 insertions(+), 3426 deletions(-)
>   create mode 100644 Documentation/ref/ovs-actions.7.rst
>   delete mode 100644 lib/ovs-actions.xml
> 
> diff --git a/Documentation/automake.mk b/Documentation/automake.mk
> index 213d9c867..137cc57c5 100644
> --- a/Documentation/automake.mk
> +++ b/Documentation/automake.mk
> @@ -155,6 +155,7 @@ endif
>   
>   # rST formatted manpages under Documentation/ref.
>   RST_MANPAGES = \
> +	ovs-actions.7.rst \
>   	ovs-appctl.8.rst \
>   	ovs-ctl.8.rst \
>   	ovs-l3ping.8.rst \
> diff --git a/Documentation/conf.py b/Documentation/conf.py
> index 37d92c36f..085ca2cd6 100644
> --- a/Documentation/conf.py
> +++ b/Documentation/conf.py
> @@ -48,7 +48,7 @@ master_doc = 'contents'
>   
>   # General information about the project.
>   project = u'Open vSwitch'
> -copyright = u'2016, The Open vSwitch Development Community'
> +copyright = u'2016-2021, The Open vSwitch Development Community'
>   author = u'The Open vSwitch Development Community'
>   
>   # The version info for the project you're documenting, acts as replacement for
> @@ -114,6 +114,8 @@ html_static_path = ['_static']
>   # One entry per manual page. List of tuples
>   # (source start file, name, description, authors, manual section).
>   _man_pages = [
> +    ('ovs-actions.7',
> +     u'OpenFlow actions and instructions with Open vSwitch extensions'),
>       ('ovs-appctl.8',
>        u'utility for configuring running Open vSwitch daemons'),
>       ('ovs-ctl.8',
> diff --git a/Documentation/ref/index.rst b/Documentation/ref/index.rst
> index 274dacbeb..03ada932f 100644
> --- a/Documentation/ref/index.rst
> +++ b/Documentation/ref/index.rst
> @@ -39,6 +39,7 @@ time:
>   .. toctree::
>      :maxdepth: 3
>   
> +   ovs-actions.7
>      ovs-appctl.8
>      ovs-ctl.8
>      ovs-l3ping.8
> @@ -57,10 +58,6 @@ The remainder are still in roff format can be found below:
>   
>   .. list-table::
>   
> -   * - ovs-actions(7)
> -     - `(pdf) <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.openvswitch.org%2Fsupport%2Fdist-docs%2Fovs-actions.7.pdf&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859758396%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=%2FcxH02HXX3moS7VCloFG8ndO05YbLAVe45tBN2Fzxsw%3D&reserved=0>`__
> -     - `(html) <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.openvswitch.org%2Fsupport%2Fdist-docs%2Fovs-actions.7.html&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=ADHOZ4pHGiaqo6%2BUcGpr3pUJiPVStPbJ40s1VZj4APs%3D&reserved=0>`__
> -     - `(plain text) <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.openvswitch.org%2Fsupport%2Fdist-docs%2Fovs-actions.7.txt&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=R0C15Agq6HN%2FSvrtRW0Dr2BaDZIadcysZdXZc9a9JXU%3D&reserved=0>`__
>      * - ovs-bugtool(8)
>        - `(pdf) <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.openvswitch.org%2Fsupport%2Fdist-docs%2Fovs-bugtool.8.pdf&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=usNwmh2APwGB14UniInNYAqz6ECiEPrDk%2Bf9QEH6rwI%3D&reserved=0>`__
>        - `(html) <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.openvswitch.org%2Fsupport%2Fdist-docs%2Fovs-bugtool.8.html&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=WNMKmxXG1UzrDuEF%2BjsHQ%2B5k%2Fwqdf%2F901jkTY%2BOJm4A%3D&reserved=0>`__
> diff --git a/Documentation/ref/ovs-actions.7.rst b/Documentation/ref/ovs-actions.7.rst
> new file mode 100644
> index 000000000..7224896df
> --- /dev/null
> +++ b/Documentation/ref/ovs-actions.7.rst
> @@ -0,0 +1,2332 @@
> +..
> +      Copyright (c) 2018 Nicira, Inc.
> +      Copyright (c) 2021 RedHat, Inc.
> +
> +      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
> +
> +          https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.apache.org%2Flicenses%2FLICENSE-2.0&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=8BC7SDSR7E4CoiqNkuK9dFZLVaxnUpJMotOj4NHU4Dg%3D&reserved=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.
> +
> +      Convention for heading levels in Open vSwitch documentation:
> +
> +      =======  Heading 0 (reserved for the title in a document)
> +      -------  Heading 1
> +      ~~~~~~~  Heading 2
> +      +++++++  Heading 3
> +      '''''''  Heading 4
> +
> +      Avoid deeper levels because they do not render well.
> +
> +===========
> +ovs-actions
> +===========
> +
> +Introduction
> +============
> +
> +This document aims to comprehensively document all of the OpenFlow actions and
> +instructions, both standard and non-standard, supported by Open vSwitch,
> +regardless of origin.  The document includes information of interest to
> +Open vSwitch users, such as the semantics of each supported action and the
> +syntax used by Open vSwitch tools, and to developers seeking to build
> +controllers and switches compatible with Open vSwitch, such as the wire format
> +for each supported message.
> +
> +Actions
> +-------
> +
> +In this document, we define an ``action`` as an OpenFlow action, which is a
> +kind of command that specifies what to do with a packet.  Actions are used in
> +OpenFlow flows to describe what to do when the flow matches a packet, and in
> +a few other places in OpenFlow.  Each version of the OpenFlow specification
> +defines standard actions, and beyond that many OpenFlow switches, including
> +Open vSwitch, implement extensions to the standard.
> +
> +OpenFlow groups actions in two ways: as an ``action list`` or an
> +``action set``, described below.
> +
> +Action Lists
> +~~~~~~~~~~~~
> +
> +An ``action list``, a concept present in every version of OpenFlow, is simply
> +an ordered sequence of actions.  The OpenFlow specifications require a switch
> +to execute actions within an action list in the order specified, and to refuse
> +to execute an action list entirely if it cannot implement the actions in that
> +order [OpenFlow 1.0, section 3.3], with one exception: when an action list
> +outputs multiple packets, the switch may output the packets in an order
> +different from that specified.  Usually, this exception is not important,
> +especially in the common case when the packets are output to different ports.
> +
> +Action Sets
> +~~~~~~~~~~~
> +
> +OpenFlow 1.1 introduced the concept of an ``action set``.  An action set is
> +also a sequence of actions, but the switch reorders the actions and drops
> +duplicates according to rules specified in the OpenFlow specifications.
> +Because of these semantics, some standard OpenFlow actions cannot usefully be
> +included in an action set.  For some, but not all, Open vSwitch extension
> +actions, Open vSwitch defines its own action set semantics and ordering.
> +
> +The OpenFlow pipeline has an action set associated with it as a packet is
> +processed.  After pipeline processing is otherwise complete, the switch
> +executes the actions in the action set.
> +
> +Open vSwitch applies actions in an action set in the following order:
> +Except as noted otherwise below, the action set only executes at most a single
> +action of each type, and when more than one action of a given type is present,
> +the one added to the set later replaces the earlier action:
> +
> +  #. ``strip_vlan``
> +  #. ``pop_mpls``
> +  #. ``decap``
> +  #. ``encap``
> +  #. ``push_mpls``
> +  #. ``push_vlan``
> +  #. ``dec_ttl``
> +  #. ``dec_mpls_ttl``
> +  #. ``dec_nsh_ttl``
> +  #. All of the following actions are executed in the order added to the action
> +     set, with cumulative effect.  That is, when multiple actions modify the
> +     same part of a field, the later modification takes effect, and when they
> +     modify different parts of a field (or different fields), then both
> +     modifications are applied:
> +
> +       - ``load``
> +       - ``move``
> +       - ``mod_dl_dst``
> +       - ``mod_dl_src``
> +       - ``mod_nw_dst``
> +       - ``mod_nw_src``
> +       - ``mod_nw_tos``
> +       - ``mod_nw_ecn``
> +       - ``mod_nw_ttl``
> +       - ``mod_tp_dst``
> +       - ``mod_tp_src``
> +       - ``mod_vlan_pcp``
> +       - ``mod_vlan_vid``
> +       - ``set_field``
> +       - ``set_tunnel``
> +       - ``set_tunnel64``
> +
> +  #. ``set_queue``
> +  #. ``group``, ``output``, ``resubmit``, ``ct_clear``, or ``ct``.  If more
> +     than one of these actions is present, then the one listed earliest above
> +     is executed and the others are ignored, regardless of the order in which
> +     they were added to the action set.  (If none of these actions is present,
> +     the action set has no real effect, because the modified packet is not sent
> +     anywhere and thus the modifications are not visible.)
> +
> +An action set may only contain the actions listed above.
> +
> +Error Handling
> +--------------
> +
> +Packet processing can encounter a variety of errors:
> +
> +Bridge not found
> +  Open vSwitch supports an extension to the standard OpenFlow ``controller``
> +  action called a ``continuation``, which allows the controller to interrupt
> +  and later resume the processing of a packet through the switch pipeline.
> +  This error occurs when such a packet's processing cannot be resumed, e.g.
> +  because the bridge processing it has been destroyed.  Open vSwitch reports
> +  this error to the controller as Open vSwitch extension error ``NXR_STALE``.
> +
> +  This error prevents packet processing entirely.
> +
> +Recursion too deep
> +  While processing a given packet, Open vSwitch limits the flow table recursion
> +  depth to 64, to ensure that packet processing uses a finite amount of time
> +  and space.  Actions that count against the recursion limit include
> +  ``resubmit`` from a given OpenFlow table to the same or an earlier table,
> +  ``group``, and ``output`` to patch ports.
> +
> +  A ``resubmit`` from one table to a later one (or, equivalently, a
> +  ``goto_table`` instruction) does not count against the depth limit because
> +  resubmits to strictly monotonically increasing tables will eventually
> +  terminate.  OpenFlow tables are most commonly traversed in numerically
> +  increasing order, so this limit has little effect on conventionally designed
> +  OpenFlow pipelines.
> +
> +  This error terminates packet processing.  Any previous side effects
> +  (e.g. output actions) are retained.
> +
> +  Usually this error indicates a loop or other bug in the OpenFlow flow tables.
> +  To assist debugging, when this error occurs, Open vSwitch 2.10 and later logs
> +  a trace of the packet execution, as if by ``ovs-appctl ofproto/trace``,
> +  rate-limited to one per minute to reduce the log volume.
> +
> +Too many resubmits
> +  Open vSwitch limits the total number of ``resubmit`` actions that a given
> +  packet can execute to 4,096.  For this purpose, ``goto_table`` instructions
> +  and output to the ``table`` port are treated like ``resubmit``.  This limits
> +  the amount of time to process a single packet.
> +
> +  Unlike the limit on recursion depth, the limit on resubmits counts all
> +  resubmits, regardless of direction.
> +
> +  This error has the same effect, including logging, as exceeding the recursion
> +  depth limit.
> +
> +Stack too deep
> +  Open vSwitch limits the amount of data that the ``push`` action can put onto
> +  the stack at one time to 64 kB of data.
> +
> +  This error terminates packet processing.  Any previous side effects
> +  (e.g. output actions) are retained.
> +
> +No recirculation context / Recirculation conflict
> +  These errors indicate internal errors inside Open vSwitch and should
> +  generally not occur.  If you notice recurring log messages about these
> +  errors, please report a bug.
> +
> +Too many MPLS labels
> +  Open vSwitch can process packets with any number of MPLS labels, but its
> +  ability to push and pop MPLS labels is limited, currently to 3 labels.
> +  Attempting to push more than the supported number of labels onto a packet,
> +  or to pop any number of labels from a packet with more than the supported
> +  number, raises this error.
> +
> +  This error terminates packet processing, retaining any previous side effects
> +  (e.g. output actions).  When this error arises within the execution of a
> +  group bucket, it only terminates that bucket's execution, not packet
> +  processing overall.
> +
> +Invalid tunnel metadata
> +  Open vSwitch raises this error when it processes a Geneve packet that has TLV
> +  options with an invalid form, e.g. where the length in a TLV would extend
> +  past the end of the options.
> +
> +  This error prevents packet processing entirely.
> +
> +Unsupported packet type
> +  When a ``encap`` action encapsulates a packet, Open vSwitch raises this error
> +  if it does not support the combination of the new encapsulation with the
> +  current packet.  ``encap(ethernet)`` raises this error if the current packet
> +  is not an L3 packet, and ``encap(nsh)`` raises this error if the current
> +  packet is not Ethernet, IPv4, IPv6, or NSH.
> +
> +  When a ``decap`` action decapsulates a packet, Open vSwitch raises this error
> +  if it does not support the type of inner packet.  ``decap`` of an Ethernet
> +  header raises this error if a VLAN header is present, ``decap`` of a NSH
> +  packet raises this error if the NSH inner packet is not Ethernet, IPv4, IPv6,
> +  or NSH, and ``decap`` of other types of packets is unsupported and also
> +  raises this error.
> +
> +  This error terminates packet processing, retaining any previous side effects
> +  (e.g. output actions).  When this error arises within the execution of a
> +  group bucket, it only terminates that bucket's execution, not packet
> +  processing overall.
> +
> +Inconsistencies
> +---------------
> +
> +OpenFlow 1.0 allows any action to be part of any flow, regardless of the flow's
> +match.  Some combinations do not make sense, e.g. an ``set_nw_tos`` action in a
> +flow that matches only ARP packets or ``strip_vlan`` in a flow that matches
> +packets without VLAN tags.  Other combinations have varying results depending
> +on the kind of packet that the flow processes, e.g. a ``set_nw_src`` action in
> +a flow that does not match on Ethertype will be treated as a no-op when it
> +processes a non-IPv4 packet.  Nevertheless OVS allows all of the above in
> +conformance with OpenFlow 1.0, that is, the following will succeed::
> +
> +  $ ovs-ofctl -O OpenFlow10 add-flow br0 arp,actions=mod_nw_tos:12
> +  $ ovs-ofctl -O OpenFlow10 add-flow br0 dl_vlan=0xffff,actions=strip_vlan
> +  $ ovs-ofctl -O OpenFlow10 add-flow br0 actions=mod_nw_src:1.2.3.4
> +
> +Open vSwitch calls these kinds of combinations ``inconsistencies`` between
> +match and actions.  OpenFlow 1.1 and later forbid inconsistencies, and disallow
> +the examples described above by preventing such flows from being added.  All of
> +the above, for example, will fail with an error message if one replaces
> +``OpenFlow10`` by ``OpenFlow11``.
> +
> +OpenFlow 1.1 and later cannot detect and disallow all inconsistencies.  For
> +example, the ``write_actions`` instruction arbitrarily delays execution of the
> +actions inside it, which can even be canceled with ``clear_actions``, so that
> +there is no way to ensure that its actions are consistent with the packet at
> +the time they execute.  Thus, actions with ``write_actions`` and some other
> +contexts are exempt from consistency requirements.
> +
> +When OVS executes an action inconsistent with the packet, it treats it as a
> +no-op.
> +
> +Inter-Version Compatibility
> +---------------------------
> +
> +Open vSwitch supports multiple OpenFlow versions simultaneously on a single
> +switch.  When actions are added with one OpenFlow version and then retrieved
> +with another, Open vSwitch does its best to translate between them.
> +
> +Inter-version compatibility issues can still arise when different connections
> +use different OpenFlow versions.  Backward compatibility is the most obvious
> +case.  Suppose, for example, that an OpenFlow 1.1 session adds a flow with a
> +``push_vlan`` action, for which there is no equivalent in OpenFlow 1.0.  If an
> +OpenFlow 1.0 session retrieves this flow, Open vSwitch must somehow represent
> +the action.
> +
> +Forward compatibility can also be an issue, because later OpenFlow versions
> +sometimes remove functionality.  The best example is the ``enqueue`` action
> +from OpenFlow 1.0, which OpenFlow 1.1 removed.
> +
> +In practice, Open vSwitch uses a variety of strategies for inter-version
> +compatibility:
> +
> +- Most standard OpenFlow actions, such as ``output`` actions, translate without
> +  compatibility issues.
> +
> +- Open vSwitch supports its extension actions in every OpenFlow version, so
> +  they do not pose inter-version compatibility problems.
> +
> +- Open vSwitch sometimes adds extension actions to ensure backward or forward
> +  compatibility.  For example, for backward compatibility with the ``group``
> +  action added in OpenFlow 1.1, Open vSwitch includes an OpenFlow 1.0 extension
> +  ``group`` action.
> +
> +Perfect inter-version compatibility is not possible, so best results require
> +OpenFlow connections to use a consistent version.  One may enforce use of a
> +particular version by setting the ``protocols`` column for a bridge, e.g. to
> +force ``br0`` to use only OpenFlow 1.3::
> +
> +  ovs-vsctl set bridge br0 protocols=OpenFlow13
> +
> +Field Specifications
> +--------------------
> +
> +Many Open vSwitch actions refer to fields.  In such cases, fields may usually
> +be referred to by their common names, such as ``eth_dst`` for the Ethernet
> +destination field, or by their full OXM or NXM names, such as
> +``NXM_OF_ETH_DST`` or ``OXM_OF_ETH_DST``.  Before Open vSwitch 2.7, only OXM or
> +NXM field names were accepted.
> +
> +Many actions that act on fields can also act on ``subfields``, that is, parts
> +of fields, written as ``field[start..end]``, where ``start`` is the first bit
> +and ``end`` is the last bit to use in ``field``, e.g. ``vlan_tci[13..15]`` for
> +the VLAN PCP.  A single-bit subfield may also be written as ``field[offset]``,
> +e.g. ``vlan_tci[13]`` for the least-significant bit of the VLAN PCP.  Empty
> +brackets may be used to explicitly designate an entire field, e.g.
> +``vlan_tci[]`` for the entire 16-bit VLAN TCI header.  Before Open vSwitch 2.7,
> +brackets were required in field specifications.
> +
> +See ``ovs-fields(7)`` for a list of fields and their names.
> +
> +Port Specifications
> +-------------------
> +
> +Many Open vSwitch actions refer to OpenFlow ports.  In such cases, the port may
> +be specified as a numeric port number in the range 0 to 65,535, although
> +Open vSwitch only assigns port numbers in the range 1 through 62,279 to ports.
> +OpenFlow 1.1 and later use 32-bit port numbers, but Open vSwitch never assigns
> +a port number that requires more than 16 bits.
> +
> +In most contexts, the name of a port may also be used.  (The most obvious
> +context where a port name may not be used is in an ``ovs-ofctl`` command along
> +with the ``--no-names`` option.)  When a port's name contains punctuation or
> +could be ambiguous with other actions, the name may be enclosed in double
> +quotes, with JSON-like string escapes supported (see [RFC 8259]).
> +
> +Open vSwitch also supports the following standard OpenFlow port names (even
> +in contexts where port names are not otherwise supported).  The corresponding
> +OpenFlow 1.0 and 1.1+ port numbers are listed alongside them but should not be
> +used in flow syntax:
> +
> +  - ``in_port`` (65528 or 0xfff8; 0xfffffff8)
> +  - ``table`` (65529 or 0xfff9; 0xfffffff9)
> +  - ``normal`` (65530 or 0xfffa; 0xfffffffa)
> +  - ``flood`` (65531 or 0xfffb; 0xfffffffb)
> +  - ``all`` (65532 or 0xfffc; 0xfffffffc)
> +  - ``controller`` (65533 or 0xfffd; 0xfffffffd)
> +  - ``local`` (65534 or 0xfffe; 0xfffffffe)
> +  - ``any`` or ``none`` (65535 or 0xffff; 0xffffffff)
> +  - ``unset`` (not in OpenFlow 1.0; 0xfffffff7)
> +
> +..
> +  <!-- What about OVS version compatibility as opposed to OF version -->
> +
> +Output Actions
> +==============
> +
> +These actions send a packet to a physical port or a controller.  A packet that
> +never encounters an output action on its trip through the Open vSwitch pipeline
> +is effectively dropped.  Because actions are executed in order, a packet
> +modification action that is not eventually followed by an output action will
> +not have an externally visible effect.
> +
> +The ``output`` action
> +---------------------
> +..
> +  name: OUTPUT, OUTPUT_REG, OUTPUT_TRUNC
> +
> +**Syntax**:
> +  | *port*
> +  | ``output:``\ *port*
> +  | ``output:``\ *field*
> +  | ``output(port=``\ *port*\ ``, max_len=``\ *nbytes*\ ``)``
> +
> +Outputs the packet to an OpenFlow port most commonly specified as *port*.
> +Alternatively, the output port may be read from *field*, a field or subfield
> +in the syntax described under `Field Specifications`_ above.  Either way, if
> +the port is the packet's input port, the packet is not output.
> +
> +The *port* may be one of the following standard OpenFlow ports:
> +
> +  ``local``
> +    Outputs the packet on the ``local port`` that corresponds to the network
> +    device that has the same name as the bridge, unless the packet was received
> +    on the local port.  OpenFlow switch implementations are not required to
> +    have a local port, but Open vSwitch bridges always do.
> +
> +  ``in_port``
> +    Outputs the packet on the port on which it was received.  This is the only
> +    standard way to output the packet to the input port (but see
> +    `Output to the Input port`_, below).
> +
> +The *port* may also be one of the following additional OpenFlow ports, unless
> +``max_len`` is specified:
> +
> +  ``normal``
> +    Subjects the packet to the device's normal L2/L3 processing.  This action
> +    is not implemented by all OpenFlow switches, and each switch implements it
> +    differently.  The section `The OVS Normal Pipeline`_ below documents the
> +    OVS implementation.
> +
> +  ``flood``
> +    Outputs the packet on all switch physical ports, except the port on which
> +    it was received and any ports on which flooding is disabled.  Flooding can
> +    be disabled automatically on a port by Open vSwitch when IEEE 802.1D
> +    spanning tree (STP) or rapid spanning tree (RSTP) is enabled, or by a
> +    controller using an OpenFlow ``OFPT_MOD_PORT`` request to set the port's
> +    ``OFPPC_NO_FLOOD`` flag (``ovs-ofctl mod-port`` provides a command-line
> +    interface to set this flag).
> +
> +  ``all``
> +    Outputs the packet on all switch physical ports except the port on which it
> +    was received.
> +
> +  ``controller``
> +    Sends the packet and its metadata to an OpenFlow controller or controllers
> +    encapsulated in an OpenFlow ``packet-in`` message.  The separate
> +    ``controller`` action, described below, provides more options for output to
> +    a controller.
> +
> +Open vSwitch rejects output to other standard OpenFlow ports, including
> +``none``, ``unset``, and port numbers reserved for future use as standard
> +ports, with the error ``OFPBAC_BAD_OUT_PORT``.
> +
> +With ``max_len``, the packet is truncated to at most *nbytes* bytes before
> +being output.  In this case, the output port may not be a patch port.
> +Truncation is just for the single output action, so that later actions in the
> +OpenFlow pipeline work with the complete packet.  The truncation feature is
> +meant for use in monitoring applications, e.g. for mirroring packets to a
> +collector.
> +
> +When an ``output`` action specifies the number of a port that does not
> +currently exist (and is not in the range for standard ports), the OpenFlow
> +specification allows but does not require OVS to reject the action.  All
> +versions of Open vSwitch treat such an action as a no-op.  If a port with the
> +number is created later, then the action will be honored at that point.
> +(OpenFlow requires OVS to reject output to a port number that will never be
> +valid, with ``OFPBAC_BAD_OUT_PORT``, but this situation does not arise when OVS
> +is a software switch, since the user can add or renumber ports at any time.)
> +
> +A controller can suppress output to a port by setting its ``OFPPC_NO_FORWARD``
> +flag using an OpenFlow ``OFPT_MOD_PORT`` request (``ovs-ofctl mod-port``
> +provides a command-line interface to set this flag).  When output is disabled,
> +``output`` actions (and other actions that output to the port) are allowed but
> +have no effect.
> +
> +Open vSwitch allows output to a port that does not exist, although OpenFlow
> +allows switches to reject such actions.
> +
> +..
> +  <!-- XXX output to patch ports details -->
> +
> +**Conformance**
> +  All versions of OpenFlow and Open vSwitch support ``output`` to a literal
> +  ``port``.  Output to a register is an OpenFlow extension introduced in
> +  Open vSwitch 1.3.  Output with truncation is an OpenFlow extension introduced
> +  in Open vSwitch 2.6.
> +
> +Output to the Input Port
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +OpenFlow requires a switch to ignore attempts to send a packet out its ingress
> +port in the most straightforward way.  For example, ``output:234`` has no
> +effect if the packet has ingress port 234.  The rationale is that dropping
> +these packets makes it harder to loop the network.  Sometimes this behavior can
> +even be convenient, e.g. it is often the desired behavior in a flow that
> +forwards a packet to several ports (``floods`` the packet).
> +
> +Sometimes one really needs to send a packet out its ingress port (``hairpin``).
> +In this case, use ``in_port`` to explicitly output the packet to its input
> +port, e.g.::
> +
> +  $ ovs-ofctl add-flow br0 in_port=2,actions=in_port
> +
> +This also works in some circumstances where the flow doesn't match on the input
> +port.  For example, if you know that your switch has five ports numbered 2
> +through 6, then the following will send every received packet out every port,
> +even its ingress port::
> +
> +  $ ovs-ofctl add-flow br0 actions=2,3,4,5,6,in_port
> +
> +or, equivalently::
> +
> +  $ ovs-ofctl add-flow br0 actions=all,in_port
> +
> +Sometimes, in complicated flow tables with multiple levels of ``resubmit``
> +actions, a flow needs to output to a particular port that may or may not be the
> +ingress port.  It's difficult to take advantage of output to ``in_port`` in
> +this situation.  To help, Open vSwitch provides, as an OpenFlow extension, the
> +ability to modify the ``in_port`` field.  Whatever value is currently in the
> +``in_port`` field is both the port to which output will be dropped and the
> +destination for ``in_port``.  This means that the following adds flows that
> +reliably output to port 2 or to ports 2 through 6, respectively::
> +
> +  $ ovs-ofctl add-flow br0 "in_port=2,actions=load:0->in_port,2"
> +  $ ovs-ofctl add-flow br0 "actions=load:0->in_port,2,3,4,5,6"
> +
> +If ``in_port`` is important for matching or other reasons, one may save and
> +restore it on the stack::
> +
> +  $ ovs-ofctl add-flow br0 \
> +        actions="push:in_port,load:0->in_port,2,3,4,5,6,pop:in_port"
> +
> +
> +The OVS Normal Pipeline
> +-----------------------
> +
> +This section documents how Open vSwitch implements output to the ``normal``
> +port.  The OpenFlow specification places no requirements on how this port
> +works, so all of this documentation is specific to Open vSwitch.
> +
> +Open vSwitch uses the ``Open_vSwitch`` database, detailed in
> +``ovs-vswitchd.conf.db(5)``, to determine the details of the normal pipeline.
> +
> +The normal pipeline executes the following ingress stages for each packet.
> +Each stage either accepts the packet, in which case the packet goes on to the
> +next stage, or drops the packet, which terminates the pipeline.  The result of
> +the ingress stages is a set of output ports, which is the empty set if some
> +ingress stage drops the packet:
> +
> +#. **Input port lookup**: Looks up the OpenFlow ``in_port`` field's value to
> +   the corresponding ``Port`` and ``Interface`` record in the database.
> +
> +   The ``in_port`` is normally the OpenFlow port that the packet was received
> +   on.  If ``set_field`` or another actions changes the ``in_port``, the
> +   updated value is honored.  Accept the packet if the lookup succeeds, which
> +   it normally will.  If the lookup fails, for example because ``in_port`` was
> +   changed to an unknown value, drop the packet.
> +
> +#. **Drop malformed packet**: If the packet is malformed enough that it
> +   contains only part of an 802.1Q header, then drop the packet with an error.
> +
> +#. **Drop packets sent to a port reserved for mirroring**: If the packet was
> +   received on a port that is configured as the output port for a mirror (that
> +   is, it is the ``output_port`` in some ``Mirror`` record), then drop the
> +   packet.
> +
> +#. **VLAN input processing**: This stage determines what VLAN the packet is in.
> +   It also verifies that this VLAN is valid for the port; if not, drop the
> +   packet.  How the VLAN is determined and which ones are valid vary based on
> +   the ``vlan-mode`` in the input port's ``Port`` record:
> +
> +     ``trunk``
> +       The packet is in the VLAN specified in its 802.1Q header, or in VLAN 0
> +       if there is no 802.1Q header.  The ``trunks`` column in the ``Port``
> +       record lists the valid VLANs; if it is empty, all VLANs are valid.
> +
> +     ``access``
> +       The packet is in the VLAN specified in the ``tag`` column of its
> +       ``Port`` record.  The packet must not have an 802.1Q header with a
> +       nonzero VLAN ID; if it does, drop the packet.
> +
> +     ``native-tagged`` / ``native-untagged``
> +       Same as ``trunk`` except that the VLAN of a packet without an 802.1Q
> +       header is not necessarily zero; instead, it is taken from the ``tag``
> +       column.
> +
> +     ``dot1q-tunnel``
> +       The packet is in the VLAN specified in the ``tag`` column of its
> +       ``Port`` record, which is a QinQ service VLAN with the Ethertype
> +       specified by the ``Port``'s ``other_config:qinq-ethtype``.  If the
> +       packet has an 802.1Q header, then it specifies the customer VLAN.  The
> +       ``cvlans`` column specifies the valid customer VLANs; if it is empty,
> +       all customer VLANs are valid.
> +
> +#. **Drop reserved multicast addresses**: If the packet is addressed to a
> +   reserved Ethernet multicast address and the ``Bridge`` record does not have
> +   ``other_config:forward-bpdu`` set to ``true``, drop the packet.
> +
> +#. **LACP bond admissibility**: This step applies only if the input port is a
> +   member of a bond (a ``Port`` with more than one ``Interface``) and that bond
> +   is configured to use LACP. Otherwise, skip to the next step.
> +
> +   The behavior here depends on the state of LACP negotiation:
> +
> +     - If LACP has been negotiated with the peer, accept the packet if the bond
> +       member is enabled (i.e. carrier is up and it hasn't been
> +       administratively disabled).  Otherwise, drop the packet.
> +
> +     - If LACP negotiation is incomplete, then drop the packet.  There is
> +       one exception: if fallback to active-backup mode is enabled, continue
> +       with the next step, pretending that the active-backup balancing mode is
> +       in use.
> +
> +#. **Non-LACP bond admissibility**: This step applies if the input port is a
> +   member of a bond without LACP configured, or if a LACP bond falls back to
> +   active-backup as described in the previous step.  If neither of these
> +   applies, skip to the next step.
> +
> +   If the packet is an Ethernet multicast or broadcast, and not received on the
> +   bond's active member, drop the packet.
> +
> +   The remaining behavior depends on the bond's balancing mode:
> +
> +     L4 (aka TCP balancing)
> +       Drop the packet (this balancing mode is only supported with LACP).
> +
> +     Active-backup
> +       Accept the packet only if it was received on the active member.
> +
> +     SLB (Source Load Balancing)
> +       Drop the packet if the bridge has not learned the packet's source
> +       address (in its VLAN) on the port that received it.  Otherwise, accept
> +       the packet unless it is a gratuitous ARP.  Otherwise, accept the packet
> +       if the MAC entry we found is ARP-locked.  Otherwise, drop the packet.
> +       (See the ``SLB Bonding`` section in the OVS bonding document for more
> +       information and a rationale.)
> +
> +#. **Learn source MAC**: If the source Ethernet address is not a multicast
> +   address, then insert a mapping from packet's source Ethernet address and
> +   VLAN to the input port in the bridge's MAC learning table.  (This is skipped
> +   if the packet's VLAN is listed in the switch's ``Bridge`` record in the
> +   ``flood_vlans`` column, since there is no use for MAC learning when all
> +   packets are flooded.)
> +
> +   When learning happens on a non-bond port, if the packet is a gratuitous ARP,
> +   the entry is marked as ARP-locked.  The lock expires after 5 seconds.  (See
> +   the ``SLB Bonding`` section in the OVS bonding document for more information
> +   and a rationale.)
> +
> +#. **IP multicast path**: If multicast snooping is enabled on the bridge, and
> +   the packet is an Ethernet multicast but not an Ethernet broadcast, and the
> +   packet is an IP packet, then the packet takes a special processing path.
> +   This path is not yet documented here.
> +
> +   ..
> +     <!-- XXX document multicast processing -->
> +
> +#. **Output port set**: Search the MAC learning table for the port
> +   corresponding to the packet's Ethernet destination and VLAN.  If the search
> +   finds an entry, the output port set is just the learned port.  Otherwise
> +   (including the case where the packet is an Ethernet multicast or in
> +   ``flood_vlans``), the output port set is all of the ports in the bridge that
> +   belong to the packet's VLAN, except for any ports that were disabled for
> +   flooding via OpenFlow or that are configured in a ``Mirror`` record as a
> +   mirror destination port.
> +
> +The following egress stages execute once for each element in the set of output
> +ports.  They execute (conceptually) in parallel, so that a decision or action
> +taken for a given output port has no effect on those for another one:
> +
> +#. **Drop loopback**: If the output port is the same as the input port, drop
> +   the packet.
> +
> +#. **VLAN output processing**: This stage adjusts the packet to represent the
> +   VLAN in the correct way for the output port.  Its behavior varies based on
> +   the ``vlan-mode`` in the output port's ``Port`` record:
> +
> +     ``trunk`` / ``native-tagged`` / ``native-untagged``
> +       If the packet is in VLAN 0 (for ``native-untagged``, if the packet is in
> +       the native VLAN) drops any 802.1Q header.  Otherwise, ensures that there
> +       is an 802.1Q header designating the VLAN.
> +
> +     ``access``
> +       Remove any 802.1Q header that was present.
> +
> +     ``dot1q-tunnel``
> +       Ensures that the packet has an outer 802.1Q header with the QinQ
> +       Ethertype and the specified configured tag, and an inner 802.1Q header
> +       with the packet's VLAN.
> +
> +#. **VLAN priority tag processing**: If VLAN output processing discarded the
> +   802.1Q headers, but priority tags are enabled with
> +   ``other_config:priority-tags`` in the output port's ``Port`` record, then a
> +   priority-only tag is added (perhaps only if the priority would be nonzero,
> +   depending on the configuration).
> +
> +#. **Bond member choice**: If the output port is a bond, the code chooses a
> +   particular member.  This step is skipped for non-bonded ports.
> +
> +   If the bond is configured to use LACP, but LACP negotiation is incomplete,
> +   then normally the packet is dropped.  The exception is that if fallback to
> +   active-backup mode is enabled, the egress pipeline continues choosing a bond
> +   member as if active-backup mode was in use.
> +
> +   For active-backup mode, the output member is the active member.  Other modes
> +   hash appropriate header fields and use the hash value to choose one of the
> +   enabled members.
> +
> +#. **Output**: The pipeline sends the packet to the output port.
> +
> +
> +The ``controller`` action
> +-------------------------
> +..
> +  name: CONTROLLER
> +
> +**Syntax**:
> +  | ``controller``
> +  | ``controller:``\ *max_len*
> +  | ``controller(``\ *key*\ ``[=``\ *value*\ ``], ...)``
> +
> +Sends the packet and its metadata to an OpenFlow controller or controllers
> +encapsulated in an OpenFlow ``packet-in`` message.  The supported options are:
> +
> +  ``max_len=``\ *max_len*
> +    Limit to *max_len* the number of bytes of the packet to send in the
> +    ``packet-in.``  A *max_len* of 0 prevents any of the packet from being
> +    sent (thus, only metadata is included).  By default, the entire packet is
> +    sent, equivalent to a *max_len* of 65535.
> +
> +  ``reason=``\ *reason*
> +    Specify *reason* as the reason for sending the message in the
> +    ``packet-in``.  The supported reasons are ``no_match``, ``action``,
> +    ``invalid_ttl``, ``action_set``, ``group``, and ``packet_out``.  The
> +    default reason is ``action``.
> +
> +  ``id=``\ *controller_id*
> +    Specify *controller_id*, a 16-bit integer, as the connection ID of the
> +    OpenFlow controller or controllers to which the ``packet-in`` message
> +    should be sent.  The default is zero.  Zero is also the default connection
> +    ID for each controller connection, and a given controller connection will
> +    only have a nonzero connection ID if its controller uses the
> +    ``NXT_SET_CONTROLLER_ID`` Open vSwitch extension to OpenFlow.
> +
> +  ``userdata=``\ *hh*\ ``...``
> +    Supplies the bytes represented as hex digits *hh* as additional data to
> +    the controller in the ``packet-in`` message.  Pairs of hex digits may be
> +    separated by periods for readability.
> +
> +  ``pause``
> +    Causes the switch to freeze the packet's trip through Open vSwitch flow
> +    tables and serializes that state into the packet-in message as a
> +    ``continuation,`` an additional property in the ``NXT_PACKET_IN2`` message.
> +    The controller can later send the continuation back to the switch in an
> +    ``NXT_RESUME`` message, which will restart the packet's traversal from the
> +    point where it was interrupted.  This permits an OpenFlow controller to
> +    interpose on a packet midway through processing in Open vSwitch.
> +
> +**Conformance**
> +  All versions of OpenFlow and Open vSwitch support ``controller`` action and
> +  its ``max_len`` option.  The ``userdata`` and ``pause`` options require the
> +  Open vSwitch ``NXAST_CONTROLLER2`` extension action added in Open vSwitch
> +  2.6. In the absence of these options, the ``reason`` (other than
> +  ``reason=action``) and ``controller_id`` (option than ``controller_id=0``)
> +  options require the Open vSwitch ``NXAST_CONTROLLER`` extension action added
> +  in Open vSwitch 1.6.
> +
> +
> +The ``enqueue`` action
> +----------------------
> +..
> +  name: ENQUEUE
> +
> +**Syntax**:
> +  | ``enqueue(``\ *port*\ ``,``\ *queue*\ ``)``
> +  | ``enqueue:``\ *port*\ ``:``\ *queue*
> +
> +Enqueues the packet on the specified *queue* within port *port*.
> +
> +*port* must be an OpenFlow port number or name as described under
> +`Port Specifications`_ above.  *port* may be ``in_port`` or ``local`` but the
> +other standard OpenFlow ports are not allowed.
> +
> +*queue* must be a number between 0 and 4294967294 (0xfffffffe), inclusive.
> +The number of actually supported queues depends on the switch.  Some OpenFlow
> +implementations do not support queuing at all.  In Open vSwitch, the supported
> +queues vary depending on the operating system, datapath, and hardware in use.
> +Use the ``QoS`` and ``Queue`` tables in the Open vSwitch database to configure
> +queuing on individual OpenFlow ports (see ``ovs-vswitchd.conf.db(5)`` for more
> +information).
> +
> +**Conformance**
> +  Only OpenFlow 1.0 supports ``enqueue``.  OpenFlow 1.1 added the ``set_queue``
> +  action to use in its place along with ``output``.
> +
> +  Open vSwitch translates ``enqueue`` to a sequence of three actions in
> +  OpenFlow 1.1 or later: ``set_queue:``\ *queue*\ ``,output:``\ *port*\
> +  ``,pop_queue``.  This is equivalent in behavior as long as the flow table
> +  does not otherwise use ``set_queue``, but it relies on the ``pop_queue``
> +  Open vSwitch extension action.
> +
> +
> +The ``bundle`` and ``bundle_load`` actions
> +------------------------------------------
> +..
> +  name: BUNDLE, BUNDLE_LOAD
> +
> +**Syntax**:
> +  | ``bundle(``\ *fields*\ ``,``\ *basis*\ ``,``\ *algorithm*\
> +             ``,ofport,members:``\ *port*\ ``...)``
> +  | ``bundle_load(``\ *fields*\ ``,``\ *basis*\ ``,``\ *algorithm*\
> +                  ``,ofport,``\ *dst*\ ``,members:``\ *port*\ ``...)``
> +
> +These actions choose a port (a ``member``) from a comma-separated OpenFlow
> +*port* list.  After selecting the port, ``bundle`` outputs to it, whereas
> +``bundle_load`` writes its port number to *dst*, which must be a 16-bit or
> +wider field or subfield in the syntax described under `Field Specifications`_
> +above.
> +
> +These actions hash a set of *fields* using *basis* as a universal hash
> +parameter, then apply the bundle link selection *algorithm* to choose a *port*.
> +
> +*fields* must be one of the following.  For the options with ``symmetric`` in
> +the name, reversing source and destination addresses yields the same hash:
> +
> +  ``eth_src``
> +    Ethernet source address.
> +
> +  ``nw_src``
> +    IPv4 or IPv6 source address.
> +
> +  ``nw_dst``
> +    IPv4 or IPv6 destination address.
> +
> +  ``symmetric_l4``
> +    Ethernet source and destination, Ethernet type, VLAN ID or IDs (if any),
> +    IPv4 or IPv6 source and destination, IP protocol, TCP or SCTP (but not UDP)
> +    source and destination.
> +
> +  ``symmetric_l3l4``
> +    IPv4 or IPv6 source and destination, IP protocol, TCP or SCTP (but not UDP)
> +    source and destination.
> +
> +  ``symmetric_l3l4+udp``
> +    Like ``symmetric_l3l4`` but include UDP ports.
> +
> +*algorithm* must be one of the following:
> +
> +  ``active_backup``
> +    Chooses the first live port listed in ``members``.
> +
> +  ``hrw`` (Highest Random Weight)
> +    Computes the following, considering only the live ports in ``members``::
> +
> +      for i in [1, n_members]:
> +          weights[i] = hash(flow, i)
> +      member = { i such that weights[i] >= weights[j] for all j != i }
> +
> +    This algorithm is specified by RFC 2992.
> +
> +The algorithms take port liveness into account when selecting members.  The
> +definition of whether a port is live is subject to change.  It currently takes
> +into account carrier status and link monitoring protocols such as BFD and CFM.
> +If none of the members is live, ``bundle`` does not output the packet and
> +``bundle_load`` stores ``OFPP_NONE`` (65535) in the output field.
> +
> +Example: ``bundle(eth_src,0,hrw,ofport,members:4,8)`` uses an Ethernet source
> +hash with basis 0, to select between OpenFlow ports 4 and 8 using the Highest
> +Random Weight algorithm.
> +
> +**Conformance**
> +  Open vSwitch 1.2 introduced the ``bundle`` and ``bundle_load`` OpenFlow
> +  extension actions.
> +
> +
> +The ``group`` action
> +--------------------
> +..
> +  name: GROUP
> +
> +**Syntax**:
> +  | ``group:``\ *group*
> +
> +Outputs the packet to the OpenFlow group *group*, which must be a number in
> +the range 0 to 4294967040 (0xffffff00).  The group must exist or Open vSwitch
> +will refuse to add the flow.  When a group is deleted, Open vSwitch also
> +deletes all of the flows that output to it.
> +
> +Groups contain action sets, whose semantics are described above in the section
> +`Action Sets`_.  The semantics of action sets can be surprising to users who
> +expect action list semantics, since action sets reorder and sometimes ignore
> +actions.
> +
> +A ``group`` action usually executes the action set or sets in one or more group
> +buckets.  Open vSwitch saves the packet and metadata before it executes each
> +bucket, and then restores it afterward.  Thus, when a group executes more than
> +one bucket, this means that each bucket executes on the same packet and
> +metadata.  Moreover, regardless of the number of buckets executed, the packet
> +and metadata are the same before and after executing the group.
> +
> +Sometimes saving and restoring the packet and metadata can be undesirable.  In
> +these situations, workarounds are possible.  For example, consider a pipeline
> +design in which a ``select`` group bucket is to communicate to a later stage of
> +processing a value based on which bucket was selected.  An obvious design would
> +be for the bucket to communicate the value via ``set_field`` on a register.
> +This does not work because registers are part of the metadata that ``group``
> +saves and restores.  The following alternative bucket designs do work:
> +
> +  - Recursively invoke the rest of the pipeline with ``resubmit``.
> +  - Use ``resubmit`` into a table that uses ``push`` to put the value on the
> +    stack for the caller to ``pop`` off.  This works because ``group``
> +    preserves only packet data and metadata, not the stack.
> +
> +    (This design requires indirection through ``resubmit`` because actions sets
> +    may not contain ``push`` or ``pop`` actions.)
> +
> +An ``exit`` action within a group bucket terminates only execution of that
> +bucket, not other buckets or the overall pipeline.
> +
> +**Conformance**
> +  OpenFlow 1.1 introduced ``group``.  Open vSwitch 2.6 and later also supports
> +  ``group`` as an extension to OpenFlow 1.0.
> +
> +
> +Encapsulation and Decapsulation Actions
> +=======================================
> +
> +The ``strip_vlan`` and ``pop`` actions
> +--------------------------------------
> +..
> +  name: STRIP_VLAN
> +
> +**Syntax**:
> +  | ``strip_vlan``
> +  | ``pop_vlan``
> +
> +Removes the outermost VLAN tag, if any, from the packet.
> +
> +The two names for this action are synonyms with no semantic difference.  The
> +OpenFlow 1.0 specification uses the name ``strip_vlan`` and later versions use
> +``pop_vlan``, but OVS accepts either name regardless of version.
> +
> +In OpenFlow 1.1 and later, consistency rules allow ``strip_vlan`` only in a
> +flow that matches only packets with a VLAN tag (or following an action that
> +pushes a VLAN tag, such as ``push_vlan``).  See `Inconsistencies`_, above, for
> +more information.
> +
> +**Conformance**
> +  All versions of OpenFlow and Open vSwitch support this action.
> +
> +
> +The ``push_vlan`` action
> +------------------------
> +..
> +  name: PUSH_VLAN
> +
> +**Syntax**:
> +  | ``push_vlan:``\ *ethertype*
> +
> +Pushes a new outermost VLAN onto the packet.  Uses TPID *ethertype*, which
> +must be ``0x8100`` for an 802.1Q C-tag or ``0x88a8`` for a 802.1ad S-tag.
> +
> +**Conformance**
> +  OpenFlow 1.1 and later supports this action.  Open vSwitch 2.8 added support
> +  for multiple VLAN tags (with a limit of 2) and 802.1ad S-tags.
> +
> +
> +The ``push_mpls`` action
> +------------------------
> +..
> +  name: PUSH_MPLS
> +
> +**Syntax**:
> +  | ``push_mpls:``\ *ethertype*
> +
> +Pushes a new outermost MPLS label stack entry (LSE) onto the packet and
> +changes the packet's Ethertype to *ethertype*, which must be either ``B0x8847``
> +or ``0x8848``.  If the packet did not already contain any MPLS labels,
> +initializes the new LSE as:
> +
> +  Label
> +    2, if the packet contains IPv6, 0 otherwise.
> +
> +  TC
> +    The low 3 bits of the packet's DSCP value, or 0 if the packet is not IP.
> +
> +  TTL
> +    Copied from the IP TTL, or 64 if the packet is not IP.
> +
> +If the packet did already contain an MPLS label, initializes the new
> +outermost label as a copy of the existing outermost label.
> +
> +OVS currently supports at most 3 MPLS labels.
> +
> +This action applies only to Ethernet packets.
> +
> +**Conformance**
> +  Open vSwitch 1.11 introduced support for MPLS.  OpenFlow 1.1 and later
> +  support ``push_mpls``.  Open vSwitch implements ``push_mpls`` as an extension
> +  to OpenFlow 1.0.
> +
> +
> +The ``pop_mpls`` action
> +-----------------------
> +..
> +  name: POP_MPLS
> +
> +**Syntax**:
> +  | ``pop_mpls:``\ *ethertype*
> +
> +Strips the outermost MPLS label stack entry and changes the packet's Ethertype
> +to *ethertype*.  This action applies only to Ethernet packets with at least one
> +MPLS label.  If there is more than one MPLS label, then *ethertype* should be
> +an MPLS Ethertype (``B0x8847`` or ``0x8848``).
> +
> +**Conformance**
> +  Open vSwitch 1.11 introduced support for MPLS.  OpenFlow 1.1 and later
> +  support ``pop_mpls``.  Open vSwitch implements ``pop_mpls`` as an extension
> +  to OpenFlow 1.0.
> +
> +
> +The ``encap`` action
> +--------------------
> +..
> +  name: ENCAP
> +
> +**Syntax**:
> +  | ``encap(nsh([md_type=``\ *md_type*\
> +                 ``], [tlv(``\ *class*,\ *type*,\ *value*\ ``)]...))``
> +  | ``encap(ethernet)``
> +
> +The ``encap`` action encapsulates a packet with a specified header.  It has
> +variants for different kinds of encapsulation.
> +
> +The ``encap(nsh(...))`` variant encapsulates an Ethernet frame with NSH.  The
> +*md_type* may be ``1`` or ``2`` for metadata type 1 or 2, defaulting to 1.
> +For metadata type 2, TLVs may be specified with *class* as a 16-bit
> +hexadecimal integer beginning with ``0x``, *type* as an 8-bit decimal
> +integer, and *value* a sequence of pairs of hex digits beginning with ``0x``.
> +For example:
> +
> +  ``encap(nsh(md_type=1))``
> +    Encapsulates the packet with an NSH header with metadata type 1.
> +
> +  ``encap(nsh(md_type=2,tlv(0x1000,10,0x12345678)))``
> +    Encapsulates the packet with an NSH header, NSH metadata type 2, and an
> +    NSH TLV with class 0x1000, type 10, and the 4-byte value 0x12345678.
> +
> +The ``encap(ethernet)`` variant encapsulate a bare L3 packet in an Ethernet
> +frame.  The Ethernet type is initialized to the L3 packet's type, e.g. 0x0800
> +if the L3 packet is IPv4.  The Ethernet source and destination are initially
> +zeroed.
> +
> +**Conformance**
> +  This action is an Open vSwitch extension to OpenFlow 1.3 and later,
> +  introduced in Open vSwitch 2.8.
> +
> +
> +The ``decap`` action
> +--------------------
> +..
> +  name: DECAP
> +
> +**Syntax**:
> +  | ``decap``
> +
> +Removes an outermost encapsulation from the packet:
> +
> +  - If the packet is an Ethernet packet, removes the Ethernet header, which
> +    changes the packet into a bare L3 packet.  If the packet has VLAN tags,
> +    raises an unsupported packet type error (see `Error Handling`_, above).
> +
> +  - Otherwise, if the packet is an NSH packet, removes the NSH header,
> +    revealing the inner packet.  Open vSwitch supports Ethernet, IPv4, IPv6,
> +    and NSH inner packet types.  Other types raise unsupported packet type
> +    errors.
> +
> +  - Otherwise, raises an unsupported packet type error.
> +
> +**Conformance**
> +  This action is an Open vSwitch extension to OpenFlow 1.3 and later,
> +  introduced in Open vSwitch 2.8.
> +
> +
> +Field Modification Actions
> +==========================
> +
> +These actions modify packet data and metadata fields.
> +
> +The ``set_field`` and ``load`` actions
> +--------------------------------------
> +..
> +  name: SET_FIELD
> +
> +**Syntax**:
> +  | ``set_field:``\ *value*\ ``[/``\ *mask*\ ``]->``\ *dst*
> +  | ``load:``\ *value*\ ``->``\ *dst*
> +
> +These actions loads a literal value into a field or part of a field.  The
> +``set_field`` action takes *value* in the customary syntax for field *dst*,
> +e.g. ``00:11:22:33:44:55`` for an Ethernet address, and *dst* as the field's
> +name.  The optional *mask* allows part of a field to be set.
> +
> +The ``load`` action takes *value* as an integer value (in decimal or prefixed
> +by ``0x`` for hexadecimal) and *dst* as a field or subfield in the syntax
> +described under `Field Specifications`_ above.
> +
> +The following all set the Ethernet source address to 00:11:22:33:44:55:
> +
> +  - ``set_field:00:11:22:33:44:55->eth_src``
> +  - ``load:0x001122334455->eth_src``
> +  - ``load:0x001122334455->OXM_OF_ETH_SRC[]``
> +
> +The following all set the multicast bit in the Ethernet destination address:
> +
> +  - ``set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst``
> +  - ``load:1->eth_dst[40]``
> +
> +Open vSwitch prohibits a ``set_field`` or ``load`` action whose *dst* is not
> +guaranteed to be part of the packet; for example, ``set_field`` of ``nw_dst``
> +is only allowed in a flow that matches on Ethernet type 0x800.  In some cases,
> +such as in an action set, Open vSwitch can't statically check that *dst* is
> +part of the packet, and in that case if it is not then Open vSwitch treats the
> +action as a no-op.
> +
> +**Conformance**
> +  Open vSwitch 1.1 introduced ``NXAST_REG_LOAD`` as a extension to OpenFlow 1.0
> +  and used ``load`` to express it.  Later, OpenFlow 1.2 introduced a standard
> +  ``OFPAT_SET_FIELD`` action that was restricted to loading entire fields, so
> +  Open vSwitch added the form ``set_field`` with this restriction.  OpenFlow
> +  1.5 extended ``OFPAT_SET_FIELD`` to the point that it became a superset of
> +  ``NXAST_REG_LOAD``.  Open vSwitch translates either syntax as necessary for
> +  the OpenFlow version in use: in OpenFlow 1.0 and 1.1, ``NXAST_REG_LOAD``; in
> +  OpenFlow 1.2, 1.3, and 1.4, ``NXAST_REG_LOAD`` for ``load`` or for loading a
> +  subfield, ``OFPAT_SET_FIELD`` otherwise; and OpenFlow 1.5 and later,
> +  ``OFPAT_SET_FIELD``.
> +
> +
> +The ``move`` action
> +-------------------
> +..
> +  name: REG_MOVE
> +
> +**Syntax**:
> +  | ``move:``\ *src*\ ``->``\ *dst*
> +
> +Copies the named bits from field or subfield *src* to field or subfield *dst*.
> +*src* and *dst* should fields or subfields in the syntax described under
> +`Field Specifications`_ above.  The two fields or subfields must have the same
> +width.
> +
> +Examples:
> +
> +  - ``move:reg0[0..5]->reg1[26..31]`` copies the six bits numbered 0 through 5
> +    in register 0 into bits 26 through 31 of register 1.
> +  - ``move:reg0[0..15]->vlan_tci`` copies the least significant 16 bits of
> +    register 0 into the VLAN TCI field.
> +
> +**Conformance**
> +  In OpenFlow 1.0 through 1.4, ``move`` ordinarily uses an Open vSwitch
> +  extension to OpenFlow.  In OpenFlow 1.5, ``move`` uses the OpenFlow 1.5
> +  standard ``OFPAT_COPY_FIELD`` action.  The ONF has also made
> +  ``OFPAT_COPY_FIELD`` available as an extension to OpenFlow 1.3.  Open vSwitch
> +  2.4 and later understands this extension and uses it if a controller uses it,
> +  but for backward compatibility with older versions of Open vSwitch,
> +  ``ovs-ofctl`` does not use it.
> +
> +
> +The ``mod_dl_src`` and ``mod_dl_dst`` actions
> +---------------------------------------------
> +..
> +  name: SET_ETH_SRC, SET_ETH_DST
> +
> +**Syntax**:
> +  | ``mod_dl_src:``\ *mac*
> +  | ``mod_dl_dst:``\ *mac*
> +
> +Sets the Ethernet source or destination address, respectively, to *mac*,
> +which should be expressed in the form ``xx:xx:xx:xx:xx:xx``.
> +
> +For L3-only packets, that is, those that lack an Ethernet header, this action
> +has no effect.
> +
> +**Conformance**
> +  OpenFlow 1.0 and 1.1 have specialized actions for these purposes.  OpenFlow
> +  1.2 and later do not, so Open vSwitch translates them to appropriate
> +  ``OFPAT_SET_FIELD`` actions for those versions,
> +
> +
> +The ``mod_nw_src`` and ``mod_nw_dst`` actions
> +---------------------------------------------
> +..
> +  name: SET_IP_SRC, SET_IP_DST
> +
> +**Syntax**:
> +  | ``mod_nw_src:``\ *ip*
> +  | ``mod_nw_dst:``\ *ip*
> +
> +Sets the IPv4 source or destination address, respectively, to *ip*, which
> +should be expressed in the form ``w.x.y.z``.
> +
> +In OpenFlow 1.1 and later, consistency rules allow these actions only in a flow
> +that matches only packets that contain an IPv4 header (or following an action
> +that adds an IPv4 header, e.g. ``pop_mpls:0x0800``).  See `Inconsistencies`_,
> +above, for more information.
> +
> +**Conformance**
> +  OpenFlow 1.0 and 1.1 have specialized actions for these purposes.  OpenFlow
> +  1.2 and later do not, so Open vSwitch translates them to appropriate
> +  ``OFPAT_SET_FIELD`` actions for those versions,
> +
> +
> +The ``mod_nw_tos`` and ``mod_nw_ecn`` actions
> +---------------------------------------------
> +..
> +  name: SET_IP_DSCP, SET_IP_ECN
> +
> +**Syntax**:
> +  | ``mod_nw_tos:``\ *tos*
> +  | ``mod_nw_ecn:``\ *ecn*
> +
> +The ``mod_nw_tos`` action sets the DSCP bits in the IPv4 ToS/DSCP or IPv6
> +traffic class field to *tos*, which must be a multiple of 4 between 0 and
> +255.  This action does not modify the two least significant bits of the ToS
> +field (the ECN bits).
> +
> +The ``mod_nw_ecn`` action sets the ECN bits in the IPv4 ToS or IPv6 traffic
> +class field to *ecn*, which must be a value between 0 and 3, inclusive.  This
> +action does not modify the six most significant bits of the field (the DSCP
> +bits).
> +
> +In OpenFlow 1.1 and later, consistency rules allow these actions only in a flow
> +that matches only packets that contain an IPv4 or IPv6 header (or following an
> +action that adds such a header).  See `Inconsistencies`_, above, for more
> +information.
> +
> +**Conformance**
> +  OpenFlow 1.0 has a ``mod_nw_tos`` action but not ``mod_nw_ecn``.
> +  Open vSwitch implements the latter in OpenFlow 1.0 as an extension using
> +  ``NXAST_REG_LOAD``.  OpenFlow 1.1 has specialized actions for these purposes.
> +  OpenFlow 1.2 and later do not, so Open vSwitch translates them to appropriate
> +  ``OFPAT_SET_FIELD`` actions for those versions.
> +
> +
> +The ``mod_tp_src`` and ``mod_tp_dst`` actions
> +---------------------------------------------
> +..
> +  name: SET_L4_SRC_PORT, SET_L4_DST_PORT
> +
> +**Syntax**:
> +  | ``mod_tp_src:``\ *port*
> +  | ``mod_tp_dst:``\ *port*
> +
> +Sets the TCP or UDP or SCTP source or destination port, respectively, to
> +*port*.  Both IPv4 and IPv6 are supported.
> +
> +In OpenFlow 1.1 and later, consistency rules allow these actions only in a flow
> +that matches only packets that contain a TCP or UDP or SCTP header.  See
> +`Inconsistencies`_, above, for more information.
> +
> +**Conformance**
> +  OpenFlow 1.0 and 1.1 have specialized actions for these purposes.  OpenFlow
> +  1.2 and later do not, so Open vSwitch translates them to appropriate
> +  ``OFPAT_SET_FIELD`` actions for those versions,
> +
> +
> +The ``dec_ttl`` action
> +----------------------
> +..
> +  name : DEC_TTL
> +
> +**Syntax**:
> +  | ``dec_ttl``
> +  | ``dec_ttl(``\ *id1*\ ``[,``\ *id2*\ ``[, ...]])``
> +
> +Decrement TTL of IPv4 packet or hop limit of IPv6 packet.  If the TTL or hop
> +limit is initially 0 or 1, no decrement occurs, as packets reaching TTL zero
> +must be rejected.  Instead, Open vSwitch sends a ``packet-in`` message with
> +reason code ``OFPR_INVALID_TTL`` to each connected controller that has enabled
> +receiving such messages, and stops processing the current set of actions.
> +(However, if the current set of actions was reached through ``resubmit``, the
> +remaining actions in outer levels resume processing.)
> +
> +As an Open vSwitch extension to OpenFlow, this action supports the ability to
> +specify a list of controller IDs.  Open vSwitch will only send the message to
> +controllers with the given ID or IDs.  Specifying no list is equivalent to
> +specifying a single controller ID of zero.
> +
> +In OpenFlow 1.1 and later, consistency rules allow these actions only in a flow
> +that matches only packets that contain an IPv4 or IPv6 header.  See
> +`Inconsistencies`_, above, for more information.
> +
> +**Conformance**
> +  All versions of OpenFlow and Open vSwitch support this action.
> +
> +
> +The ``set_mpls_label``, ``set_mpls_tc``, and ``set_mpls_ttl`` actions
> +---------------------------------------------------------------------
> +..
> +  name: SET_MPLS_LABEL, SET_MPLS_TC, SET_MPLS_TTL
> +
> +**Syntax**:
> +  | ``set_mpls_label:``\ *label*
> +  | ``set_mpls_tc:``\ *tc*
> +  | ``set_mpls_ttl:``\ *ttl*
> +
> +The ``set_mpls_label`` action sets the label of the packet's outer MPLS label
> +stack entry.  *label* should be a 20-bit value that is decimal by default;
> +use a ``0x`` prefix to specify the value in hexadecimal.
> +
> +The ``set_mpls_tc`` action sets the traffic class of the packet's outer MPLS
> +label stack entry.  *tc* should be in the range 0 to 7, inclusive.
> +
> +The ``set_mpls_ttl`` action sets the TTL of the packet's outer MPLS label stack
> +entry.  *ttl* should be in the range 0 to 255 inclusive.  In OpenFlow 1.1 and
> +later, consistency rules allow these actions only in a flow that matches only
> +packets that contain an MPLS label (or following an action that adds an MPLS
> +label, e.g. ``push_mpls:0x8847``).  See `Inconsistencies`_, above, for more
> +information.
> +
> +**Conformance**
> +  OpenFlow 1.0 does not support MPLS, but Open vSwitch implements these actions
> +  as extensions.  OpenFlow 1.1 has specialized actions for these purposes.
> +  OpenFlow 1.2 and later do not, so Open vSwitch translates them to appropriate
> +  ``OFPAT_SET_FIELD`` actions for those versions,
> +
> +
> +The ``dec_mpls_ttl`` and ``dec_nsh_ttl`` actions
> +------------------------------------------------
> +..
> +  name: DEC_MPLS_TTL, DEC_NSH_TTL
> +
> +**Syntax**:
> +  | ``dec_mpls_ttl``
> +  | ``dec_nsh_ttl``
> +
> +These actions decrement the TTL of the packet's outer MPLS label stack entry or
> +its NSH header, respectively.  If the TTL is initially 0 or 1, no decrement
> +occurs.  Instead, Open vSwitch sends a ``packet-in`` message with reason code
> +``BOFPR_INVALID_TTL`` to OpenFlow controllers with ID 0, if it has enabled
> +receiving them.  Processing the current set of actions then stops.  (However,
> +if the current set of actions was reached through ``resubmit``, remaining
> +actions in outer levels resume processing.)
> +
> +In OpenFlow 1.1 and later, consistency rules allow this actions only in a flow
> +that matches only packets that contain an MPLS label or an NSH header,
> +respectively.  See `Inconsistencies`_, above, for more information.
> +
> +**Conformance**
> +  Open vSwitch 1.11 introduced support for MPLS.  OpenFlow 1.1 and later
> +  support ``dec_mpls_ttl``.  Open vSwitch implements ``dec_mpls_ttl`` as an
> +  extension to OpenFlow 1.0.
> +
> +  Open vSwitch 2.8 introduced support for NSH, although the NSH draft changed
> +  after release so that only Open vSwitch 2.9 and later conform to the final
> +  protocol specification.  The ``dec_nsh_ttl`` action and NSH support in
> +  general is an Open vSwitch extension not supported by any version of
> +  OpenFlow.
> +
> +
> +The ``check_pkt_larger`` action
> +-------------------------------
> +..
> +  name: CHECK_PKT_LARGER
> +
> +**Syntax**:
> +  | ``check_pkt_larger(``\ *pkt_len*\ ``)->``\ *dst*
> +
> +Checks if the packet is larger than the specified length in *pkt_len*.  If
> +so, stores 1 in *dst*, which should be a 1-bit field; if not, stores 0.
> +
> +The packet length to check against the argument *pkt_len* includes the L2
> +header and L2 payload of the packet, but not the VLAN tag (if present).
> +
> +Examples:
> +
> +  - ``check_pkt_larger(1500)->reg0[0]``
> +  - ``check_pkt_larger(8000)->reg9[10]``
> +
> +This action was added in Open vSwitch 2.12.
> +
> +
> +The ``delete_field`` action
> +---------------------------
> +..
> +  name: DELETE_FIELD
> +
> +**Syntax**:
> +  | ``delete_field:``\ *field*
> +
> +The ``delete_field`` action deletes a *field* in the syntax described under
> +`Field Specifications`_ above.  Currently, only the ``tun_metadta`` fields are
> +supported.
> +
> +This action was added in Open vSwitch 2.14.
> +
> +
> +Metadata Actions
> +================
> +
> +The ``set_tunnel`` action
> +-------------------------
> +..
> +  name: SET_TUNNEL
> +
> +**Syntax**:
> +  | ``set_tunnel:``\ *id*
> +  | ``set_tunnel64:``\ *id*
> +
> +Many kinds of tunnels support a tunnel ID, e.g. VXLAN and Geneve have a 24-bit
> +VNI, and GRE has an optional 32-bit key.  This action sets the value used for
> +tunnel ID in such tunneled packets, although whether it is used for a
> +particular tunnel depends on the tunnel's configuration.  See the tunnel ID
> +documentation in ``ovs-fields(7)`` for more information.
> +
> +**Conformance**
> +  These actions are OpenFlow extensions.  ``set_tunnel`` was introduced in
> +  Open vSwitch 1.0.  ``set_tunnel64``, which is needed if *id* is wider than
> +  32 bits, was added in Open vSwitch 1.1.  Both actions always set the entire
> +  tunnel ID field.  Open vSwitch supports these actions in all versions of
> +  OpenFlow, but in OpenFlow 1.2 and later it translates them to an appropriate
> +  standardized ``OFPAT_SET_FIELD`` action.
> +
> +
> +The ``set_queue`` and ``pop_queue`` actions
> +-------------------------------------------
> +..
> +  name: SET_QUEUE, POP_QUEUE
> +
> +**Syntax**:
> +  | ``set_queue:``\ *queue*
> +  | ``pop_queue``
> +
> +The ``set_queue`` action sets the queue ID to be used for subsequent output
> +actions to *queue*, which must be a 32-bit integer.  The range of meaningful
> +values of *queue*, and their meanings, varies greatly from one OpenFlow
> +implementation to another.  Even within a single implementation, there is no
> +guarantee that all OpenFlow ports have the same queues configured or that all
> +OpenFlow ports in an implementation can be configured the same way queue-wise.
> +For more information, see the documentation for the output queue field
> +in ``ovs-fields(7)``.
> +
> +The ``pop_queue`` restores the output queue to the default that was set when
> +the packet entered the switch (generally 0).
> +
> +Four billion queues ought to be enough for anyone:
> +https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmailman.stanford.edu%2Fpipermail%2Fopenflow-spec%2F2009-August%2F000394.html&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=RtS68qasfM2nzT6pKBXaEbIycuE%2B9%2B6mUOp4c8IuJ94%3D&reserved=0
> +
> +**Conformance**
> +  OpenFlow 1.1 introduced the ``set_queue`` action.  Open vSwitch also supports
> +  it as an extension in OpenFlow 1.0.
> +
> +  The ``pop_queue`` action is an Open vSwitch extension.
> +
> +
> +Firewalling Actions
> +===================
> +
> +Open vSwitch is often used to implement a firewall.  The preferred way to
> +implement a firewall is ``connection tracking,`` that is, to keep track of the
> +connection state of individual TCP sessions.  The ``ct`` action described in
> +this section, added in Open vSwitch 2.5, implements connection tracking.  For
> +new deployments, it is the recommended way to implement firewalling with
> +Open vSwitch.
> +
> +Before ``ct`` was added, Open vSwitch did not have built-in support for
> +connection tracking.  Instead, Open vSwitch supported the ``learn`` action,
> +which allows a received packet to add a flow to an OpenFlow flow table.  This
> +could be used to implement a primitive form of connection tracking: packets
> +passing through the firewall in one direction could create flows that allowed
> +response packets back through the firewall in the other direction.  The
> +additional ``fin_timeout`` action allowed the learned flows to expire quickly
> +after TCP session termination.
> +
> +The ``ct`` action
> +-----------------
> +..
> +  name: CT
> +
> +**Syntax**:
> +  | ``ct([``\ *argument*\ ``]...)``
> +  | ``ct(commit[,``\ *argument*\ ``]...)``
> +
> +The action has two modes of operation, distinguished by whether ``commit`` is
> +present.  The following arguments may be present in either mode:
> +
> +  ``zone=``\ *value*
> +    A zone is a 16-bit id that isolates connections into separate domains,
> +    allowing overlapping network addresses in different zones.  If a zone is
> +    not provided, then the default is 0. The *value* may be specified either
> +    as a 16-bit integer literal or a field or subfield in the syntax described
> +    under `Field Specifications`_ above.
> +
> +Without ``commit``, this action sends the packet through the connection
> +tracker.  The connection tracker keeps track of the state of TCP connections
> +for packets passed through it.  For each packet through a connection, it checks
> +that it satisfies TCP invariants and signals the connection state to later
> +actions using the ``ct_state`` metadata field, which is documented in
> +``ovs-fields(7)``.
> +
> +In this form, ``ct`` forks the OpenFlow pipeline:
> +
> +  - In one fork, ``ct`` passes the packet to the connection tracker.
> +    Afterward, it reinjects the packet into the OpenFlow pipeline with the
> +    connection tracking fields initialized.  The ``ct_state`` field is
> +    initialized with connection state and ``ct_zone`` to the connection
> +    tracking zone specified on the ``zone`` argument.  If the connection is one
> +    that is already tracked, ``ct_mark`` and ``ct_label`` to its existing mark
> +    and label, respectively; otherwise they are zeroed.  In addition,
> +    ``ct_nw_proto``, ``ct_nw_src``, ``ct_nw_dst``, ``ct_ipv6_src``,
> +    ``ct_ipv6_dst``, ``ct_tp_src``, and ``ct_tp_dst`` are initialized
> +    appropriately for the original direction connection.  See the ``resubmit``
> +    action for a way to search the flow table with the connection tracking
> +    original direction fields swapped with the packet 5-tuple fields.  See
> +    ``ovs-fields(7)`` for details on the connection tracking fields.
> +
> +  - In the other fork, the original instance of the packet continues
> +    independent processing following the ``ct`` action.  The ``ct_state`` field
> +    and other connection tracking metadata are cleared.
> +
> +Without ``commit``, the ``ct`` action accepts the
> +following arguments:
> +
> +  ``table=``\ *table*
> +    Sets the OpenFlow table where the packet is reinjected.  The *table* must
> +    be a number between 0 and 254 inclusive, or a table's name.  If *table* is
> +    not specified, then the packet is not reinjected.
> +
> +  ``nat``
> +
> +  ``nat(``\ *type*\ ``=``\ *addrs*\ ``[:``\ *ports*\ ``][,``\ *flag*\ ``]...)``
> +    Specify address and port translation for the connection being  tracked.
> +    The *type* must be ``src``, for source address/port translation (SNAT), or
> +    ``dst``, for destination address/port translation (DNAT).  Setting up
> +    address translation for a new connection takes effect only if the
> +    connection is later committed with ``ct(commit ...)``.
> +
> +    The ``src`` and ``dst`` options take the following arguments:
> +
> +      *addrs*
> +        The IP address ``addr`` or range ``addr1-addr2`` from which the
> +        translated address should be selected.  If only one address is given,
> +        then that address will always be selected, otherwise the address
> +        selection can be informed by the optional persistent flag as described
> +        below.  Either IPv4 or IPv6 addresses can be provided, but both
> +        addresses must be of the same type, and the datapath behavior is
> +        undefined in case of providing IPv4 address range for an IPv6 packet,
> +        or IPv6 address range for an IPv4 packet.  IPv6 addresses must be
> +        bracketed with ``[`` and ``]`` if a port range is also given.
> +
> +      *ports*
> +        The L4 ``port`` or range ``port1-port2`` from which the translated port
> +        should be selected. When a port range is specified, fallback to
> +        ephemeral ports does not happen, else, it will.  The port number
> +        selection can be informed by the optional ``random`` and ``hash`` flags
> +        described below.  The userspace datapath only supports the ``hash``
> +        behavior.
> +
> +    The optional *flags* are:
> +
> +      ``random``
> +        The selection of the port from the given range should be done using a
> +        fresh random number.  This flag is mutually exclusive with ``hash``.
> +
> +      ``hash``
> +        The selection of the port from the given range should be done using a
> +        datapath specific hash of the packet's IP addresses and the other,
> +        non-mapped port number.  This flag is mutually exclusive with
> +        ``random``.
> +
> +      ``persistent``
> +        The selection of the IP address from the given range should be done so
> +        that the same mapping can be provided after the system restarts.
> +
> +    If ``alg`` is specified for the committing ``ct`` action that also includes
> +    ``nat`` with a ``src`` or ``dst`` attribute, then the datapath tries to set
> +    up the helper to be NAT-aware.  This functionality is datapath specific and
> +    may not be supported by all datapaths.
> +
> +    A ``bare`` ``nat`` argument with no options will only translate the packet
> +    being processed in the way the connection has been set up with an earlier,
> +    committed ``ct`` action.  A ``nat`` action with ``src`` or ``dst``, when
> +    applied to a packet belonging to an established (rather than new)
> +    connection, will behave the same as a bare ``nat``.
> +
> +    For SNAT, there is a special case when the ``src`` IP address is configured
> +    as all 0's, i.e., ``nat(src=0.0.0.0)``. In this case, when a source port
> +    collision is detected during the commit, the source port will be translated
> +    to an ephemeral port. If there is no collision, no SNAT is performed.
> +
> +    Open vSwitch 2.6 introduced ``nat``.  Linux 4.6 was the earliest upstream
> +    kernel that implemented ``ct`` support for ``nat``.
> +
> +With ``commit``, the connection tracker commits the connection to the
> +connection tracking module.  The ``commit`` flag should only be used from the
> +pipeline within the first fork of ``ct`` without ``commit``.  Information about
> +the connection is stored beyond the lifetime of the packet in the pipeline.
> +Some ``ct_state`` flags are only available for committed connections.
> +
> +The following options are available only with ``commit``:
> +
> +  ``force``
> +    A committed connection always has the directionality of the packet that
> +    caused the connection to be committed in the first place.  This is the
> +    ``original direction`` of the connection, and the opposite direction is the
> +    ``reply direction``.  If a connection is already committed, but it is in
> +    the wrong direction, ``force`` effectively terminates the existing
> +    connection and starts a new one in the current direction.  This flag has no
> +    effect if the original direction of the connection is already the same as
> +    that of the current packet.
> +
> +  ``exec(``\ *action*\ ``...)``
> +    Perform each *action* within the context of connection tracking.  Only
> +    actions which modify the ``ct_mark`` or ``ct_label`` fields are accepted
> +    within ``exec`` action, and these fields may only be modified with this
> +    option. For example:
> +
> +    ``set_field:``\ *value*\ ``[/``\ *mask*\ ``]->ct_mark``
> +      Store a 32-bit metadata value with the connection.  Subsequent lookups
> +      for packets in this connection will populate ``ct_mark`` when the packet
> +      is sent to the connection tracker with the table specified.
> +
> +    ``set_field:``\ *value*\ ``[/``\ *mask*\ ``]->ct_label``
> +      Store a 128-bit metadata value with the connection.  Subsequent lookups
> +      for packets in this connection will populate ``ct_label`` when the packet
> +      is sent to the connection tracker with the table specified.
> +
> +  ``alg=``\ *alg*
> +    Specify application layer gateway *alg* to track specific connection types.
> +    If subsequent related connections are sent through the ``ct`` action, then
> +    the ``rel`` flag in the ``ct_state`` field will be set.  Supported types
> +    include:
> +
> +    ``ftp``
> +      Look for negotiation of FTP data connections.  Specify this option for
> +      FTP control connections to detect related data connections and populate
> +      the ``rel`` flag for the data connections.
> +
> +    ``tftp``
> +      Look for negotiation of TFTP data connections.  Specify this option for
> +      TFTP control connections to detect related data connections and populate
> +      the ``rel`` flag for the data connections.
> +
> +    Related connections inherit ``ct_mark`` from that stored with the original
> +    connection (i.e. the connection created by ``ct(alg=...)``.
> +
> +With the Linux datapath, global sysctl options affect ``ct`` behavior.  In
> +particular, if ``net.netfilter.nf_conntrack_helper`` is enabled, which it is
> +by default until Linux 4.7, then application layer gateway helpers may be
> +executed even if *alg* is not specified.  For security reasons, the netfilter
> +team recommends users disable this option.  For further details, please see
> +https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.netfilter.org%2Fnews.html%232012-04-03&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=K9NgT9oWdJeokJl4vGtko6d7ZIUwtph9UP44jSyQ%2Fss%3D&reserved=0 .
> +
> +The ``ct`` action may be used as a primitive to construct stateful firewalls by
> +selectively committing some traffic, then matching ``ct_state`` to allow
> +established connections while denying new connections.  The following flows
> +provide an example of how to implement a simple firewall that allows new
> +connections from port 1 to port 2, and only allows established connections to
> +send traffic from port 2 to port 1::
> +
> +  table=0,priority=1,action=drop
> +  table=0,priority=10,arp,action=normal
> +  table=0,priority=100,ip,ct_state=-trk,action=ct(table=1)
> +  table=1,in_port=1,ip,ct_state=+trk+new,action=ct(commit),2
> +  table=1,in_port=1,ip,ct_state=+trk+est,action=2
> +  table=1,in_port=2,ip,ct_state=+trk+new,action=drop
> +  table=1,in_port=2,ip,ct_state=+trk+est,action=1
> +
> +If ``ct`` is executed on IPv4 (or IPv6) fragments, then the message is
> +implicitly reassembled before sending to the connection tracker and
> +refragmented upon output, to the original maximum received fragment size.
> +Reassembly occurs within the context of the zone, meaning that IP fragments in
> +different zones are not assembled together.  Pipeline processing for the
> +initial fragments is halted.  When the final fragment is received, the message
> +is assembled and pipeline processing continues for that flow.  Packet ordering
> +is not guaranteed by IP protocols, so it is not possible to determine which IP
> +fragment will cause message reassembly (and therefore continue pipeline
> +processing). As such, it is strongly recommended that multiple flows should not
> +execute ``ct`` to reassemble fragments from the same IP message.
> +
> +**Conformance**
> +  The ``ct`` action was introduced in Open vSwitch 2.5.  Some of its features
> +  were introduced later, noted individually above.
> +
> +
> +The ``ct_clear`` action
> +-----------------------
> +..
> +  name: CT_CLEAR
> +
> +**Syntax**:
> +  | ``ct_clear``
> +
> +Clears connection tracking state from the flow, zeroing ``ct_state``,
> +``ct_zone``, ``ct_mark``, and ``ct_label``.
> +
> +This action was introduced in Open vSwitch 2.7.
> +
> +
> +The ``learn`` action
> +--------------------
> +..
> +  name: LEARN
> +
> +**Syntax**:
> +  | ``learn(``\ *argument*\ ``...)``
> +
> +The ``learn`` action adds or modifies a flow in an OpenFlow table, similar to
> +``ovs-ofctl --strict mod-flows``.  The arguments specify the match fields,
> +actions, and other properties of the flow to be added or modified.
> +
> +Match fields for the new flow are specified as follows.  At least one match
> +field should ordinarily be specified:
> +
> +  *field*\ ``=``\ *value*
> +    Specifies that *field*, in the new flow, must match the literal *value*,
> +    e.g. ``dl_type=0x800``.  Shorthand match syntax, such as ``ip`` in place of
> +    ``dl_type=0x800``, is not supported.
> +
> +  *field*\ ``=``\ *src*
> +    Specifies that *field* in the new flow must match *src* taken from the
> +    packet currently being processed.  For example, ``udp_dst=udp_src``,
> +    applied to a UDP packet with source port 53, creates a flow which matches
> +    ``udp_dst=53``.  *field* and *src* must have the same width.
> +
> +  *field*
> +    Shorthand for the previous form when *field* and *src* are the same.  For
> +    example, ``udp_dst``, applied to a UDP packet with destination port 53,
> +    creates a flow which matches ``udp_dst=53``.
> +
> +The *field* and *src* arguments above should be fields or subfields in the
> +syntax described under `Field Specifications`_ above.
> +
> +Match field specifications must honor prerequisites for both the flow with the
> +``learn`` and the new flow that it creates.  Consider the following complete
> +flow, in the syntax accepted by ``ovs-ofctl``.  If the flow's match on ``udp``
> +were omitted, then the flow would not satisfy the prerequisites for the
> +``learn`` action's use of ``udp_src``.  If ``dl_type=0x800`` or ``nw_proto``
> +were omitted from ``learn``, then the new flow would not satisfy the
> +prerequisite for its match on ``udp_dst``.  For more information on
> +prerequisites, please refer to ``ovs-fields(7)``::
> +
> +  udp, actions=learn(dl_type=0x800, nw_proto=17, udp_dst=udp_src)
> +
> +Actions for the new flow are specified as follows.  At least one action should
> +ordinarily be specified:
> +
> +  ``load:``\ *value*\ ``->``\ *dst*
> +    Adds a ``load`` action to the new flow that loads the literal *value* into
> +    *dst*.  The syntax is the same as the ``load`` action explained in the
> +    `Field Modification Actions`_ section.
> +
> +  ``load:``\ *src*\ ``->``\ *dst*
> +    Adds a ``load`` action to the new flow that loads *src*, a field or
> +    subfield from the packet being processed, into *dst*.
> +
> +  ``output:``\ *field*
> +    Adds an ``output`` action to the new flow's actions that outputs to the
> +    OpenFlow port taken from *field*, which must be a field as described above.
> +
> +  ``fin_idle_timeout=``\ *seconds*  /  ``fin_hard_timeout=``\ *seconds*
> +    Adds a ``fin_timeout`` action with the specified arguments to the new flow.
> +    This feature was added in Open vSwitch 1.6.
> +
> +The following additional arguments are optional:
> +
> +  ``idle_timeout=``\ *seconds*
> +
> +  ``hard_timeout=``\ *seconds*
> +
> +  ``priority=``\ *value*
> +
> +  ``cookie=``\ *value*
> +
> +  ``send_flow_rem``
> +    These arguments have the same meaning as in the usual flow syntax
> +    documented in ``ovs-ofctl(8)``.
> +
> +  ``table=``\ *table*
> +    The table in which the new flow should be inserted.  Specify a decimal
> +    number between 0 and 254 inclusive or the name of a table.  The default, if
> +    table is unspecified, is table 1 (not 0).
> +
> +  ``delete_learned``
> +    When this flag is specified, deleting the flow that contains the ``learn``
> +    action will also delete the flows created by ``learn``.  Specifically, when
> +    the last ``learn`` action with this flag and particular ``table`` and
> +    ``cookie`` values is removed, the switch deletes all of the flows in the
> +    specified table with the specified cookie.
> +
> +    This flag was added in Open vSwitch 2.4.
> +
> +  ``limit=``\ *number*
> +    If the number of flows in the new flow's table with the same cookie exceeds
> +    *number*, the action will not add a new flow.  By default, or with
> +    ``limit=0``, there is no limit.
> +
> +    This flag was added in Open vSwitch 2.8.
> +
> +  ``result_dst=``\ *field*\ ``[``\ *bit*\ ``]``
> +    If learn fails (because the number of flows exceeds ``limit``), the action
> +    sets *field*\ [*bit*] to 0, otherwise it will be set to 1.
> +    *field*\ [*bit*] must be a single bit.
> +
> +    This flag was added in Open vSwitch 2.8.
> +
> +By itself, the ``learn`` action can only put two kinds of actions into the
> +flows that it creates: ``load`` and ``output`` actions.  If ``learn`` is used
> +in isolation, these are severe limits.
> +
> +However, ``learn`` is not meant to be used in isolation.  It is a primitive
> +meant to be used together with other Open vSwitch features to accomplish a
> +task.  Its existing features are enough to accomplish most tasks.
> +
> +Here is an outline of a typical pipeline structure that allows for versatile
> +behavior using ``learn``:
> +
> +  - Flows in table ``A`` contain a ``learn`` action, that populates flows in
> +    table ``L``, that use a ``load`` action to populate register ``R`` with
> +    information about what was learned.
> +
> +  - Flows in table ``B`` contain two sequential resubmit actions: one to table
> +    ``L`` and another one to table ``B + 1``.
> +
> +  - Flows in table ``B + 1`` match on register ``R`` and act differently
> +    depending on what the flows in table ``L`` loaded into it.
> +
> +This approach can be used to implement many ``learn``-based features.  For
> +example:
> +
> +  - Resubmit to a table selected based on learned information, e.g. see
> +    https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.openvswitch.org%2Fpipermail%2Fovs-discuss%2F2016-June%2F021694.html&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=zfD%2FWlKmTPqOS0OhZMIqo%2FTgvpiT95%2B17XODh65KyHM%3D&reserved=0 .
> +
> +  - MAC learning in the middle of a pipeline, as described in the
> +    ``Open vSwitch Advanced Features Tutorial`` in the OVS documentation.
> +
> +  - TCP state based firewalling, by learning outgoing connections based on SYN
> +    packets and matching them up with incoming packets.  (This is usually
> +    better implemented using the ``ct`` action.)
> +
> +  - At least some of the features described in T. A. Hoff, ``Extending
> +    Open vSwitch to Facilitate Creation of Stateful SDN Applications``.
> +
> +**Conformance**
> +  The ``learn`` action is an Open vSwitch extension to OpenFlow added in
> +  Open vSwitch 1.3.  Some features of ``learn`` were added in later versions,
> +  as noted individually above.
> +
> +
> +The ``fin_timeout`` action
> +--------------------------
> +..
> +  name: FIN_TIMEOUT
> +
> +**Syntax**:
> +  | ``fin_timeout(``\ *key*\ ``=``\ *value*\ ``...)``
> +
> +This action changes the idle timeout or hard timeout, or both, of the OpenFlow
> +flow that contains it, when the flow matches a TCP packet with the FIN or RST
> +flag.  When such a packet is observed, the action reduces the rule's timeouts
> +to those specified on the action.  If the rule's existing timeout is already
> +shorter than the one that the action specifies, then that timeout is
> +unaffected.
> +
> +The timeouts are specified as key-value pairs:
> +
> +  ``idle_timeout=``\ *seconds*
> +    Causes the flow to expire after the given number of seconds of inactivity.
> +
> +  ``hard_timeout=``\ *seconds*
> +    Causes the flow to expire after the given number of *seconds*, regardless
> +    of activity.  (*seconds* specifies time since the flow's creation, not
> +    since the receipt of the FIN or RST.)
> +
> +This action is normally added to a learned flow by the ``learn`` action.  It is
> +unlikely to be useful otherwise.
> +
> +**Conformance**
> +  This Open vSwitch extension action was added in Open vSwitch 1.6.
> +
> +
> +Programming and Control Flow Actions
> +====================================
> +
> +The ``resubmit`` action
> +-----------------------
> +..
> +  name: RESUBMIT
> +
> +**Syntax**:
> +  | ``resubmit:``\ *port*
> +  | ``resubmit([``\ *port*\ ``],[``\ *table*\ ][,ct])``
> +
> +Searches an OpenFlow flow table for a matching flow and executes the actions
> +found, if any, before continuing to the following action in the current flow
> +entry.  Arguments can customize the search:
> +
> +  - If *port* is given as an OpenFlow port number or name, then it specifies a
> +    value to use for the input port metadata field as part of the search, in
> +    place of the input port currently in the flow.  Specifying ``in_port`` as
> +    ``port`` is equivalent to omitting it.
> +
> +  - If *table* is given as an integer between 0 and 254 or a table name, it
> +    specifies the OpenFlow table to search.  If it is not specified, the table
> +    from the current flow is used.
> +
> +  - If ``ct`` is specified, then the search is done with packet 5-tuple fields
> +    swapped with the corresponding conntrack original direction tuple fields.
> +    See the documentation for ``ct`` above, for more information about
> +    connection tracking, or ``ovs-fields(7)`` for details about the connection
> +    tracking fields.
> +
> +    This flag requires a valid connection tracking state as a match
> +    prerequisite in the flow where this action is placed.  Examples of valid
> +    connection tracking state matches include ``ct_state=+new``,
> +    ``ct_state=+est``, ``ct_state=+rel``, and ``ct_state=+trk-inv``.
> +
> +The changes, if any, to the input port and connection tracking fields are just
> +for searching the flow table.  The changes are not visible to actions or to
> +later flow table lookups.
> +
> +The most common use of ``resubmit`` is to visit another flow table without
> +*port* or ``ct``, like this: ``resubmit(,``\ *table*\ ``)``.
> +
> +Recursive ``resubmit`` actions are permitted.
> +
> +**Conformance**
> +  The ``resubmit`` action is an Open vSwitch extension.  However, the
> +  ``goto_table`` instruction in OpenFlow 1.1 and later can be viewed as a kind
> +  of restricted ``resubmit``.
> +
> +  Open vSwitch 1.3 added ``table``.  Open vSwitch 2.7 added ``ct``.
> +
> +  Open vSwitch imposes a limit on ``resubmit`` recursion that varies among
> +  version:
> +
> +    - Open vSwitch 1.0.1 and earlier did not support recursion.
> +    - Open vSwitch 1.0.2 and 1.0.3 limited recursion to 8 levels.
> +    - Open vSwitch 1.1 and 1.2 limited recursion to 16 levels.
> +    - Open vSwitch 1.2 through 1.8 limited recursion to 32 levels.
> +    - Open vSwitch 1.9 through 2.0 limited recursion to 64 levels.
> +    - Open vSwitch 2.1 through 2.5 limited recursion to 64 levels and impose a
> +      total limit of 4,096 resubmits per flow translation (earlier versions did
> +      not impose any total limit).
> +    - Open vSwitch 2.6 and later imposes the same limits as 2.5, with one
> +      exception: resubmit from table ``x`` to any table ``y > x`` does not
> +      count against the recursion depth limit.
> +
> +
> +The ``clone`` action
> +--------------------
> +..
> +  name: CLONE
> +
> +**Syntax**:
> +  | ``clone(``\ *action*\ ``...)``
> +
> +Executes each nested *action*, saving much of the packet and pipeline state
> +beforehand and then restoring it afterward.  The state that is saved and
> +restored includes all flow data and metadata (including, for example,
> +``in_port`` and ``ct_state``), the stack accessed by ``push`` and ``pop``
> +actions, and the OpenFlow action set.
> +
> +This action was added in Open vSwitch 2.7.
> +
> +
> +The ``push`` and ``pop`` actions
> +--------------------------------
> +..
> +  name: STACK_PUSH, STACK_POP
> +
> +**Syntax**:
> +  | ``push:``\ *src*
> +  | ``pop:``\ *dst*
> +
> +The ``push`` action pushes *src* on a general-purpose stack.  The ``pop``
> +action pops an entry off the stack into *dst*.  *src* and *dst* should be
> +fields or subfields in the syntax described under `Field Specifications`_
> +above.
> +
> +Controllers can use the stack for saving and restoring data or metadata around
> +``resubmit`` actions, for swapping or rearranging data and metadata, or for
> +other purposes.  Any data or metadata field, or part of one, may be pushed, and
> +any modifiable field or subfield may be popped.
> +
> +The number of bits pushed in a stack entry do not have to match the number of
> +bits later popped from that entry.  If more bits are popped from an entry than
> +were pushed, then the entry is conceptually left-padded with 0-bits as needed.
> +If fewer bits are popped than pushed, then bits are conceptually trimmed from
> +the left side of the entry.
> +
> +The stack's size is limited.  The limit is intended to be high enough that
> +``normal`` use will not pose problems.  Stack overflow or underflow is an error
> +that stops action execution (see ``Stack too deep`` under `Error Handling`_,
> +above).
> +
> +Examples:
> +
> +  - ``push:reg2[0..5]`` or ``push:NXM_NX_REG2[0..5]`` pushes on the stack the 6
> +    bits in register 2 bits 0 through 5.
> +
> +  - ``pop:reg2[0..5]`` or ``pop:NXM_NX_REG2[0..5]`` pops the value from top of
> +    the stack and copy bits 0 through 5 of that value into bits 0 through 5 of
> +    register 2.
> +
> +**Conformance**
> +  Open vSwitch 1.2 introduced ``push`` and ``pop`` as OpenFlow extension
> +  actions.
> +
> +
> +The ``exit`` action
> +-------------------
> +..
> +  name: EXIT
> +
> +**Syntax**:
> +  | ``exit``
> +
> +This action causes Open vSwitch to immediately halt execution of further
> +actions.  Actions which have already been executed are unaffected.  Any further
> +actions, including those which may be in other tables, or different levels of
> +the ``resubmit`` call stack, are ignored.  However, an ``exit`` action within a
> +group bucket terminates only execution of that bucket, not other buckets or the
> +overall pipeline.  Actions in the action set are still executed (specify
> +``clear_actions`` before ``exit`` to discard them).
> +
> +
> +The ``multipath`` action
> +------------------------
> +..
> +  name: MULTIPATH
> +
> +**Syntax**:
> +  | ``multipath(``\ *fields*,\ *basis*,\ *algorithm*,\
> +                *n_links*,\ *arg*,\ *dst*\ ``)``
> +
> +Hashes *fields* using *basis* as a universal hash parameter, then the
> +applies multipath link selection *algorithm* (with parameter *arg*) to
> +choose one of *n_links* output links numbered 0 through *n_links* minus 1,
> +and stores the link into *dst*, which must be a field or subfield in the
> +syntax described under `Field Specifications`_ above.
> +
> +The ``bundle`` or ``bundle_load`` actions are usually easier to use than
> +``multipath``.
> +
> +*fields* must be one of the following:
> +
> +  ``eth_src``
> +    Hashes Ethernet source address only.
> +
> +  ``symmetric_l4``
> +    Hashes Ethernet source, destination, and type, VLAN ID, IPv4/IPv6 source,
> +    destination, and protocol, and TCP or SCTP (but not UDP) ports.  The hash
> +    is computed so that pairs of corresponding flows in each direction hash to
> +    the same value, in environments where L2 paths are the same in each
> +    direction.  UDP ports are not included in the hash to support protocols
> +    such as VXLAN that use asymmetric ports in each direction.
> +
> +  ``symmetric_l3l4``
> +    Hashes IPv4/IPv6 source, destination, and protocol, and TCP or SCTP (but
> +    not UDP) ports.  Like ``symmetric_l4``, this is a symmetric hash, but by
> +    excluding L2 headers it is more effective in environments with asymmetric
> +    L2 paths (e.g. paths involving VRRP IP addresses on a router).  Not an
> +    effective hash function for protocols other than IPv4 and IPv6, which hash
> +    to a constant zero.
> +
> +  ``symmetric_l3l4+udp``
> +    Like ``symmetric_l3l4+udp``, but UDP ports are included in the hash.  This
> +    is a more effective hash when asymmetric UDP protocols such as VXLAN are
> +    not a consideration.
> +
> +  ``symmetric_l3``
> +    Hashes network source address and network destination address.
> +
> +  ``nw_src``
> +    Hashes network source address only.
> +
> +  ``nw_dst``
> +    Hashes network destination address only.
> +
> +The *algorithm* used to compute the final result ``link`` must be one of the
> +following:
> +
> +  ``modulo_n``
> +    Computes ``link = hash(flow) % n_links``.
> +
> +    This algorithm redistributes all traffic when ``n_links`` changes.  It has
> +    ``O(1)`` performance.
> +
> +    Use 65535 for ``max_link`` to get a raw hash value.
> +
> +    This algorithm is specified by RFC 2992.
> +
> +  ``hash_threshold``
> +    Computes ``link = hash(flow) / (MAX_HASH / n_links)``.
> +
> +    Redistributes between one-quarter and one-half of traffic when ``n_links``
> +    changes.  It has ``O(1)`` performance.
> +
> +    This algorithm is specified by RFC 2992.
> +
> +  ``hrw`` (Highest Random Weight)
> +    Computes the following::
> +
> +      for i in [0, n_links]:
> +          weights[i] = hash(flow, i)
> +      link = { i such that weights[i] >= weights[j] for all j != i }
> +
> +    Redistributes ``1 / n_links`` of traffic when ``n_links`` changes.  It has
> +    ``O(n_links)`` performance.  If ``n_links`` is greater than a threshold
> +    (currently 64, but subject to change), Open vSwitch will substitute another
> +    algorithm automatically.
> +
> +    This algorithm is specified by RFC 2992.
> +
> +  ``iter_hash`` (Iterative Hash)
> +    Computes the following::
> +
> +      i = 0
> +      repeat:
> +          i = i + 1
> +          link = hash(flow, i) % arg
> +      while link > max_link
> +
> +    Redistributes ``1 / n_links`` of traffic when ``n_links`` changes.
> +    ``O(1)`` performance when ``arg / max_link`` is bounded by a constant.
> +
> +    Redistributes all traffic when ``arg`` changes.
> +
> +    *arg* must be greater than ``max_link`` and for best performance should be
> +    no more than approximately ``max_link * 2``.  If *arg* is outside the
> +    acceptable range, Open vSwitch will automatically substitute the least
> +    power of 2 greater than ``max_link``.
> +
> +    This algorithm is specific to Open vSwitch.
> +
> +Only the ``iter_hash`` algorithm uses *arg*.
> +
> +It is an error if ``max_link`` is greater than or equal to ``2**n_bits``.
> +
> +**Conformance**
> +  This is an OpenFlow extension added in Open vSwitch 1.1.
> +
> +
> +Other Actions
> +=============
> +
> +The ``conjunction`` action
> +--------------------------
> +..
> +  name: CONJUNCTION
> +
> +**Syntax**:
> +  | ``conjunction(``\ *id*, *k*/*n*\ ``)``
> +
> +This action allows for sophisticated ``conjunctive match`` flows.  Refer to
> +``Conjunctive Match Fields`` in ``ovs-fields(7)`` for details.
> +
> +A flow that has one or more ``conjunction`` actions may not have any other
> +actions except for ``note`` actions.
> +
> +**Conformance**
> +  Open vSwitch 2.4 introduced the ``conjunction`` action and ``conj_id`` field.
> +  They are Open vSwitch extensions to OpenFlow.
> +
> +
> +The ``note`` action
> +-------------------
> +..
> +  name: NOTE
> +
> +**Syntax**:
> +  | ``note:[``\ *hh*\ ``]...``
> +
> +This action does nothing at all.  OpenFlow controllers may use it to annotate
> +flows with more data than can fit in a flow cookie.
> +
> +The action may include any number of bytes represented as hex digits *hh*.
> +Periods may separate pairs of hex digits, for readability.  The ``note``
> +action's format doesn't include an exact length for its payload, so the
> +provided bytes will be padded on the right by enough bytes with value 0 to make
> +the total number 6 more than a multiple of 8.
> +
> +**Conformance**
> +  This action is an extension to OpenFlow introduced in Open vSwitch 1.1.
> +
> +
> +The ``sample`` action
> +---------------------
> +..
> +  name: SAMPLE
> +
> +**Syntax**:
> +  | ``sample(``\ *argument*\ ``...)``
> +
> +Samples packets and sends one sample for every sampled packet.
> +
> +The following *argument* forms are accepted:
> +
> +  ``probability=``\ *packets*
> +    The number of sampled packets out of 65535.  Must be greater or equal to 1.
> +
> +  ``collector_set_id=``\ *id*
> +    The unsigned 32-bit integer identifier of the set of sample collectors to
> +    send sampled packets to.  Defaults to 0.
> +
> +  ``obs_domain_id=``\ *id*
> +    When sending samples to IPFIX collectors, the unsigned 32-bit integer
> +    Observation Domain ID sent in every IPFIX flow record.  Defaults to 0.
> +
> +  ``obs_point_id=``\ *id*
> +    When sending samples to IPFIX collectors, the unsigned 32-bit integer
> +    Observation Point ID sent in every IPFIX flow record.  Defaults to 0.
> +
> +  ``sampling_port=``\ *port*
> +    Sample packets on *port*, which should be the ingress or egress port.  This
> +    option, which was added in Open vSwitch 2.6, allows the IPFIX
> +    implementation to export egress tunnel information.
> +
> +  ``ingress``
> +
> +  ``egress``
> +    Specifies explicitly that the packet is being sampled on ingress to or
> +    egress from the switch.  IPFIX reports sent by Open vSwitch before version
> +    2.6 did not include a direction.  From 2.6 until 2.7, IPFIX reports
> +    inferred a direction from ``sampling_port``: if it was the packet's output
> +    port, then the direction was reported as egress, otherwise as ingress.
> +    Open vSwitch 2.7 introduced these options, which allow the inferred
> +    direction to be overridden.  This is particularly useful when the ingress
> +    (or egress) port is not a tunnel.
> +
> +Refer to ``ovs-vswitchd.conf.db(5)`` for more details on configuring sample
> +collector sets.
> +
> +**Conformance**
> +  This action is an OpenFlow extension added in Open vSwitch 2.4.
> +
> +
> +Instructions
> +============
> +
> +Every version of OpenFlow includes actions.  OpenFlow 1.1 introduced the
> +higher-level, related concept of ``instructions``.  In OpenFlow 1.1 and later,
> +actions within a flow are always encapsulated within an instruction.  Each flow
> +has at most one instruction of each kind, which are executed in the following
> +fixed order defined in the OpenFlow specification:
> +
> +  #. ``Meter``
> +  #. ``Apply-Actions``
> +  #. ``Clear-Actions``
> +  #. ``Write-Actions``
> +  #. ``Write-Metadata``
> +  #. ``Stat-Trigger`` (not supported by Open vSwitch)
> +  #. ``Goto-Table``
> +
> +The most important instruction is ``Apply-Actions``.  This instruction
> +encapsulates any number of actions, which the instruction executes.
> +Open vSwitch does not explicitly represent ``Apply-Actions``.  Instead, any
> +action by itself is implicitly part of an ``Apply-Actions`` instructions.
> +
> +Open vSwitch syntax requires other instructions, if present, to be in the order
> +listed above.  Otherwise it will flag an error.
> +
> +
> +The ``meter`` action and instruction
> +------------------------------------
> +..
> +  name: METER
> +
> +**Syntax**:
> +  | ``meter:``\ *meter_id*
> +
> +Apply meter *meter_id*.  If a meter band rate is exceeded, the packet may be
> +dropped, or modified, depending on the meter band type.
> +
> +**Conformance**
> +  OpenFlow 1.3 introduced the ``meter`` instruction.  OpenFlow 1.5 changes
> +  ``meter`` from an instruction to an action.
> +
> +  OpenFlow 1.5 allows implementations to restrict ``meter`` to be the first
> +  action in an action list and to exclude ``meter`` from action sets, for
> +  better compatibility with OpenFlow 1.3 and 1.4.  Open vSwitch restricts the
> +  ``meter`` action both ways.
> +
> +  Open vSwitch 2.0 introduced OpenFlow protocol support for meters, but it did
> +  not include a datapath implementation.  Open vSwitch 2.7 added meter support
> +  to the userspace datapath.  Open vSwitch 2.10 added meter support to the
> +  kernel datapath.  Open vSwitch 2.12 added support for meter as an action in
> +  OpenFlow 1.5.
> +
> +
> +The ``clear_actions`` instruction
> +---------------------------------
> +..
> +  name: CLEAR_ACTIONS
> +
> +**Syntax**:
> +  | ``clear_actions``
> +
> +Clears the action set.  See `Action Sets`_, above, for more information.
> +
> +**Conformance**
> +  OpenFlow 1.1 introduced ``clear_actions``.  Open vSwitch 2.1 added support
> +  for ``clear_actions``.
> +
> +
> +The ``write_actions`` instruction
> +---------------------------------
> +..
> +  name: WRITE_ACTIONS
> +
> +**Syntax**:
> +  | ``write_actions(``\ *action*\ ``...)``
> +
> +Adds each *action* to the action set.  The action set is carried between flow
> +tables and then executed at the end of the pipeline.  Only certain actions may
> +be written to the action set.  See `Action Sets`_, above, for more information.
> +
> +**Conformance**
> +  OpenFlow 1.1 introduced ``write_actions``.  Open vSwitch 2.1 added support
> +  for ``write_actions``.
> +
> +
> +The ``write_metadata`` instruction
> +----------------------------------
> +..
> +  name: WRITE_METADATA
> +
> +**Syntax**:
> +  | ``write_metadata:``\ *value*\ ``[/``\ *mask*\ ``]``
> +
> +Updates the flow's ``metadata`` field.  If *mask* is omitted, ``metadata`` is
> +set exactly to *value*; if *mask* is specified, then a 1-bit in *mask*
> +indicates that the corresponding bit in ``metadata`` will be replaced with the
> +corresponding bit from *value*.  Both *value* and *mask* are 64-bit
> +values that are decimal by default; use a ``0x`` prefix to specify them in
> +hexadecimal.
> +
> +The ``metadata`` field can also be matched in the flow table and updated with
> +actions such as ``set_field`` and ``move``.
> +
> +**Conformance**
> +  OpenFlow 1.1 introduced ``write_metadata``.  Open vSwitch 2.1 added support
> +  for ``write_metadata``.
> +
> +
> +The ``goto_table`` instruction
> +------------------------------
> +..
> +  name: GOTO_TABLE
> +
> +**Syntax**:
> +  | ``goto_table:``\ *table*
> +
> +Jumps to *table* as the next table in the process pipeline.  The table may be
> +a number between 0 and 254 or a table name.
> +
> +It is an error if *table* is less than or equal to the table of the flow that
> +contains it; that is, ``goto_table`` must move forward in the OpenFlow
> +pipeline.  Since ``goto_table`` must be the last instruction in a flow, it
> +never leads to recursion.  The ``resubmit`` extension action is more flexible.
> +
> +**Conformance**
> +  OpenFlow 1.1 introduced ``goto_table``.  Open vSwitch 2.1 added support for
> +  ``goto_table``.
> diff --git a/build-aux/extract-ofp-actions b/build-aux/extract-ofp-actions
> index 2d1dbe709..0aa6c65f3 100755
> --- a/build-aux/extract-ofp-actions
> +++ b/build-aux/extract-ofp-actions
> @@ -4,8 +4,6 @@ import getopt
>   import sys
>   import os.path
>   import re
> -import xml.dom.minidom
> -import build.nroff
>   
>   OFP_ACTION_ALIGN = 8
>   
> @@ -73,7 +71,6 @@ def usage():
>       print('''\
>   %(argv0)s, for extracting OpenFlow action data
>   usage: %(argv0)s [prototypes | definitions] OFP-ACTIONS.c
> -usage: %(argv0)s ovs-actions OVS-ACTIONS.XML
>   
>   Commands:
>   
> @@ -84,9 +81,6 @@ Commands:
>     definitions OFP-ACTIONS.C
>       Reads ofp-actions.c and prints a set of definitions to #include late in
>       ofp-actions.c.
> -
> -  ovs-actions OVS-ACTIONS.XML
> -    Reads ovs-actions.xml and prints documentation in troff format.\
>   ''' % {"argv0": argv0})
>       sys.exit(0)
>   
> @@ -387,133 +381,6 @@ static enum ofperr ofpact_decode(const struct ofp_action_header *,
>                                    uint64_t arg, const struct vl_mff_map *vl_mff_map,
>                                    uint64_t *tlv_bitmap, struct ofpbuf *out);
>   """)
> -

> -## ------------------------ ##
> -## Documentation Generation ##
> -## ------------------------ ##
> -
> -def action_to_xml(action_node, body):
> -    syntax = 0
> -    for node in action_node.childNodes:
> -        if node.nodeType == node.ELEMENT_NODE and node.tagName == 'syntax':
> -            if body[-1].strip() == '.PP':
> -                del body[-1]
> -            if syntax:
> -                body += ['.IQ\n']
> -            else:
> -                body += ['.IP "\\fBSyntax:\\fR"\n']
> -            body += [build.nroff.inline_xml_to_nroff(x, r'\fR')
> -                     for x in node.childNodes] + ['\n']
> -            syntax += 1
> -        elif (node.nodeType == node.ELEMENT_NODE
> -              and node.tagName == 'conformance'):
> -            body += ['.IP "\\fBConformance:\\fR"\n']
> -            body += [build.nroff.block_xml_to_nroff(node.childNodes)]
> -        else:
> -            body += [build.nroff.block_xml_to_nroff([node])]
> -
> -def group_xml_to_nroff(group_node):
> -    title = group_node.attributes['title'].nodeValue
> -
> -    body = []
> -    for node in group_node.childNodes:
> -        if node.nodeType == node.ELEMENT_NODE and node.tagName == 'action':
> -            action_to_xml(node, body)
> -        else:
> -            body += [build.nroff.block_xml_to_nroff([node])]
> -
> -    content = [
> -        '.bp\n',
> -        '.SH \"%s\"\n' % build.nroff.text_to_nroff(title.upper())]
> -    content += body
> -    return ''.join(content)
> -
> -def make_ovs_actions(ovs_actions_xml):
> -    document = xml.dom.minidom.parse(ovs_actions_xml)
> -    doc = document.documentElement
> -
> -    global version
> -    if version == None:
> -        version = "UNKNOWN"
> -
> -    print('''\
> -'\\" tp
> -.\\" -*- mode: troff; coding: utf-8 -*-
> -.TH "ovs\-actions" 7 "%s" "Open vSwitch" "Open vSwitch Manual"
> -.fp 5 L CR              \\" Make fixed-width font available as \\fL.
> -.de ST
> -.  PP
> -.  RS -0.15in
> -.  I "\\\\$1"
> -.  RE
> -..
> -
> -.de SU
> -.  PP
> -.  I "\\\\$1"
> -..
> -
> -.de IQ
> -.  br
> -.  ns
> -.  IP "\\\\$1"
> -..
> -
> -.de TQ
> -.  br
> -.  ns
> -.  TP "\\\\$1"
> -..
> -.de URL
> -\\\\$2 \\(laURL: \\\\$1 \\(ra\\\\$3
> -..
> -.if \\n[.g] .mso https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.tmac%2F&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=829MGqobrX4p%2BFcsAaGnhjXguYqS3AQDi0GIgllDOSY%3D&reserved=0
> -.SH NAME
> -ovs\-actions \- OpenFlow actions and instructions with Open vSwitch extensions
> -.
> -.PP
> -''' % version)
> -
> -    s = ''
> -    for node in doc.childNodes:
> -        if node.nodeType == node.ELEMENT_NODE and node.tagName == "group":
> -            s += group_xml_to_nroff(node)
> -        elif node.nodeType == node.TEXT_NODE:
> -            assert node.data.isspace()
> -        elif node.nodeType == node.COMMENT_NODE:
> -            pass
> -        else:
> -            s += build.nroff.block_xml_to_nroff([node])
> -
> -    if n_errors:
> -        sys.exit(1)
> -
> -    output = []
> -    for oline in s.split("\n"):
> -        oline = oline.strip()
> -
> -        # Life is easier with nroff if we don't try to feed it Unicode.
> -        # Fortunately, we only use a few characters outside the ASCII range.
> -        oline = oline.replace(u'\u2208', r'\[mo]')
> -        oline = oline.replace(u'\u2260', r'\[!=]')
> -        oline = oline.replace(u'\u2264', r'\[<=]')
> -        oline = oline.replace(u'\u2265', r'\[>=]')
> -        oline = oline.replace(u'\u00d7', r'\[mu]')
> -        if len(oline):
> -            output += [oline]
> -
> -    # nroff tends to ignore .bp requests if they come after .PP requests,
> -    # so remove .PPs that precede .bp.
> -    for i in range(len(output)):
> -        if output[i] == '.bp':
> -            j = i - 1
> -            while j >= 0 and output[j] == '.PP':
> -                output[j] = None
> -                j -= 1
> -    for i in range(len(output)):
> -        if output[i] is not None:
> -            print(output[i])
> -
>   

>   ## ------------ ##
>   ## Main Program ##
> @@ -544,8 +411,7 @@ if __name__ == '__main__':
>           sys.exit(1)
>   
>       commands = {"prototypes": (lambda fn: extract_ofp_actions(fn, False), 1),
> -                "definitions": (lambda fn: extract_ofp_actions(fn, True), 1),
> -                "ovs-actions": (make_ovs_actions, 1)}
> +                "definitions": (lambda fn: extract_ofp_actions(fn, True), 1)}
>   
>       if not args[0] in commands:
>           sys.stderr.write("%s: unknown command \"%s\" "
> diff --git a/lib/automake.mk b/lib/automake.mk
> index 8ac138f71..46f869a33 100644
> --- a/lib/automake.mk
> +++ b/lib/automake.mk
> @@ -667,12 +667,3 @@ lib/ovs-fields.7: $(srcdir)/build-aux/extract-ofp-fields include/openvswitch/met
>               $(srcdir)/lib/meta-flow.xml > $@.tmp
>   	$(AM_V_at)mv $@.tmp $@
>   EXTRA_DIST += lib/meta-flow.xml
> -
> -man_MANS += lib/ovs-actions.7
> -CLEANFILES += lib/ovs-actions.7
> -lib/ovs-actions.7: $(srcdir)/build-aux/extract-ofp-actions lib/ovs-actions.xml
> -	$(AM_V_GEN)PYTHONIOENCODING=utf8 $(run_python) $< \
> -            --ovs-version=$(VERSION) ovs-actions \
> -            $(srcdir)/lib/ovs-actions.xml > $@.tmp
> -	$(AM_V_at)mv $@.tmp $@
> -EXTRA_DIST += lib/ovs-actions.xml
> diff --git a/lib/ovs-actions.xml b/lib/ovs-actions.xml
> deleted file mode 100644
> index c94b5f3b3..000000000
> --- a/lib/ovs-actions.xml
> +++ /dev/null
> @@ -1,3277 +0,0 @@
> -<?xml version="1.0" encoding="utf-8"?>
> -<actions>
> -  <h1>Introduction</h1>
> -
> -  <p>
> -    This document aims to comprehensively document all of the OpenFlow actions
> -    and instructions, both standard and non-standard, supported by Open
> -    vSwitch, regardless of origin.  The document includes information of
> -    interest to Open vSwitch users, such as the semantics of each supported
> -    action and the syntax used by Open vSwitch tools, and to developers seeking
> -    to build controllers and switches compatible with Open vSwitch, such as the
> -    wire format for each supported message.
> -  </p>
> -
> -  <h2>Actions</h2>
> -
> -  <p>
> -    In this document, we define an <dfn>action</dfn> as an OpenFlow action,
> -    which is a kind of command that specifies what to do with a packet.
> -    Actions are used in OpenFlow flows to describe what to do when the flow
> -    matches a packet, and in a few other places in OpenFlow.  Each version of
> -    the OpenFlow specification defines standard actions, and beyond that many
> -    OpenFlow switches, including Open vSwitch, implement extensions to the
> -    standard.
> -  </p>
> -
> -  <p>
> -    OpenFlow groups actions in two ways: as an <dfn>action list</dfn> or an
> -    <dfn>action set</dfn>, described below.
> -  </p>
> -
> -  <h3>Action Lists</h3>
> -
> -  <p>
> -    An <dfn>action list</dfn>, a concept present in every version of OpenFlow,
> -    is simply an ordered sequence of actions.  The OpenFlow specifications
> -    require a switch to execute actions within an action list in the order
> -    specified, and to refuse to execute an action list entirely if it cannot
> -    implement the actions in that order [OpenFlow 1.0, section 3.3], with one
> -    exception: when an action list outputs multiple packets, the switch may
> -    output the packets in an order different from that specified.  Usually,
> -    this exception is not important, especially in the common case when the
> -    packets are output to different ports.
> -  </p>
> -
> -  <h3>Action Sets</h3>
> -
> -  <p>
> -    OpenFlow 1.1 introduced the concept of an <dfn>action set</dfn>.  An action
> -    set is also a sequence of actions, but the switch reorders the actions and
> -    drops duplicates according to rules specified in the OpenFlow
> -    specifications.  Because of these semantics, some standard OpenFlow actions
> -    cannot usefully be included in an action set.  For some, but not all, Open
> -    vSwitch extension actions, Open vSwitch defines its own action set
> -    semantics and ordering.
> -  </p>
> -
> -  <p>
> -    The OpenFlow pipeline has an action set associated with it as a packet is
> -    processed.  After pipeline processing is otherwise complete, the switch
> -    executes the actions in the action set.
> -  </p>
> -
> -  <p>
> -    Open vSwitch applies actions in an action set in the following order:
> -    Except as noted otherwise below, the action set only executes at most a
> -    single action of each type, and when more than one action of a given type
> -    is present, the one added to the set later replaces the earlier action:
> -  </p>
> -
> -  <ol>
> -    <li><code>strip_vlan</code></li>
> -    <li><code>pop_mpls</code></li>
> -    <li><code>decap</code></li>
> -    <li><code>encap</code></li>
> -    <li><code>push_mpls</code></li>
> -    <li><code>push_vlan</code></li>
> -    <li><code>dec_ttl</code></li>
> -    <li><code>dec_mpls_ttl</code></li>
> -    <li><code>dec_nsh_ttl</code></li>
> -    <li>
> -      <p>
> -        All of the following actions are executed in the order added to the
> -        action set, with cumulative effect.  That is, when multiple actions
> -        modify the same part of a field, the later modification takes effect,
> -        and when they modify different parts of a field (or different fields),
> -        then both modifications are applied:
> -      </p>
> -
> -      <ul>
> -        <li><code>load</code></li>
> -        <li><code>move</code></li>
> -        <li><code>mod_dl_dst</code></li>
> -        <li><code>mod_dl_src</code></li>
> -        <li><code>mod_nw_dst</code></li>
> -        <li><code>mod_nw_src</code></li>
> -        <li><code>mod_nw_tos</code></li>
> -        <li><code>mod_nw_ecn</code></li>
> -        <li><code>mod_nw_ttl</code></li>
> -        <li><code>mod_tp_dst</code></li>
> -        <li><code>mod_tp_src</code></li>
> -        <li><code>mod_vlan_pcp</code></li>
> -        <li><code>mod_vlan_vid</code></li>
> -        <li><code>set_field</code></li>
> -        <li><code>set_tunnel</code></li>
> -        <li><code>set_tunnel64</code></li>
> -      </ul>
> -    </li>
> -    <li><code>set_queue</code></li>
> -    <li>
> -      <code>group</code>, <code>output</code>, <code>resubmit</code>,
> -      <code>ct_clear</code>, or <code>ct</code>.  If more than one of these
> -      actions is present, then the one listed earliest above is executed and
> -      the others are ignored, regardless of the order in which they were added
> -      to the action set.  (If none of these actions is present, the action set
> -      has no real effect, because the modified packet is not sent anywhere and
> -      thus the modifications are not visible.)
> -    </li>
> -  </ol>
> -
> -  <p>
> -    An action set may only contain the actions listed above.
> -  </p>
> -
> -  <h2>Error Handling</h2>
> -
> -  <p>
> -    Packet processing can encounter a variety of errors:
> -  </p>
> -
> -  <dl>
> -    <dt>Bridge not found</dt>
> -    <dd>
> -      <p>
> -        Open vSwitch supports an extension to the standard OpenFlow
> -        <code>controller</code> action called a ``continuation,'' which allows
> -        the controller to interrupt and later resume the processing of a packet
> -        through the switch pipeline.  This error occurs when such a packet's
> -        processing cannot be resumed, e.g. because the bridge processing it has
> -        been destroyed.  Open vSwitch reports this error to the controller as
> -        Open vSwitch extension error <code>NXR_STALE</code>.
> -      </p>
> -
> -      <p>
> -        This error prevents packet processing entirely.
> -      </p>
> -    </dd>
> -
> -    <dt>Recursion too deep</dt>
> -    <dd>
> -      <p>
> -        While processing a given packet, Open vSwitch limits the flow table
> -        recursion depth to 64, to ensure that packet processing uses a finite
> -        amount of time and space.  Actions that count against the recursion
> -        limit include <code>resubmit</code> from a given OpenFlow table to the
> -        same or an earlier table, <code>group</code>, and <code>output</code>
> -        to patch ports.
> -      </p>
> -
> -      <p>
> -        A <code>resubmit</code> from one table to a later one (or,
> -        equivalently. a <code>goto_table</code> instruction) does not count
> -        against the depth limit because resubmits to strictly monotonically
> -        increasing tables will eventually terminate.  OpenFlow tables are most
> -        commonly traversed in numerically increasing order, so this limit has
> -        little effect on conventionally designed OpenFlow pipelines.
> -      </p>
> -
> -      <p>
> -        This error terminates packet processing.  Any previous side effects
> -        (e.g. output actions) are retained.
> -      </p>
> -
> -      <p>
> -        Usually this error indicates a loop or other bug in the OpenFlow flow
> -        tables.  To assist debugging, when this error occurs, Open vSwitch 2.10
> -        and later logs a trace of the packet execution, as if by
> -        <code>ovs-appctl ofproto/trace</code>, rate-limited to one per minute
> -        to reduce the log volume.
> -      </p>
> -    </dd>
> -
> -    <dt>Too many resubmits</dt>
> -    <dd>
> -      <p>
> -        Open vSwitch limits the total number of <code>resubmit</code> actions
> -        that a given packet can execute to 4,096.  For this purpose,
> -        <code>goto_table</code> instructions and output to the
> -        <code>table</code> port are treated like <code>resubmit</code>.  This
> -        limits the amount of time to process a single packet.
> -      </p>
> -
> -      <p>
> -        Unlike the limit on recursion depth, the limit on resubmits counts all
> -        resubmits, regardless of direction.
> -      </p>
> -
> -      <p>
> -        This error has the same effect, including logging, as exceeding the
> -        recursion depth limit.
> -      </p>
> -    </dd>
> -
> -    <dt>Stack too deep</dt>
> -    <dd>
> -      <p>
> -        Open vSwitch limits the amount of data that the <code>push</code>
> -        action can put onto the stack at one time to 64 kB of data.
> -      </p>
> -
> -      <p>
> -        This error terminates packet processing.  Any previous side effects
> -        (e.g. output actions) are retained.
> -      </p>
> -    </dd>
> -
> -    <dt>No recirculation context</dt>
> -    <dt>Recirculation conflict</dt>
> -    <dd>
> -      These errors indicate internal errors inside Open vSwitch and should
> -      generally not occur.  If you notice recurring log messages about these
> -      errors, please report a bug.
> -    </dd>
> -
> -    <dt>Too many MPLS labels</dt>
> -    <dd>
> -      <p>
> -        Open vSwitch can process packets with any number of MPLS labels, but
> -        its ability to push and pop MPLS labels is limited, currently to 3
> -        labels.  Attempting to push more than the supported number of labels
> -        onto a packet, or to pop any number of labels from a packet with more
> -        than the supported number, raises this error.
> -      </p>
> -
> -      <p>
> -        This error terminates packet processing, retaining any previous side
> -        effects (e.g. output actions).  When this error arises within the
> -        execution of a group bucket, it only terminates that bucket's
> -        execution, not packet processing overall.
> -      </p>
> -    </dd>
> -
> -    <dt>Invalid tunnel metadata</dt>
> -    <dd>
> -      <p>
> -        Open vSwitch raises this error when it processes a Geneve packet that
> -        has TLV options with an invalid form, e.g. where the length in a TLV
> -        would extend past the end of the options.
> -      </p>
> -
> -      <p>
> -        This error prevents packet processing entirely.
> -      </p>
> -    </dd>
> -
> -    <dt>Unsupported packet type</dt>
> -    <dd>
> -      <p>
> -        When a <code>encap</code> action encapsulates a packet, Open vSwitch
> -        raises this error if it does not support the combination of the new
> -        encapsulation with the current packet.  <code>encap(ethernet)</code>
> -        raises this error if the current packet is not an L3 packet, and
> -        <code>encap(nsh)</code> raises this error if the current packet is not
> -        Ethernet, IPv4, IPv6, or NSH.
> -      </p>
> -
> -      <p>
> -        When a <code>decap</code> action decapsulates a packet, Open vSwitch
> -        raises this error if it does not support the type of inner packet.
> -        <code>decap</code> of an Ethernet header raises this error if a VLAN
> -        header is present, <code>decap</code> of a NSH packet raises this error
> -        if the NSH inner packet is not Ethernet, IPv4, IPv6, or NSH, and
> -        <code>decap</code> of other types of packets is unsupported and also
> -        raises this error.
> -      </p>
> -
> -      <p>
> -        This error terminates packet processing, retaining any previous side
> -        effects (e.g. output actions).  When this error arises within the
> -        execution of a group bucket, it only terminates that bucket's
> -        execution, not packet processing overall.
> -      </p>
> -    </dd>
> -  </dl>
> -
> -  <h2>Inconsistencies</h2>
> -
> -  <p>
> -    OpenFlow 1.0 allows any action to be part of any flow, regardless of the
> -    flow's match.  Some combinations do not make sense, e.g. an
> -    <code>set_nw_tos</code> action in a flow that matches only ARP packets or
> -    <code>strip_vlan</code> in a flow that matches packets without VLAN tags.
> -    Other combinations have varying results depending on the kind of packet
> -    that the flow processes, e.g. a <code>set_nw_src</code> action in a flow
> -    that does not match on Ethertype will be treated as a no-op when it
> -    processes a non-IPv4 packet.  Nevertheless OVS allows all of the above in
> -    conformance with OpenFlow 1.0, that is, the following will succeed:
> -  </p>
> -
> -  <pre>
> -$ ovs-ofctl -O OpenFlow10 add-flow br0 arp,actions=mod_nw_tos:12
> -$ ovs-ofctl -O OpenFlow10 add-flow br0 dl_vlan=0xffff,actions=strip_vlan
> -$ ovs-ofctl -O OpenFlow10 add-flow br0 actions=mod_nw_src:1.2.3.4
> -  </pre>
> -
> -  <p>
> -    Open vSwitch calls these kinds of combinations <dfn>inconsistencies</dfn>
> -    between match and actions.  OpenFlow 1.1 and later forbid inconsistencies,
> -    and disallow the examples described above by preventing such flows from
> -    being added.  All of the above, for example, will fail with an error
> -    message if one replaces <code>OpenFlow10</code> by <code>OpenFlow11</code>.
> -  </p>
> -
> -  <p>
> -    OpenFlow 1.1 and later cannot detect and disallow all inconsistencies.  For
> -    example, the <code>write_actions</code> instruction arbitrarily delays
> -    execution of the actions inside it, which can even be canceled with
> -    <code>clear_actions</code>, so that there is no way to ensure that its
> -    actions are consistent with the packet at the time they execute.  Thus,
> -    actions with <code>write_actions</code> and some other contexts are exempt
> -    from consistency requirements.
> -  </p>
> -
> -  <p>
> -    When OVS executes an action inconsistent with the packet, it treats it as a
> -    no-op.
> -  </p>
> -
> -  <h2>Inter-Version Compatibility</h2>
> -
> -  <p>
> -    Open vSwitch supports multiple OpenFlow versions simultaneously on a single
> -    switch.  When actions are added with one OpenFlow version and then
> -    retrieved with another, Open vSwitch does its best to translate between
> -    them.
> -  </p>
> -
> -  <p>
> -    Inter-version compatibility issues can still arise when different
> -    connections use different OpenFlow versions.  Backward compatibility is the
> -    most obvious case.  Suppose, for example, that an OpenFlow 1.1 session adds
> -    a flow with a <code>push_vlan</code> action, for which there is no
> -    equivalent in OpenFlow 1.0.  If an OpenFlow 1.0 session retrieves this
> -    flow, Open vSwitch must somehow represent the action.
> -  </p>
> -
> -  <p>
> -    Forward compatibility can also be an issue, because later OpenFlow versions
> -    sometimes remove functionality.  The best example is the
> -    <code>enqueue</code> action from OpenFlow 1.0, which OpenFlow 1.1 removed.
> -  </p>
> -
> -  <p>
> -    In practice, Open vSwitch uses a variety of strategies for inter-version
> -    compatibility:
> -  </p>
> -
> -  <ul>
> -    <li>
> -      Most standard OpenFlow actions, such as <code>output</code> actions,
> -      translate without compatibility issues.
> -    </li>
> -
> -    <li>
> -      Open vSwitch supports its extension actions in every OpenFlow version, so
> -      they do not pose inter-version compatibility problems.
> -    </li>
> -
> -    <li>
> -      Open vSwitch sometimes adds extension actions to ensure backward or
> -      forward compatibility.  For example, for backward compatibility with the
> -      <code>group</code> action added in OpenFlow 1.1, Open vSwitch includes
> -      an OpenFlow 1.0 extension <code>group</code> action.
> -    </li>
> -  </ul>
> -
> -  <p>
> -    Perfect inter-version compatibility is not possible, so best results
> -    require OpenFlow connections to use a consistent version.  One may enforce
> -    use of a particular version by setting the <code>protocols</code> column
> -    for a bridge, e.g. to force <code>br0</code> to use only OpenFlow 1.3:
> -  </p>
> -
> -  <pre>
> -    ovs-vsctl set bridge br0 protocols=OpenFlow13
> -  </pre>
> -
> -  <h2>Field Specifications</h2>
> -
> -  <p>
> -    Many Open vSwitch actions refer to fields.  In such cases, fields may
> -    usually be referred to by their common names, such as <code>eth_dst</code>
> -    for the Ethernet destination field, or by their full OXM or NXM names, such
> -    as <code>NXM_OF_ETH_DST</code> or <code>OXM_OF_ETH_DST</code>.  Before Open
> -    vSwitch 2.7, only OXM or NXM field names were accepted.
> -  </p>
> -
> -  <p>
> -    Many actions that act on fields can also act on <dfn>subfields</dfn>, that
> -    is, parts of fields, written as
> -    <code><var>field</var>[<var>start</var>..<var>end</var>]</code>, where
> -    <var>start</var> is the first bit and <var>end</var> is the last bit to use
> -    in <var>field</var>, e.g. <code>vlan_tci[13..15]</code> for the VLAN PCP.
> -    A single-bit subfield may also be written as
> -    <code><var>field</var>[<var>offset</var>]</code>,
> -    e.g. <code>vlan_tci[13]</code> for the least-significant bit of the VLAN
> -    PCP.  Empty brackets may be used to explicitly designate an entire field,
> -    e.g. <code>vlan_tci[]</code> for the entire 16-bit VLAN TCI header.  Before
> -    Open vSwitch 2.7, brackets were required in field specifications.
> -  </p>
> -
> -  <p>
> -    See <code>ovs-fields</code>(7) for a list of fields and their names.
> -  </p>
> -
> -  <h2>Port Specifications</h2>
> -
> -  <p>
> -    Many Open vSwitch actions refer to OpenFlow ports.  In such cases, the port
> -    may be specified as a numeric port number in the range 0 to 65,535,
> -    although Open vSwitch only assigns port numbers in the range 1 through
> -    62,279 to ports.  OpenFlow 1.1 and later use 32-bit port numbers, but Open
> -    vSwitch never assigns a port number that requires more than 16 bits.
> -  </p>
> -
> -  <p>
> -    In most contexts, the name of a port may also be used.  (The most obvious
> -    context where a port name may not be used is in an <code>ovs-ofctl</code>
> -    command along with the <code>--no-names</code> option.)  When a port's name
> -    contains punctuation or could be ambiguous with other actions, the name may
> -    be enclosed in double quotes, with JSON-like string escapes supported (see
> -    [RFC 8259]).
> -  </p>
> -
> -  <p>
> -    Open vSwitch also supports the following standard OpenFlow port names (even
> -    in contexts where port names are not otherwise supported).  The
> -    corresponding OpenFlow 1.0 and 1.1+ port numbers are listed alongside them
> -    but should not be used in flow syntax:
> -  </p>
> -
> -  <ul>
> -    <li><code>in_port</code> (65528 or 0xfff8; 0xfffffff8)</li>
> -    <li><code>table</code> (65529 or 0xfff9; 0xfffffff9)</li>
> -    <li><code>normal</code> (65530 or 0xfffa; 0xfffffffa)</li>
> -    <li><code>flood</code> (65531 or 0xfffb; 0xfffffffb)</li>
> -    <li><code>all</code> (65532 or 0xfffc; 0xfffffffc)</li>
> -    <li><code>controller</code> (65533 or 0xfffd; 0xfffffffd)</li>
> -    <li><code>local</code> (65534 or 0xfffe; 0xfffffffe)</li>
> -    <li><code>any</code> or <code>none</code> (65535 or 0xffff; 0xffffffff)</li>
> -    <li><code>unset</code> (not in OpenFlow 1.0; 0xfffffff7)</li>
> -  </ul>
> -
> -  <!-- What about OVS version compatibility as opposed to OF version -->
> -
> -  <group title="Output Actions">
> -    <p>
> -      These actions send a packet to a physical port or a controller.  A packet
> -      that never encounters an output action on its trip through the Open
> -      vSwitch pipeline is effectively dropped.  Because actions are executed in
> -      order, a packet modification action that is not eventually followed by an
> -      output action will not have an externally visible effect.
> -    </p>
> -
> -    <action name="OUTPUT, OUTPUT_REG, OUTPUT_TRUNC">
> -      <h2>The <code>output</code> action</h2>
> -      <syntax><var>port</var></syntax>
> -      <syntax><code>output:</code><var>port</var></syntax>
> -      <syntax><code>output:<var>field</var></code></syntax>
> -      <syntax><code>output(port=<var>port</var>, max_len=<var>nbytes</var>)</code></syntax>
> -
> -      <p>
> -        Outputs the packet to an OpenFlow port most commonly specified as
> -        <var>port</var>.  Alternatively, the output port may be read from
> -        <var>field</var>, a field or subfield in the syntax described under
> -        ``Field Specifications'' above.  Either way, if the port is the
> -        packet's input port, the packet is not output.
> -      </p>
> -
> -      <p>
> -        The port may be one of the following standard OpenFlow ports:
> -      </p>
> -
> -      <dl>
> -        <dt><code>local</code></dt>
> -        <dd>
> -          Outputs the packet on the ``local port'' that corresponds to the
> -          network device that has the same name as the bridge, unless the
> -          packet was received on the local port.  OpenFlow switch
> -          implementations are not required to have a local port, but Open
> -          vSwitch bridges always do.
> -        </dd>
> -
> -        <dt><code>in_port</code></dt>
> -        <dd>
> -          Outputs the packet on the port on which it was received.  This is the
> -          only standard way to output the packet to the input port (but see
> -          ``Output to the Input port'', below).
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        The port may also be one of the following additional OpenFlow ports,
> -        unless <code>max_len</code> is specified:
> -      </p>
> -
> -      <dl>
> -        <dt><code>normal</code></dt>
> -        <dd>
> -          Subjects the packet to the device's normal L2/L3 processing.  This
> -          action is not implemented by all OpenFlow switches, and each switch
> -          implements it differently.  The section ``The OVS Normal Pipeline''
> -          below documents the OVS implementation.
> -        </dd>
> -
> -        <dt><code>flood</code></dt>
> -        <dd>
> -          Outputs the packet on all switch physical ports, except the port on
> -          which it was received and any ports on which flooding is disabled.
> -          Flooding can be disabled automatically on a port by Open vSwitch when
> -          IEEE 802.1D spanning tree (STP) or rapid spanning tree (RSTP) is
> -          enabled, or by a controller using an OpenFlow
> -          <code>OFPT_MOD_PORT</code> request to set the port's
> -          <code>OFPPC_NO_FLOOD</code> flag (<code>ovs-ofctl mod-port</code>
> -          provides a command-line interface to set this flag).
> -        </dd>
> -
> -        <dt><code>all</code></dt>
> -        <dd>
> -          Outputs the packet on all switch physical ports except the port on
> -          which it was received.
> -        </dd>
> -
> -        <dt><code>controller</code></dt>
> -        <dd>
> -          Sends the packet and its metadata to an OpenFlow controller or
> -          controllers encapsulated in an OpenFlow ``packet-in'' message.  The
> -          separate <code>controller</code> action, described below, provides
> -          more options for output to a controller.
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        Open vSwitch rejects output to other standard OpenFlow ports, including
> -        <code>none</code>, <code>unset</code>, and port numbers reserved for
> -        future use as standard ports, with the error
> -        <code>OFPBAC_BAD_OUT_PORT</code>.
> -      </p>
> -
> -      <p>
> -        With <var>max_len</var>, the packet is truncated to at most
> -        <var>nbytes</var> bytes before being output.  In this case, the output
> -        port may not be a patch port.  Truncation is just for the single output
> -        action, so that later actions in the OpenFlow pipeline work with the
> -        complete packet.  The truncation feature is meant for use in monitoring
> -        applications, e.g. for mirroring packets to a collector.
> -      </p>
> -
> -      <p>
> -        When an <code>output</code> action specifies the number of a port that
> -        does not currently exist (and is not in the range for standard ports),
> -        the OpenFlow specification allows but does not require OVS to reject
> -        the action.  All versions of Open vSwitch treat such an action as a
> -        no-op.  If a port with the number is created later, then the action
> -        will be honored at that point.  (OpenFlow requires OVS to reject output
> -        to a port number that will never be valid, with
> -        <code>OFPBAC_BAD_OUT_PORT</code>, but this situation does not arise
> -        when OVS is a software switch, since the user can add or renumber ports
> -        at any time.)
> -      </p>
> -
> -      <p>
> -        A controller can suppress output to a port by setting its
> -        <code>OFPPC_NO_FORWARD</code> flag using an OpenFlow
> -        <code>OFPT_MOD_PORT</code> request (<code>ovs-ofctl mod-port</code>
> -        provides a command-line interface to set this flag).  When output is
> -        disabled, <code>output</code> actions (and other actions that output to
> -        the port) are allowed but have no effect.
> -      </p>
> -
> -      <p>
> -        Open vSwitch allows output to a port that does not exist, although
> -        OpenFlow allows switches to reject such actions.
> -      </p>
> -
> -      <!-- XXX output to patch ports details -->
> -
> -      <h3>Output to the Input Port</h3>
> -
> -      <p>
> -        OpenFlow requires a switch to ignore attempts to send a packet out its
> -        ingress port in the most straightforward way.  For example,
> -        <code>output:234</code> has no effect if the packet has ingress port
> -        234.  The rationale is that dropping these packets makes it harder to
> -        loop the network.  Sometimes this behavior can even be convenient,
> -        e.g. it is often the desired behavior in a flow that forwards a packet
> -        to several ports (``floods'' the packet).
> -      </p>
> -
> -      <p>
> -        Sometimes one really needs to send a packet out its ingress port
> -        (``hairpin''). In this case, use <code>in_port</code> to explicitly
> -        output the packet to its input port, e.g.:
> -      </p>
> -
> -      <pre>
> -        $ ovs-ofctl add-flow br0 in_port=2,actions=in_port
> -      </pre>
> -
> -      <p>
> -        This also works in some circumstances where the flow doesn't match on
> -        the input port.  For example, if you know that your switch has five
> -        ports numbered 2 through 6, then the following will send every received
> -        packet out every port, even its ingress port:
> -      </p>
> -
> -      <pre>
> -        $ ovs-ofctl add-flow br0 actions=2,3,4,5,6,in_port
> -      </pre>
> -
> -      <p>
> -        or, equivalently:
> -      </p>
> -
> -      <pre>
> -        $ ovs-ofctl add-flow br0 actions=all,in_port
> -      </pre>
> -
> -      <p>
> -        Sometimes, in complicated flow tables with multiple levels of
> -        <code>resubmit</code> actions, a flow needs to output to a particular
> -        port that may or may not be the ingress port.  It's difficult to take
> -        advantage of output to <code>in_port</code> in this situation.  To
> -        help, Open vSwitch provides, as an OpenFlow extension, the ability to
> -        modify the <code>in_port</code> field.  Whatever value is currently in
> -        the <code>in_port</code> field is both the port to which output will be
> -        dropped and the destination for <code>in_port</code>.  This means that
> -        the following adds flows that reliably output to port 2 or to ports 2
> -        through 6, respectively:
> -      </p>
> -
> -      <pre>
> -        $ ovs-ofctl add-flow br0 "in_port=2,actions=load:0->in_port,2"
> -        $ ovs-ofctl add-flow br0 "actions=load:0->in_port,2,3,4,5,6"
> -      </pre>
> -
> -      <p>
> -        If <code>in_port</code> is important for matching or other reasons, one
> -        may save and restore it on the stack:
> -      </p>
> -
> -      <pre>
> -        $ ovs-ofctl add-flow br0 actions="push:in_port,\
> -        load:0->in_port,\
> -        2,3,4,5,6,\
> -        pop:in_port"
> -      </pre>
> -
> -      <conformance>
> -        All versions of OpenFlow and Open vSwitch support <code>output</code>
> -        to a literal <var>port</var>.  Output to a register is an OpenFlow
> -        extension introduced in Open vSwitch 1.3.  Output with truncation is an
> -        OpenFlow extension introduced in Open vSwitch 2.6.
> -      </conformance>
> -    </action>
> -
> -    <h2>The OVS Normal Pipeline</h2>
> -
> -    <p>
> -      This section documents how Open vSwitch implements output to the
> -      <code>normal</code> port.  The OpenFlow specification places no
> -      requirements on how this port works, so all of this documentation is
> -      specific to Open vSwitch.
> -    </p>
> -
> -    <p>
> -      Open vSwitch uses the <code>Open_vSwitch</code> database, detailed in
> -      <code>ovs-vswitchd.conf.db</code>(5), to determine the details of the
> -      normal pipeline.
> -    </p>
> -
> -    <p>
> -      The normal pipeline executes the following ingress stages for each
> -      packet.  Each stage either accepts the packet, in which case the packet
> -      goes on to the next stage, or drops the packet, which terminates the
> -      pipeline.  The result of the ingress stages is a set of output ports,
> -      which is the empty set if some ingress stage drops the packet:
> -    </p>
> -
> -    <ol>
> -      <li>
> -        <p>
> -          <b>Input port lookup</b>: Looks up the OpenFlow
> -          <code>in_port</code> field's value to the corresponding
> -          <code>Port</code> and <code>Interface</code> record in the database.
> -        </p>
> -
> -        <p>
> -          The <code>in_port</code> is normally the OpenFlow port that the
> -          packet was received on.  If <code>set_field</code> or another actions
> -          changes the <code>in_port</code>, the updated value is honored.
> -          Accept the packet if the lookup succeeds, which it normally will.  If
> -          the lookup fails, for example because <code>in_port</code> was
> -          changed to an unknown value, drop the packet.
> -        </p>
> -      </li>
> -
> -      <li>
> -        <b>Drop malformed packet</b>: If the packet is malformed enough that it
> -        contains only part of an 802.1Q header, then drop the packet with an
> -        error.
> -      </li>
> -
> -      <li>
> -        <b>Drop packets sent to a port reserved for mirroring:</b> If the
> -        packet was received on a port that is configured as the output port for
> -        a mirror (that is, it is the <code>output_port</code> in some
> -        <code>Mirror</code> record), then drop the packet.
> -      </li>
> -
> -      <li>
> -        <p>
> -          <b>VLAN input processing:</b> This stage determines what VLAN the
> -          packet is in.  It also verifies that this VLAN is valid for the port;
> -          if not, drop the packet.  How the VLAN is determined and which ones
> -          are valid vary based on the <code>vlan-mode</code> in the input
> -          port's <code>Port</code> record:
> -        </p>
> -
> -        <dl>
> -          <dt><code>trunk</code></dt>
> -          <dd>
> -            The packet is in the VLAN specified in its 802.1Q header, or in
> -            VLAN 0 if there is no 802.1Q header.  The <code>trunks</code>
> -            column in the <code>Port</code> record lists the valid VLANs; if it
> -            is empty, all VLANs are valid.
> -          </dd>
> -
> -          <dt><code>access</code></dt>
> -          <dd>
> -            The packet is in the VLAN specified in the <code>tag</code> column
> -            of its <code>Port</code> record.  The packet must not have an
> -            802.1Q header with a nonzero VLAN ID; if it does, drop the packet.
> -          </dd>
> -
> -          <dt><code>native-tagged</code></dt>
> -          <dt><code>native-untagged</code></dt>
> -          <dd>
> -            Same as <code>trunk</code> except that the VLAN of a packet without
> -            an 802.1Q header is not necessarily zero; instead, it is taken from
> -            the <code>tag</code> column.
> -          </dd>
> -
> -          <dt><code>dot1q-tunnel</code></dt>
> -          <dd>
> -            The packet is in the VLAN specified in the <code>tag</code> column
> -            of its <code>Port</code> record, which is a QinQ service VLAN with
> -            the Ethertype specified by the <code>Port</code>'s
> -            <code>other_config</code> : <code>qinq-ethtype</code>.  If the
> -            packet has an 802.1Q header, then it specifies the customer VLAN.
> -            The <code>cvlans</code> column specifies the valid customer VLANs;
> -            if it is empty, all customer VLANs are valid.
> -          </dd>
> -        </dl>
> -      </li>
> -
> -      <li>
> -        <b>Drop reserved multicast addresses:</b> If the packet is addressed to
> -        a reserved Ethernet multicast address and the <code>Bridge</code>
> -        record does not have <code>other_config</code> :
> -        <code>forward-bpdu</code> set to <code>true</code>, drop the packet.
> -      </li>
> -
> -      <li>
> -        <p>
> -          <b>LACP bond admissibility:</b> This step applies only if the input
> -          port is a member of a bond (a <code>Port</code> with more than one
> -          <code>Interface</code>) and that bond is configured to use LACP.
> -          Otherwise, skip to the next step.
> -        </p>
> -
> -        <p>
> -          The behavior here depends on the state of LACP negotiation:
> -        </p>
> -
> -        <ul>
> -          <li>
> -            If LACP has been negotiated with the peer, accept the packet if the
> -            bond member is enabled (i.e. carrier is up and it hasn't been
> -            administratively disabled).  Otherwise, drop the packet.
> -          </li>
> -
> -          <li>
> -            If LACP negotiation is incomplete, then drop the packet.  There is
> -            one exception: if fallback to active-backup mode is enabled,
> -            continue with the next step, pretending that the active-backup
> -            balancing mode is in use.
> -          </li>
> -        </ul>
> -      </li>
> -
> -      <li>
> -        <p>
> -          <b>Non-LACP bond admissibility:</b> This step applies if the input
> -          port is a member of a bond without LACP configured, or if a LACP bond
> -          falls back to active-backup as described in the previous step.  If
> -          neither of these applies, skip to the next step.
> -        </p>
> -
> -        <p>
> -          If the packet is an Ethernet multicast or broadcast, and not received
> -          on the bond's active member, drop the packet.
> -        </p>
> -
> -        <p>
> -          The remaining behavior depends on the bond's balancing mode:
> -        </p>
> -
> -        <dl>
> -          <dt>L4 (aka TCP balancing)</dt>
> -          <dd>
> -            Drop the packet (this balancing mode is only supported with LACP).
> -          </dd>
> -
> -          <dt>Active-backup</dt>
> -          <dd>
> -            Accept the packet only if it was received on the active member.
> -          </dd>
> -
> -          <dt>SLB (Source Load Balancing)</dt>
> -          <dd>
> -            Drop the packet if the bridge has not learned the packet's source
> -            address (in its VLAN) on the port that received it.  Otherwise,
> -            accept the packet unless it is a gratuitous ARP.  Otherwise,
> -            accept the packet if the MAC entry we found is ARP-locked.
> -            Otherwise, drop the packet.  (See the ``SLB Bonding'' section in
> -            the OVS bonding document for more information and a rationale.)
> -          </dd>
> -        </dl>
> -      </li>
> -
> -      <li>
> -        <p>
> -          <b>Learn source MAC:</b> If the source Ethernet address is not a
> -          multicast address, then insert a mapping from packet's source
> -          Ethernet address and VLAN to the input port in the bridge's MAC
> -          learning table.  (This is skipped if the packet's VLAN is listed in
> -          the switch's <code>Bridge</code> record in the
> -          <code>flood_vlans</code> column, since there is no use for MAC
> -          learning when all packets are flooded.)
> -        </p>
> -
> -        <p>
> -          When learning happens on a non-bond port, if the packet is a
> -          gratuitous ARP, the entry is marked as ARP-locked.  The lock expires
> -          after 5 seconds.  (See the ``SLB Bonding'' section in the OVS bonding
> -          document for more information and a rationale.)
> -        </p>
> -      </li>
> -
> -      <li>
> -        <b>IP multicast path:</b> If multicast snooping is enabled on the
> -        bridge, and the packet is an Ethernet multicast but not an Ethernet
> -        broadcast, and the packet is an IP packet, then the packet takes a
> -        special processing path.  This path is not yet documented here.  <!--
> -        XXX document multicast processing -->
> -      </li>
> -
> -      <li>
> -        <p>
> -          <b>Output port set:</b> Search the MAC learning table for the port
> -          corresponding to the packet's Ethernet destination and VLAN.  If the
> -          search finds an entry, the output port set is just the learned
> -          port.  Otherwise (including the case where the packet is an Ethernet
> -          multicast or in <code>flood_vlans</code>), the output port set is all
> -          of the ports in the bridge that belong to the packet's VLAN, except
> -          for any ports that were disabled for flooding via OpenFlow or that
> -          are configured in a <code>Mirror</code> record as a mirror
> -          destination port.
> -        </p>
> -      </li>
> -    </ol>
> -
> -    <p>
> -      The following egress stages execute once for each element in the set of
> -      output ports.  They execute (conceptually) in parallel, so that a
> -      decision or action taken for a given output port has no effect on those
> -      for another one:
> -    </p>
> -
> -    <ol>
> -      <li>
> -        <b>Drop loopback:</b> If the output port is the same as the input port,
> -        drop the packet.
> -      </li>
> -
> -      <li>
> -        <p>
> -          <b>VLAN output processing:</b> This stage adjusts the packet to
> -          represent the VLAN in the correct way for the output port.  Its
> -          behavior varies based on the <code>vlan-mode</code> in the output
> -          port's <code>Port</code> record:
> -        </p>
> -
> -        <dl>
> -          <dt><code>trunk</code></dt>
> -          <dt><code>native-tagged</code></dt>
> -          <dt><code>native-untagged</code></dt>
> -          <dd>
> -            If the packet is in VLAN 0 (for <code>native-untagged</code>, if
> -            the packet is in the native VLAN) drops any 802.1Q header.
> -            Otherwise, ensures that there is an 802.1Q header designating the
> -            VLAN.
> -          </dd>
> -
> -          <dt><code>access</code></dt>
> -          <dd>
> -            Remove any 802.1Q header that was present.
> -          </dd>
> -
> -          <dt><code>dot1q-tunnel</code></dt>
> -          <dd>
> -            Ensures that the packet has an outer 802.1Q header with the QinQ
> -            Ethertype and the specified configured tag, and an inner 802.1Q
> -            header with the packet's VLAN.
> -          </dd>
> -        </dl>
> -      </li>
> -
> -      <li>
> -        <b>VLAN priority tag processing:</b> If VLAN output processing
> -        discarded the 802.1Q headers, but priority tags are enabled with
> -        <code>other_config</code> : <code>priority-tags</code> in the output
> -        port's <code>Port</code> record, then a priority-only tag is added
> -        (perhaps only if the priority would be nonzero, depending on the
> -        configuration).
> -      </li>
> -
> -      <li>
> -        <p>
> -          <b>Bond member choice:</b> If the output port is a bond, the code
> -          chooses a particular member.  This step is skipped for non-bonded
> -          ports.
> -        </p>
> -
> -        <p>
> -          If the bond is configured to use LACP, but LACP negotiation is
> -          incomplete, then normally the packet is dropped.  The exception is
> -          that if fallback to active-backup mode is enabled, the egress
> -          pipeline continues choosing a bond member as if active-backup mode
> -          was in use.
> -        </p>
> -
> -        <p>
> -          For active-backup mode, the output member is the active member.
> -          Other modes hash appropriate header fields and use the hash value to
> -          choose one of the enabled members.
> -        </p>
> -      </li>
> -
> -      <li>
> -        <b>Output:</b> The pipeline sends the packet to the output port.
> -      </li>
> -    </ol>
> -
> -    <action name="CONTROLLER">
> -      <h2>The <code>controller</code> action</h2>
> -      <syntax><code>controller</code></syntax>
> -      <syntax><code>controller:</code><var>max_len</var></syntax>
> -      <syntax><code>controller(</code><var>key</var>[<code>=</code><var>value</var>]<code>,</code> ...<code>)</code></syntax>
> -
> -      <p>
> -        Sends the packet and its metadata to an OpenFlow controller or
> -        controllers encapsulated in an OpenFlow ``packet-in'' message.  The
> -        supported options are:
> -      </p>
> -
> -      <dl>
> -        <dt><code>max_len=</code><var>max_len</var></dt>
> -        <dd>
> -          <p>
> -            Limit to <var>max_len</var> the number of bytes of the packet to
> -            send in the ``packet-in.''  A <var>max_len</var> of 0 prevents any
> -            of the packet from being sent (thus, only metadata is included).
> -            By default, the entire packet is sent, equivalent to a
> -            <var>max_len</var> of 65535.
> -          </p>
> -        </dd>
> -
> -        <dt><code>reason=</code><var>reason</var></dt>
> -        <dd>
> -          Specify <var>reason</var> as the reason for sending the message in
> -          the ``packet-in.''  The supported reasons are <code>no_match</code>,
> -          <code>action</code>, <code>invalid_ttl</code>,
> -          <code>action_set</code>, <code>group</code>, and
> -          <code>packet_out</code>.  The default reason is <code>action</code>.
> -        </dd>
> -
> -        <dt><code>id=</code><var>controller_id</var></dt>
> -        <dd>
> -          Specify <var>controller_id</var>, a 16-bit integer, as the connection
> -          ID of the OpenFlow controller or controllers to which the
> -          ``packet-in'' message should be sent.  The default is zero.  Zero is
> -          also the default connection ID for each controller connection, and a
> -          given controller connection will only have a nonzero connection ID if
> -          its controller uses the <code>NXT_SET_CONTROLLER_ID</code> Open
> -          vSwitch extension to OpenFlow.
> -        </dd>
> -
> -        <dt><code>userdata=</code><var>hh</var>...</dt>
> -        <dd>
> -          Supplies the bytes represented as hex digits <var>hh</var> as
> -          additional data to the controller in the ``packet-in'' message.
> -          Pairs of hex digits may be separated by periods for readability.
> -        </dd>
> -
> -        <dt><code>pause</code></dt>
> -        <dd>
> -          Causes the switch to freeze the packet's trip through Open vSwitch
> -          flow tables and serializes that state into the packet-in message as a
> -          ``continuation,'' an additional property in the
> -          <code>NXT_PACKET_IN2</code> message.  The controller can later send
> -          the continuation back to the switch in an <code>NXT_RESUME</code>
> -          message, which will restart the packet's traversal from the point
> -          where it was interrupted.  This permits an OpenFlow controller to
> -          interpose on a packet midway through processing in Open vSwitch.
> -        </dd>
> -      </dl>
> -
> -      <conformance>
> -        All versions of OpenFlow and Open vSwitch support
> -        <code>controller</code> action and its <code>max_len</code> option.
> -        The <code>userdata</code> and <code>pause</code> options require the
> -        Open vSwitch <code>NXAST_CONTROLLER2</code> extension action added in
> -        Open vSwitch 2.6.  In the absence of these options, the
> -        <var>reason</var> (other than <code>reason=action</code>) and
> -        <var>controller_id</var> (option than <code>controller_id=0</code>)
> -        options require the Open vSwitch <code>NXAST_CONTROLLER</code>
> -        extension action added in Open vSwitch 1.6.
> -      </conformance>
> -    </action>
> -
> -    <action name="ENQUEUE">
> -      <h2>The <code>enqueue</code> action</h2>
> -      <syntax><code>enqueue(</code><var>port</var><code>,</code><var>queue</var><code>)</code></syntax>
> -      <syntax><code>enqueue:</code><var>port</var><code>:</code><var>queue</var></syntax>
> -
> -      <p>
> -        Enqueues the packet on the specified <var>queue</var> within port
> -        <var>port</var>.
> -      </p>
> -
> -      <p>
> -        <var>port</var> must be an OpenFlow port number or name as described
> -        under ``Port Specifications'' above.  <var>port</var> may be
> -        <code>in_port</code> or <code>local</code> but the other standard
> -        OpenFlow ports are not allowed.
> -      </p>
> -
> -      <p>
> -        <var>queue</var> must be a a number between 0 and 4294967294
> -        (0xfffffffe), inclusive.  The number of actually supported queues
> -        depends on the switch.  Some OpenFlow implementations do not support
> -        queuing at all.  In Open vSwitch, the supported queues vary depending
> -        on the operating system, datapath, and hardware in use.  Use the
> -        <code>QoS</code> and <code>Queue</code> tables in the Open vSwitch
> -        database to configure queuing on individual OpenFlow ports (see
> -        <code>ovs-vswitchd.conf.db</code>(5) for more information).
> -      </p>
> -
> -      <conformance>
> -        <p>
> -          Only OpenFlow 1.0 supports <code>enqueue</code>.  OpenFlow 1.1 added
> -          the <code>set_queue</code> action to use in its place along with
> -          <code>output</code>.
> -        </p>
> -
> -        <p>
> -          Open vSwitch translates <code>enqueue</code> to a sequence of three
> -          actions in OpenFlow 1.1 or later: <code>set_queue:<var>queue</var>,
> -          output:<var>port</var>, pop_queue</code>.  This is equivalent in
> -          behavior as long as the flow table does not otherwise use
> -          <code>set_queue</code>, but it relies on the <code>pop_queue</code>
> -          Open vSwitch extension action.
> -        </p>
> -      </conformance>
> -    </action>
> -
> -    <action name="BUNDLE,BUNDLE_LOAD">
> -      <h2>The <code>bundle</code> and <code>bundle_load</code> actions</h2>
> -      <syntax><code>bundle(</code><var>fields</var><code>, </code><var>basis</var><code>, </code><var>algorithm</var><code>, ofport, members:</code><var>port</var>...<code>)</code></syntax>
> -      <syntax><code>bundle_load(</code><var>fields</var><code>, </code><var>basis</var><code>, </code><var>algorithm</var><code>, ofport, </code><var>dst</var><code>, members:</code><var>port</var>...<code>)</code></syntax>
> -
> -      <p>
> -        These actions choose a port (a ``member'') from a
> -        comma-separated OpenFlow <var>port</var> list.  After selecting the
> -        port, <code>bundle</code> outputs to it, whereas
> -        <code>bundle_load</code> writes its port number to <var>dst</var>,
> -        which must be a 16-bit or wider field or subfield in the syntax
> -        described under ``Field Specifications'' above.
> -      </p>
> -
> -      <p>
> -        These actions hash a set of <var>fields</var> using <var>basis</var> as
> -        a universal hash parameter, then apply the bundle link selection
> -        <var>algorithm</var> to choose a <var>port</var>.
> -      </p>
> -
> -      <p>
> -        <var>fields</var> must be one of the following.  For the options with
> -        ``symmetric'' in the name, reversing source and destination addresses
> -        yields the same hash:
> -      </p>
> -
> -      <dl>
> -        <dt><code>eth_src</code></dt>
> -        <dd>
> -          Ethernet source address.
> -        </dd>
> -
> -        <dt><code>nw_src</code></dt>
> -        <dd>
> -          IPv4 or IPv6 source address.
> -        </dd>
> -
> -        <dt><code>nw_dst</code></dt>
> -        <dd>
> -          IPv4 or IPv6 destination address.
> -        </dd>
> -
> -        <dt><code>symmetric_l4</code></dt>
> -        <dd>
> -          Ethernet source and destination, Ethernet type, VLAN ID or IDs (if
> -          any), IPv4 or IPv6 source and destination, IP protocol, TCP or SCTP
> -          (but not UDP) source and destination.
> -        </dd>
> -
> -        <dt><code>symmetric_l3l4</code></dt>
> -        <dd>
> -          IPv4 or IPv6 source and destination, IP protocol, TCP or SCTP (but
> -          not UDP) source and destination.
> -        </dd>
> -
> -        <dt><code>symmetric_l3l4+udp</code></dt>
> -        <dd>
> -          Like <code>symmetric_l3l4</code> but include UDP ports.
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        <var>algorithm</var> must be one of the following:
> -      </p>
> -
> -      <dl>
> -        <dt><code>active_backup</code></dt>
> -        <dd>
> -          Chooses the first live port listed in <var>members</var>.
> -        </dd>
> -
> -        <dt><code>hrw</code> (Highest Random Weight)</dt>
> -        <dd>
> -          <p>
> -            Computes the following, considering only the live ports in
> -            <var>members</var>:
> -          </p>
> -
> -          <pre>
> -for <var>i</var> in [1,<var>n_members</var>]:
> -    <var>weights</var>[<var>i</var>] = hash(<var>flow</var>, <var>i</var>)
> -<var>member</var> = { <var>i</var> such that <var>weights</var>[<var>i</var>] >= <var>weights</var>[<var>j</var>] for all <var>j</var> != <var>i</var> }
> -          </pre>
> -
> -          <p>
> -            This algorithm is specified by RFC 2992.
> -          </p>
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        The algorithms take port liveness into account when selecting
> -        members.  The definition of whether a port is live is subject to
> -        change.  It currently takes into account carrier status and link
> -        monitoring protocols such as BFD and CFM.  If none of the members is
> -        live, <code>bundle</code> does not output the packet and
> -        <code>bundle_load</code> stores <code>OFPP_NONE</code> (65535) in the
> -        output field.
> -      </p>
> -
> -      <p>
> -        Example: <code>bundle(eth_src,0,hrw,ofport,members:4,8)</code> uses an
> -        Ethernet source hash with basis 0, to select between OpenFlow ports 4
> -        and 8 using the Highest Random Weight algorithm.
> -      </p>
> -
> -      <conformance>
> -        Open vSwitch 1.2 introduced the <code>bundle</code> and
> -        <code>bundle_load</code> OpenFlow extension actions.
> -      </conformance>
> -    </action>
> -
> -    <action name="GROUP">
> -      <h2>The <code>group</code> action</h2>
> -      <syntax><code>group:</code><var>group</var></syntax>
> -      <p>
> -        Outputs the packet to the OpenFlow group <var>group</var>, which must
> -        be a number in the range 0 to 4294967040 (0xffffff00).  The group must
> -        exist or Open vSwitch will refuse to add the flow.  When a group is
> -        deleted, Open vSwitch also deletes all of the flows that output to it.
> -      </p>
> -
> -      <p>
> -        Groups contain action sets, whose semantics are described above in the
> -        section ``Action Sets''.  The semantics of action sets can be
> -        surprising to users who expect action list semantics, since action sets
> -        reorder and sometimes ignore actions.
> -      </p>
> -
> -      <p>
> -        A <code>group</code> action usually executes the action set or sets in
> -        one or more group buckets.  Open vSwitch saves the packet and metadata
> -        before it executes each bucket, and then restores it afterward.  Thus,
> -        when a group executes more than one bucket, this means that each bucket
> -        executes on the same packet and metadata.  Moreover, regardless of the
> -        number of buckets executed, the packet and metadata are the same before
> -        and after executing the group.
> -      </p>
> -
> -      <p>
> -        Sometimes saving and restoring the packet and metadata can be
> -        undesirable.  In these situations, workarounds are possible.  For
> -        example, consider a pipeline design in which a <code>select</code>
> -        group bucket is to communicate to a later stage of processing a value
> -        based on which bucket was selected.  An obvious design would be for the
> -        bucket to communicate the value via <code>set_field</code> on a
> -        register.  This does not work because registers are part of the
> -        metadata that <code>group</code> saves and restores.  The following
> -        alternative bucket designs do work:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          Recursively invoke the rest of the pipeline with
> -          <code>resubmit</code>.
> -        </li>
> -
> -        <li>
> -          <p>
> -            Use <code>resubmit</code> into a table that uses <code>push</code>
> -            to put the value on the stack for the caller to <code>pop</code>
> -            off.  This works because <code>group</code> preserves only packet
> -            data and metadata, not the stack.
> -          </p>
> -
> -          <p>
> -            (This design requires indirection through <code>resubmit</code>
> -            because actions sets may not contain <code>push</code> or
> -            <code>pop</code> actions.)
> -          </p>
> -        </li>
> -      </ul>
> -
> -      <p>
> -        An <code>exit</code> action within a group bucket terminates only
> -        execution of that bucket, not other buckets or the overall pipeline.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.1 introduced <code>group</code>.  Open vSwitch 2.6 and later
> -        also supports <code>group</code> as an extension to OpenFlow 1.0.
> -      </conformance>
> -    </action>
> -
> -  </group>
> -
> -  <group title="Encapsulation and Decapsulation Actions">
> -    <action name="STRIP_VLAN">
> -      <h2>The <code>strip_vlan</code> and <code>pop</code> actions</h2>
> -      <syntax><code>strip_vlan</code></syntax>
> -      <syntax><code>pop_vlan</code></syntax>
> -
> -      <p>
> -        Removes the outermost VLAN tag, if any, from the packet.
> -      </p>
> -
> -      <p>
> -        The two names for this action are synonyms with no semantic difference.
> -        The OpenFlow 1.0 specification uses the name <code>strip_vlan</code>
> -        and later versions use <code>pop_vlan</code>, but OVS accepts either
> -        name regardless of version.
> -      </p>
> -
> -      <p>
> -        In OpenFlow 1.1 and later, consistency rules allow
> -        <code>strip_vlan</code> only in a flow that matches only packets with a
> -        VLAN tag (or following an action that pushes a VLAN tag, such as
> -        <code>push_vlan</code>).  See ``Inconsistencies'', above, for more
> -        information.
> -      </p>
> -
> -      <conformance>
> -        All versions of OpenFlow and Open vSwitch support this action.
> -      </conformance>
> -    </action>
> -
> -    <action name="PUSH_VLAN">
> -      <h2>The <code>push_vlan</code> action</h2>
> -      <syntax><code>push_vlan:</code><var>ethertype</var></syntax>
> -
> -      <p>
> -        Pushes a new outermost VLAN onto the packet.  Uses TPID
> -        <var>ethertype</var>, which must be <code>0x8100</code> for an 802.1Q
> -        C-tag or <code>0x88a8</code> for a 802.1ad S-tag.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.1 and later supports this action.  Open vSwitch 2.8 added
> -        support for multiple VLAN tags (with a limit of 2) and 802.1ad S-tags.
> -      </conformance>
> -    </action>
> -
> -    <action name="PUSH_MPLS">
> -      <h2>The <code>push_mpls</code> action</h2>
> -      <syntax><code>push_mpls:<var>ethertype</var></code></syntax>
> -
> -      <p>
> -        Pushes a new outermost MPLS label stack entry (LSE) onto the packet and
> -        changes the packet's Ethertype to <var>ethertype</var>, which must be
> -        either <code>B0x8847</code> or <code>0x8848</code>.
> -      </p>
> -
> -      <p>
> -        If the packet did not already contain any MPLS labels, initializes the
> -        new LSE as:
> -      </p>
> -
> -      <dl>
> -        <dt>Label</dt>
> -        <dd>
> -          2, if the packet contains IPv6, 0 otherwise.
> -        </dd>
> -        <dt>TC</dt>
> -        <dd>
> -          The low 3 bits of the packet's DSCP value, or 0 if the packet is not
> -          IP.
> -        </dd>
> -        <dt>TTL</dt>
> -        <dd>
> -          Copied from the IP TTL, or 64 if the packet is not IP.
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        If the packet did already contain an MPLS label, initializes the new
> -        outermost label as a copy of the existing outermost label.
> -      </p>
> -
> -      <p>
> -        OVS currently supports at most 3 MPLS labels.
> -      </p>
> -
> -      <p>
> -        This action applies only to Ethernet packets.
> -      </p>
> -
> -      <conformance>
> -        Open vSwitch 1.11 introduced support for MPLS.  OpenFlow 1.1 and later
> -        support <code>push_mpls</code>.  Open vSwitch implements
> -        <code>push_mpls</code> as an extension to OpenFlow 1.0.
> -      </conformance>
> -    </action>
> -
> -    <action name="POP_MPLS">
> -      <h2>The <code>pop_mpls</code> action</h2>
> -      <syntax><code>pop_mpls:<var>ethertype</var></code></syntax>
> -
> -      <p>
> -        Strips the outermost MPLS label stack entry and changes the packet's
> -        Ethertype to <var>ethertype</var>.
> -      </p>
> -
> -      <p>
> -        This action applies only to Ethernet packets with at least one MPLS
> -        label.  If there is more than one MPLS label, then <var>ethertype</var>
> -        should be an MPLS Ethertype (<code>B0x8847</code> or
> -        <code>0x8848</code>).
> -      </p>
> -
> -      <conformance>
> -        Open vSwitch 1.11 introduced support for MPLS.  OpenFlow 1.1 and later
> -        support <code>pop_mpls</code>.  Open vSwitch implements
> -        <code>pop_mpls</code> as an extension to OpenFlow 1.0.
> -      </conformance>
> -    </action>
> -
> -    <action name="ENCAP">
> -      <h2>The <code>encap</code> action</h2>
> -      <syntax><code>encap(nsh(</code>[<code>md_type=<var>md_type</var></code>]<code>, </code>[<code>tlv(<var>class</var>,<var>type</var>,<var>value</var>)</code>]...<code>))</code></syntax>
> -      <syntax><code>encap(ethernet)</code></syntax>
> -
> -      <p>
> -        The <code>encap</code> action encapsulates a packet with a specified
> -        header.  It has variants for different kinds of encapsulation.
> -      </p>
> -
> -      <p>
> -        The <code>encap(nsh(</code>...<code>))</code> variant encapsulates an
> -        Ethernet frame with NSH.  The <var>md_type</var> may be <code>1</code>
> -        or <code>2</code> for metadata type 1 or 2, defaulting to 1.  For
> -        metadata type 2, TLVs may be specified with <var>class</var> as a
> -        16-bit hexadecimal integer beginning with <code>0x</code>,
> -        <var>type</var> as an 8-bit decimal integer, and <var>value</var> a
> -        sequence of pairs of hex digits beginning with <code>0x</code>.  For
> -        example:
> -      </p>
> -
> -      <dl>
> -        <dt><code>encap(nsh(md_type=1))</code></dt>
> -        <dd>
> -          Encapsulates the packet with an NSH header with metadata type 1.
> -        </dd>
> -
> -        <dt><code>encap(nsh(md_type=2,tlv(0x1000,10,0x12345678)))</code></dt>
> -        <dd>
> -          Encapsulates the packet with an NSH header, NSH metadata type 2, and
> -          an NSH TLV with class 0x1000, type 10, and the 4-byte value
> -          0x12345678.
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        The <code>encap(ethernet)</code> variant encapsulate a bare L3 packet
> -        in an Ethernet frame.  The Ethernet type is initialized to the L3
> -        packet's type, e.g. 0x0800 if the L3 packet is IPv4.  The Ethernet
> -        source and destination are initially zeroed.
> -      </p>
> -
> -      <conformance>
> -        This action is an Open vSwitch extension to OpenFlow 1.3 and later,
> -        introduced in Open vSwitch 2.8.
> -      </conformance>
> -    </action>
> -
> -    <action name="DECAP">
> -      <h2>The <code>decap</code> action</h2>
> -      <syntax><code>decap</code></syntax>
> -
> -      <p>
> -        Removes an outermost encapsulation from the packet:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          If the packet is an Ethernet packet, removes the Ethernet header,
> -          which changes the packet into a bare L3 packet.  If the packet has
> -          VLAN tags, raises an unsupported packet type error (see ``Error
> -          Handling'', above).
> -        </li>
> -
> -        <li>
> -          Otherwise, if the packet is an NSH packet, removes the NSH header,
> -          revealing the inner packet.  Open vSwitch supports Ethernet, IPv4,
> -          IPv6, and NSH inner packet types.  Other types raise unsupported
> -          packet type errors.
> -        </li>
> -
> -        <li>
> -          Otherwise, raises an unsupported packet type error.
> -        </li>
> -      </ul>
> -
> -      <conformance>
> -        This action is an Open vSwitch extension to OpenFlow 1.3 and later,
> -        introduced in Open vSwitch 2.8.
> -      </conformance>
> -    </action>
> -  </group>
> -
> -  <group title="Field Modification Actions">
> -    <p>
> -      These actions modify packet data and metadata fields.
> -    </p>
> -
> -    <action name="SET_FIELD">
> -      <h2>The <code>set_field</code> and <code>load</code> actions</h2>
> -      <syntax><code>set_field:</code><var>value</var>[<code>/</code><var>mask</var>]<code>-></code><var>dst</var></syntax>
> -      <syntax><code>load:</code><var>value</var><code>-></code><var>dst</var><code></code></syntax>
> -
> -      <p>
> -        These actions loads a literal value into a field or part of a field.
> -        The <code>set_field</code> action takes <var>value</var> in the
> -        customary syntax for field <var>dst</var>,
> -        e.g. <code>00:11:22:33:44:55</code> for an Ethernet address, and
> -        <var>dst</var> as the field's name.  The optional <var>mask</var>
> -        allows part of a field to be set.
> -      </p>
> -
> -      <p>
> -        The <code>load</code> action takes <var>value</var> as an integer value
> -        (in decimal or prefixed by <code>0x</code> for hexadecimal) and
> -        <var>dst</var> as a field or subfield in the syntax described under
> -        ``Field Specifications'' above.
> -      </p>
> -
> -      <p>
> -        The following all set the Ethernet source address to 00:11:22:33:44:55:
> -      </p>
> -
> -      <ul>
> -        <li><code>set_field:00:11:22:33:44:55->eth_src</code></li>
> -        <li><code>load:0x001122334455->eth_src</code></li>
> -        <li><code>load:0x001122334455->OXM_OF_ETH_SRC[]</code></li>
> -      </ul>
> -
> -      <p>
> -        The following all set the multicast bit in the Ethernet destination
> -        address:
> -      </p>
> -
> -      <ul>
> -        <li><code>set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst</code></li>
> -        <li><code>load:1->eth_dst[40]</code></li>
> -      </ul>
> -
> -      <p>
> -        Open vSwitch prohibits a <code>set_field</code> or <code>load</code>
> -        action whose <var>dst</var> is not guaranteed to be part of the packet;
> -        for example, <code>set_field</code> of <code>nw_dst</code> is only
> -        allowed in a flow that matches on Ethernet type 0x800.  In some cases,
> -        such as in an action set, Open vSwitch can't statically check that
> -        <var>dst</var> is part of the packet, and in that case if it is not
> -        then Open vSwitch treats the action as a no-op.
> -      </p>
> -
> -      <conformance>
> -        Open vSwitch 1.1 introduced <code>NXAST_REG_LOAD</code> as a extension
> -        to OpenFlow 1.0 and used <code>load</code> to express it.  Later,
> -        OpenFlow 1.2 introduced a standard <code>OFPAT_SET_FIELD</code> action
> -        that was restricted to loading entire fields, so Open vSwitch added the
> -        form <code>set_field</code> with this restriction.  OpenFlow 1.5
> -        extended <code>OFPAT_SET_FIELD</code> to the point that it became a
> -        superset of <code>NXAST_REG_LOAD</code>.  Open vSwitch translates
> -        either syntax as necessary for the OpenFlow version in use: in OpenFlow
> -        1.0 and 1.1, <code>NXAST_REG_LOAD</code>; in OpenFlow 1.2, 1.3, and
> -        1.4, <code>NXAST_REG_LOAD</code> for <code>load</code> or for loading a
> -        subfield, <code>OFPAT_SET_FIELD</code> otherwise; and OpenFlow 1.5 and
> -        later, <code>OFPAT_SET_FIELD</code>.
> -      </conformance>
> -    </action>
> -
> -    <action name="REG_MOVE">
> -      <h2>The <code>move</code> action</h2>
> -      <syntax><code>move:<var>src</var>-><var>dst</var></code></syntax>
> -
> -      <p>
> -        Copies the named bits from field or subfield <var>src</var> to field or
> -        subfield <var>dst</var>.  <var>src</var> and <var>dst</var> should
> -        fields or subfields in the syntax described under ``Field
> -        Specifications'' above.  The two fields or subfields must have the same
> -        width.
> -      </p>
> -
> -      <p>
> -        Examples:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          <code>move:reg0[0..5]->reg1[26..31]</code> copies the six bits
> -          numbered 0 through 5 in register 0 into bits 26 through 31 of
> -          register 1.
> -        </li>
> -        <li>
> -          <code>move:reg0[0..15]->vlan_tci</code> copies the least
> -          significant 16 bits of register 0 into the VLAN TCI field.
> -        </li>
> -      </ul>
> -
> -      <conformance>
> -        In OpenFlow 1.0 through 1.4, <code>move</code> ordinarily uses an Open
> -        vSwitch extension to OpenFlow.  In OpenFlow 1.5, <code>move</code> uses
> -        the OpenFlow 1.5 standard <code>OFPAT_COPY_FIELD</code> action.  The
> -        ONF has also made <code>OFPAT_COPY_FIELD</code> available as an
> -        extension to OpenFlow 1.3.  Open vSwitch 2.4 and later understands this
> -        extension and uses it if a controller uses it, but for backward
> -        compatibility with older versions of Open vSwitch,
> -        <code>ovs-ofctl</code> does not use it.
> -      </conformance>
> -    </action>
> -
> -    <action name="SET_ETH_SRC, SET_ETH_DST">
> -      <h2>The <code>mod_dl_src</code> and <code>mod_dl_dst</code> actions</h2>
> -      <syntax><code>mod_dl_src:</code><var>mac</var></syntax>
> -      <syntax><code>mod_dl_dst:</code><var>mac</var></syntax>
> -
> -      <p>
> -        Sets the Ethernet source or destination address, respectively, to
> -        <var>mac</var>, which should be expressed in the form
> -        <code><var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var>:<var>xx</var></code>.
> -      </p>
> -
> -      <p>
> -        For L3-only packets, that is, those that lack an Ethernet header, this
> -        action has no effect.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.0 and 1.1 have specialized actions for these purposes.
> -        OpenFlow 1.2 and later do not, so Open vSwitch translates them to
> -        appropriate <code>OFPAT_SET_FIELD</code> actions for those versions,
> -      </conformance>
> -    </action>
> -
> -    <action name="SET_IP_SRC, SET_IP_DST">
> -      <h2>The <code>mod_nw_src</code> and <code>mod_nw_dst</code> actions</h2>
> -      <syntax><code>mod_nw_src:</code><var>ip</var></syntax>
> -      <syntax><code>mod_nw_dst:</code><var>ip</var></syntax>
> -
> -      <p>
> -        Sets the IPv4 source or destination address, respectively, to
> -        <var>ip</var>, which should be expressed in the form
> -        <code><var>w</var>.<var>x</var>.<var>y</var>.<var>z</var></code>.
> -      </p>
> -
> -      <p>
> -        In OpenFlow 1.1 and later, consistency rules allow these actions only
> -        in a flow that matches only packets that contain an IPv4 header (or
> -        following an action that adds an IPv4 header,
> -        e.g. <code>pop_mpls:0x0800</code>).  See ``Inconsistencies'', above,
> -        for more information.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.0 and 1.1 have specialized actions for these purposes.
> -        OpenFlow 1.2 and later do not, so Open vSwitch translates them to
> -        appropriate <code>OFPAT_SET_FIELD</code> actions for those versions,
> -      </conformance>
> -    </action>
> -
> -    <action name="SET_IP_DSCP, SET_IP_ECN">
> -      <h2>The <code>mod_nw_tos</code> and <code>mod_nw_ecn</code> actions</h2>
> -      <syntax><code>mod_nw_tos:</code><var>tos</var></syntax>
> -      <syntax><code>mod_nw_ecn:</code><var>ecn</var></syntax>
> -
> -      <p>
> -        The <code>mod_nw_tos</code> action sets the DSCP bits in the IPv4
> -        ToS/DSCP or IPv6 traffic class field to <var>tos</var>, which must be a
> -        multiple of 4 between 0 and 255.  This action does not modify the two
> -        least significant bits of the ToS field (the ECN bits).
> -      </p>
> -
> -      <p>
> -        The <code>mod_nw_ecn</code> action sets the ECN bits in the IPv4 ToS or
> -        IPv6 traffic class field to <code>ecn</code>, which must be a value
> -        between 0 and 3, inclusive.  This action does not modify the six most
> -        significant bits of the field (the DSCP bits).
> -      </p>
> -
> -      <p>
> -        In OpenFlow 1.1 and later, consistency rules allow these actions only
> -        in a flow that matches only packets that contain an IPv4 or IPv6 header
> -        (or following an action that adds such a header).  See
> -        ``Inconsistencies'', above, for more information.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.0 has a <code>mod_nw_tos</code> action but not
> -        <code>mod_nw_ecn</code>.  Open vSwitch implements the latter in
> -        OpenFlow 1.0 as an extension using <code>NXAST_REG_LOAD</code>.
> -        OpenFlow 1.1 has specialized actions for these purposes.  OpenFlow 1.2
> -        and later do not, so Open vSwitch translates them to appropriate
> -        <code>OFPAT_SET_FIELD</code> actions for those versions,
> -      </conformance>
> -    </action>
> -
> -    <action name="SET_L4_SRC_PORT, SET_L4_DST_PORT">
> -      <h2>The <code>mod_tp_src</code> and <code>mod_tp_dst</code> actions</h2>
> -      <syntax><code>mod_tp_src:</code><var>port</var></syntax>
> -      <syntax><code>mod_tp_dst:</code><var>port</var></syntax>
> -
> -      <p>
> -        Sets the TCP or UDP or SCTP source or destination port, respectively,
> -        to <var>port</var>.  Both IPv4 and IPv6 are supported.
> -      </p>
> -
> -      <p>
> -        In OpenFlow 1.1 and later, consistency rules allow these actions only
> -        in a flow that matches only packets that contain a TCP or UDP or SCTP
> -        header.  See ``Inconsistencies'', above, for more information.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.0 and 1.1 have specialized actions for these purposes.
> -        OpenFlow 1.2 and later do not, so Open vSwitch translates them to
> -        appropriate <code>OFPAT_SET_FIELD</code> actions for those versions,
> -      </conformance>
> -    </action>
> -
> -    <action name="DEC_TTL">
> -      <h2>The <code>dec_ttl</code> action</h2>
> -      <syntax><code>dec_ttl</code></syntax>
> -      <syntax><code>dec_ttl(<var>id1</var>, </code>[<code><var>id2</var></code>]...<code>)</code></syntax>
> -
> -      <p>
> -        Decrement TTL of IPv4 packet or hop limit of IPv6 packet.  If the TTL
> -        or hop limit is initially 0 or 1, no decrement occurs, as packets
> -        reaching TTL zero must be rejected.  Instead, Open vSwitch sends a
> -        ``packet-in'' message with reason code <code>OFPR_INVALID_TTL</code> to
> -        each connected controller that has enabled receiving such messages, and
> -        stops processing the current set of actions.  (However, if the current
> -        set of actions was reached through <code>resubmit</code>, the remaining
> -        actions in outer levels resume processing.)
> -      </p>
> -
> -      <p>
> -        As an Open vSwitch extension to OpenFlow, this action supports the
> -        ability to specify a list of controller IDs.  Open vSwitch will only
> -        send the message to controllers with the given ID or IDs.  Specifying
> -        no list is equivalent to specifying a single controller ID of zero.
> -      </p>
> -
> -      <p>
> -        Sets the TCP or UDP or SCTP source or destination port, respectively,
> -        to <var>port</var>.  Both IPv4 and IPv6 are supported.
> -      </p>
> -
> -      <p>
> -        In OpenFlow 1.1 and later, consistency rules allow these actions only
> -        in a flow that matches only packets that contain an IPv4 or IPv6
> -        header.  See ``Inconsistencies'', above, for more information.
> -      </p>
> -
> -      <conformance>
> -        All versions of OpenFlow and Open vSwitch support this action.
> -      </conformance>
> -    </action>
> -
> -    <action name="SET_MPLS_LABEL, SET_MPLS_TC, SET_MPLS_TTL">
> -      <h2>The <code>set_mpls_label</code>, <code>set_mpls_tc</code>, and <code>set_mpls_ttl</code> actions</h2>
> -      <syntax><code>set_mpls_label:</code><var>label</var></syntax>
> -      <syntax><code>set_mpls_tc:</code><var>tc</var></syntax>
> -      <syntax><code>set_mpls_ttl:</code><var>ttl</var></syntax>
> -
> -      <p>
> -        The <code>set_mpls_label</code> action sets the label of the packet's
> -        outer MPLS label stack entry.  <var>label</var> should be a 20-bit
> -        value that is decimal by default; use a <code>0x</code> prefix to
> -        specify the value in hexadecimal.
> -      </p>
> -
> -      <p>
> -        The <code>set_mpls_tc</code> action sets the traffic class of the
> -        packet's outer MPLS label stack entry.  <var>tc</var> should be in the
> -        range 0 to 7, inclusive.
> -      </p>
> -
> -      <p>
> -        The <code>set_mpls_ttl</code> action sets the TTL of the packet's outer
> -        MPLS label stack entry.  <var>ttl</var> should be in the range 0 to 255
> -        inclusive.
> -      </p>
> -
> -      <p>
> -        In OpenFlow 1.1 and later, consistency rules allow these actions only
> -        in a flow that matches only packets that contain an MPLS label (or
> -        following an action that adds an MPLS label,
> -        e.g. <code>push_mpls:0x8847</code>).  See ``Inconsistencies'', above,
> -        for more information.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.0 does not support MPLS, but Open vSwitch implements these
> -        actions as extensions.  OpenFlow 1.1 has specialized actions for these
> -        purposes.  OpenFlow 1.2 and later do not, so Open vSwitch translates
> -        them to appropriate <code>OFPAT_SET_FIELD</code> actions for those
> -        versions,
> -      </conformance>
> -    </action>
> -
> -    <action name="DEC_MPLS_TTL, DEC_NSH_TTL">
> -      <h2>The <code>dec_mpls_ttl</code> and <code>dec_nsh_ttl</code> actions</h2>
> -      <syntax><code>dec_mpls_ttl</code></syntax>
> -      <syntax><code>dec_nsh_ttl</code></syntax>
> -
> -      <p>
> -        These actions decrement the TTL of the packet's outer MPLS label stack
> -        entry or its NSH header, respectively.  If the TTL is initially 0 or 1,
> -        no decrement occurs.  Instead, Open vSwitch sends a ``packet-in''
> -        message with reason code <code>BOFPR_INVALID_TTL</code> to OpenFlow
> -        controllers with ID 0, if it has enabled receiving them.  Processing
> -        the current set of actions then stops.  (However, if the current set of
> -        actions was reached through <code>resubmit</code>, remaining actions in
> -        outer levels resume processing.)
> -      </p>
> -
> -      <p>
> -        In OpenFlow 1.1 and later, consistency rules allow this actions only in
> -        a flow that matches only packets that contain an MPLS label or an NSH
> -        header, respectively.  See ``Inconsistencies'', above, for more
> -        information.
> -      </p>
> -
> -      <conformance>
> -        <p>
> -          Open vSwitch 1.11 introduced support for MPLS.  OpenFlow 1.1 and
> -          later support <code>dec_mpls_ttl</code>.  Open vSwitch implements
> -          <code>dec_mpls_ttl</code> as an extension to OpenFlow 1.0.
> -        </p>
> -
> -        <p>
> -          Open vSwitch 2.8 introduced support for NSH, although the NSH draft
> -          changed after release so that only Open vSwitch 2.9 and later conform
> -          to the final protocol specification.  The <code>dec_nsh_ttl</code>
> -          action and NSH support in general is an Open vSwitch extension not
> -          supported by any version of OpenFlow.
> -        </p>
> -      </conformance>
> -    </action>
> -
> -    <action name="CHECK_PKT_LARGER">
> -      <h2>The <code>check_pkt_larger</code> action</h2>
> -      <syntax>
> -        <code>check_pkt_larger(<var>pkt_len</var>)-><var>dst</var></code>
> -      </syntax>
> -
> -      <p>
> -        Checks if the packet is larger than the specified length in
> -        <var>pkt_len</var>.  If so, stores 1 in <var>dst</var>, which should be
> -        a 1-bit field; if not, stores 0.
> -      </p>
> -
> -      <p>
> -        The packet length to check against the argument <var>pkt_len</var>
> -        includes the L2 header and L2 payload of the packet, but not the VLAN
> -        tag (if present).
> -      </p>
> -
> -      <p>
> -        Examples:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          <code>check_pkt_larger(1500)->reg0[0]</code>
> -        </li>
> -
> -        <li>
> -          <code>check_pkt_larger(8000)->reg9[10]</code>
> -        </li>
> -      </ul>
> -
> -      <p>
> -        This action was added in Open vSwitch 2.11.90.
> -      </p>
> -    </action>
> -
> -    <action name="DELETE_FIELD">
> -      <h2>The <code>delete_field</code> action</h2>
> -      <syntax><code>delete_field:</code><var>field</var></syntax>
> -
> -      <p>
> -        The <code>delete_field</code> action deletes a field in the syntax
> -        described under ``Field Specifications'' above.  Currently, only
> -        the tun_metadta fields are supported.
> -      </p>
> -
> -      <p>
> -        This action was added in Open vSwitch 2.13.90.
> -      </p>
> -    </action>
> -
> -  </group>
> -
> -  <group title="Metadata Actions">
> -    <action name="SET_TUNNEL">
> -      <h2>The <code>set_tunnel</code> action</h2>
> -      <syntax><code>set_tunnel:</code><var>id</var></syntax>
> -      <syntax><code>set_tunnel64:</code><var>id</var></syntax>
> -
> -      <p>
> -        Many kinds of tunnels support a tunnel ID, e.g. VXLAN and Geneve have a
> -        24-bit VNI, and GRE has an optional 32-bit key.  This action sets the
> -        value used for tunnel ID in such tunneled packets, although whether it
> -        is used for a particular tunnel depends on the tunnel's configuration.
> -        See the tunnel ID documentation in <code>ovs-fields</code>(7) for more
> -        information.
> -      </p>
> -
> -      <conformance>
> -        <p>
> -          These actions are OpenFlow extensions.  <code>set_tunnel</code> was
> -          introduced in Open vSwitch 1.0.  <code>set_tunnel64</code>, which is
> -          needed if <var>id</var> is wider than 32 bits, was added in Open
> -          vSwitch 1.1.  Both actions always set the entire tunnel ID field.
> -        </p>
> -
> -        <p>
> -          Open vSwitch supports these actions in all versions of OpenFlow, but
> -          in OpenFlow 1.2 and later it translates them to an appropriate
> -          standardized <code>OFPAT_SET_FIELD</code> action.
> -        </p>
> -      </conformance>
> -    </action>
> -
> -    <action name="SET_QUEUE, POP_QUEUE">
> -      <h2>The <code>set_queue</code> and <code>pop_queue</code> actions</h2>
> -      <syntax><code>set_queue:</code><var>queue</var></syntax>
> -      <syntax><code>pop_queue</code></syntax>
> -
> -      <p>
> -        The <code>set_queue</code> action sets the queue ID to be used for
> -        subsequent output actions to <var>queue</var>, which must be a 32-bit
> -        integer.  The range of meaningful values of <var>queue</var>, and their
> -        meanings, varies greatly from one OpenFlow implementation to another.
> -        Even within a single implementation, there is no guarantee that all
> -        OpenFlow ports have the same queues configured or that all OpenFlow
> -        ports in an implementation can be configured the same way queue-wise.
> -        For more information, see the documentation for the output queue field
> -        in <code>ovs-fields</code>(7).
> -      </p>
> -
> -      <p>
> -        The <code>pop_queue</code> restores the output queue to the default
> -        that was set when the packet entered the switch (generally 0).
> -      </p>
> -
> -      <p>
> -        Four billion queues ought to be enough for anyone: <url
> -        href="https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmailman.stanford.edu%2Fpipermail%2Fopenflow-spec%2F2009-August%2F000394.html%2522%2F&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=xyObj43QLyeZVO4q3Xo6iEPmJjr29Q9ea2D67FSMiJA%3D&reserved=0>
> -      </p>
> -
> -      <conformance>
> -        <p>
> -          OpenFlow 1.1 introduced the <code>set_queue</code> action.  Open
> -          vSwitch also supports it as an extension in OpenFlow 1.0.
> -        </p>
> -
> -        <p>
> -          The <code>pop_queue</code> action is an Open vSwitch extension.
> -        </p>
> -      </conformance>
> -    </action>
> -  </group>
> -
> -  <group title="Firewalling Actions">
> -    <p>
> -      Open vSwitch is often used to implement a firewall.  The preferred way to
> -      implement a firewall is ``connection tracking,'' that is, to keep track
> -      of the connection state of individual TCP sessions.  The <code>ct</code>
> -      action described in this section, added in Open vSwitch 2.5, implements
> -      connection tracking.  For new deployments, it is the recommended way to
> -      implement firewalling with Open vSwitch.
> -    </p>
> -
> -    <p>
> -      Before <code>ct</code> was added, Open vSwitch did not have built-in
> -      support for connection tracking.  Instead, Open vSwitch supported the
> -      <code>learn</code> action, which allows a received packet to add a flow
> -      to an OpenFlow flow table.  This could be used to implement a primitive
> -      form of connection tracking: packets passing through the firewall in one
> -      direction could create flows that allowed response packets back through
> -      the firewall in the other direction.  The additional
> -      <code>fin_timeout</code> action allowed the learned flows to expire
> -      quickly after TCP session termination.
> -    </p>
> -
> -    <action name="CT">
> -      <h2>The <code>ct</code> action</h2>
> -      <syntax><code>ct(</code>[<code><var>argument</var></code>]...<code>)</code></syntax>
> -      <syntax><code>ct(commit</code>[<code>, <var>argument</var></code>]...<code>)</code></syntax>
> -
> -      <p>
> -        The action has two modes of operation, distinguished by whether
> -        <code>commit</code> is present.  The following arguments may be present
> -        in either mode:
> -      </p>
> -
> -      <dl>
> -        <dt><code>zone=<var>value</var></code></dt>
> -        <dd>
> -          A zone is a 16-bit id that isolates connections into separate
> -          domains, allowing overlapping network addresses in different zones.
> -          If a zone is not provided, then the default is 0. The
> -          <var>value</var> may be specified either as a 16-bit integer literal
> -          or a field or subfield in the syntax described under ``Field
> -          Specifications'' above.
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        Without <code>commit</code>, this action sends the packet through the
> -        connection tracker.  The connection tracker keeps track of the state of
> -        TCP connections for packets passed through it.  For each packet through
> -        a connection, it checks that it satisfies TCP invariants and signals
> -        the connection state to later actions using the <code>ct_state</code>
> -        metadata field, which is documented in <code>ovs-fields</code>(7).
> -      </p>
> -
> -      <p>
> -        In this form, <code>ct</code> forks the OpenFlow pipeline:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          In one fork, <code>ct</code> passes the packet to the connection
> -          tracker.  Afterward, it reinjects the packet into the OpenFlow
> -          pipeline with the connection tracking fields initialized.  The
> -          <code>ct_state</code> field is initialized with connection state and
> -          <code>ct_zone</code> to the connection tracking zone specified on the
> -          <code>zone</code> argument.  If the connection is one that is already
> -          tracked, <code>ct_mark</code> and <code>ct_label</code> to its
> -          existing mark and label, respectively; otherwise they are zeroed.  In
> -          addition, <code>ct_nw_proto</code>, <code>ct_nw_src</code>,
> -          <code>ct_nw_dst</code>, <code>ct_ipv6_src</code>,
> -          <code>ct_ipv6_dst</code>, <code>ct_tp_src</code>, and
> -          <code>ct_tp_dst</code> are initialized appropriately for the original
> -          direction connection.  See the <code>resubmit</code> action for a way
> -          to search the flow table with the connection tracking original
> -          direction fields swapped with the packet 5-tuple fields.  See
> -          <code>ovs-fields</code>(7) for details on the connection tracking
> -          fields.
> -        </li>
> -
> -        <li>
> -          In the other fork, the original instance of the packet continues
> -          independent processing following the <code>ct</code> action.  The
> -          <code>ct_state</code> field and other connection tracking metadata
> -          are cleared.
> -        </li>
> -      </ul>
> -
> -      <p>
> -        Without <code>commit</code>, the <code>ct</code> action accepts the
> -        following arguments:
> -      </p>
> -
> -      <dl>
> -        <dt><code>table=<var>table</var></code></dt>
> -        <dd>
> -          Sets the OpenFlow table where the packet is reinjected.  The
> -          <var>table</var> must be a number between 0 and 254 inclusive, or a
> -          table's name.  If <var>table</var> is not specified, then the packet
> -          is not reinjected.
> -        </dd>
> -
> -        <dt><code>nat</code></dt>
> -        <dt><code>nat(<var>type</var>=<var>addrs</var></code>[<code>:<var>ports</var></code>][<code>,<var>flag</var></code>]...<code>)</code></dt>
> -        <dd>
> -          <p>
> -            Specify address and port translation for the connection being
> -            tracked.  The <var>type</var> must be <code>src</code>, for source
> -            address/port translation (SNAT), or <code>dst</code>, for destination
> -            address/port translation (DNAT).  Setting up address translation for
> -            a new connection takes effect only if the connection is later
> -            committed with <code>ct(commit</code>...<code>)</code>.
> -          </p>
> -
> -          <p>
> -            The <code>src</code> and <code>dst</code> options take the following
> -            arguments:
> -          </p>
> -
> -          <dl>
> -            <dt><var>addrs</var></dt>
> -            <dd>
> -              The IP address <var>addr</var> or range
> -              <code><var>addr1</var>-<var>addr2</var></code> from which the
> -              translated address should be selected.  If only one address is
> -              given, then that address will always be selected, otherwise the
> -              address selection can be informed by the optional persistent flag
> -              as described below.  Either IPv4 or IPv6 addresses can be provided,
> -              but both addresses must be of the same type, and the datapath
> -              behavior is undefined in case of providing IPv4 address range for
> -              an IPv6 packet, or IPv6 address range for an IPv4 packet.  IPv6
> -              addresses must be bracketed with <code>[</code> and <code>]</code>
> -              if a port range is also given.
> -            </dd>
> -
> -            <dt><var>ports</var></dt>
> -            <dd>
> -              The L4 <var>port</var> or range
> -              <code><var>port1</var>-<var>port2</var></code> from which the
> -              translated port should be selected. When a port range is
> -              specified, fallback to ephemeral ports does not happen, else,
> -              it will.  The port number selection can be informed by the
> -              optional <code>random</code> and <code>hash</code> flags
> -              described below.  The userspace datapath only supports the
> -              <code>hash</code> behavior.
> -            </dd>
> -          </dl>
> -
> -          <p>
> -            The optional flags are:
> -          </p>
> -
> -          <dl>
> -            <dt><code>random</code></dt>
> -            <dd>
> -              The selection of the port from the given range should be done using
> -              a fresh random number.  This flag is mutually exclusive with
> -              <code>hash</code>.
> -            </dd>
> -
> -            <dt><code>hash</code></dt>
> -            <dd>
> -              The selection of the port from the given range should be done using
> -              a datapath specific hash of the packet's IP addresses and the
> -              other, non-mapped port number.  This flag is mutually exclusive
> -              with <code>random</code>.
> -            </dd>
> -
> -            <dt><code>persistent</code></dt>
> -            <dd>
> -              The selection of the IP address from the given range should be done
> -              so that the same mapping can be provided after the system restarts.
> -            </dd>
> -          </dl>
> -
> -          <p>
> -            If <code>alg</code> is specified for the committing <code>ct</code>
> -            action that also includes <code>nat</code> with a <code>src</code> or
> -            <code>dst</code> attribute, then the datapath tries to set up the
> -            helper to be NAT-aware.  This functionality is datapath specific and
> -            may not be supported by all datapaths.
> -          </p>
> -
> -          <p>
> -            A ``bare'' <code>nat</code> argument with no options will only
> -            translate the packet being processed in the way the connection has been
> -            set up with an earlier, committed <code>ct</code> action.  A
> -            <code>nat</code> action with <code>src</code> or <code>dst</code>, when
> -            applied to a packet belonging to an established (rather than new)
> -            connection, will behave the same as a bare <code>nat</code>.
> -          </p>
> -
> -          <p>
> -            For SNAT, there is a special case when the <code>src</code> IP
> -            address is configured as all 0's, i.e.,
> -            <code>nat(src=0.0.0.0)</code>. In this case, when a source port
> -            collision is detected during the commit, the source port will be
> -            translated to an ephemeral port. If there is no collision, no SNAT
> -            is performed.
> -          </p>
> -
> -          <p>
> -            Open vSwitch 2.6 introduced <code>nat</code>.  Linux 4.6 was the
> -            earliest upstream kernel that implemented <code>ct</code> support for
> -            <code>nat</code>.
> -          </p>
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        With <code>commit</code>, the connection tracker commits the connection
> -        to the connection tracking module.  The <code>commit</code> flag should
> -        only be used from the pipeline within the first fork of <code>ct</code>
> -        without <code>commit</code>.  Information about the connection is
> -        stored beyond the lifetime of the packet in the pipeline.  Some
> -        <code>ct_state</code> flags are only available for committed
> -        connections.
> -      </p>
> -
> -      <p>
> -        The following options are available only with <code>commit</code>:
> -      </p>
> -
> -      <dl>
> -        <dt><code>force</code></dt>
> -        <dd>
> -          A committed connection always has the directionality of the packet
> -          that caused the connection to be committed in the first place.  This
> -          is the ``original direction'' of the connection, and the opposite
> -          direction is the ``reply direction''.  If a connection is already
> -          committed, but it is in the wrong direction, <code>force</code>
> -          effectively terminates the existing connection and starts a new one
> -          in the current direction.  This flag has no effect if the original
> -          direction of the connection is already the same as that of the
> -          current packet.
> -        </dd>
> -
> -        <dt><code>exec(<var>action</var></code>...<code>)</code></dt>
> -        <dd>
> -          <p>
> -            Perform each <var>action</var> within the context of connection
> -            tracking.  Only actions which modify the <code>ct_mark</code> or
> -            <code>ct_label</code> fields are accepted within <code>exec</code>
> -            action, and these fields may only be modified with this option. For
> -            example:
> -          </p>
> -
> -          <dl>
> -            <dt><code>set_field:<var>value</var>[/<var>mask</var>]->ct_mark</code></dt>
> -            <dd>
> -              Store a 32-bit metadata value with the connection.  Subsequent
> -              lookups for packets in this connection will populate
> -              <code>ct_mark</code> when the packet is sent to the connection
> -              tracker with the table specified.
> -            </dd>
> -
> -            <dt><code>set_field:<var>value</var>[/<var>mask</var>]->ct_label</code></dt>
> -            <dd>
> -              Store a 128-bit metadata value with the connection.  Subsequent
> -              lookups for packets in this connection will populate
> -              <code>ct_label</code> when the packet is sent to the connection
> -              tracker with the table specified.
> -            </dd>
> -          </dl>
> -        </dd>
> -
> -        <dt><code>alg=<var>alg</var></code></dt>
> -        <dd>
> -          <p>
> -            Specify application layer gateway <var>alg</var> to track specific
> -            connection types.  If subsequent related connections are sent
> -            through the <code>ct</code> action, then the <code>rel</code> flag
> -            in the <code>ct_state</code> field will be set.  Supported types
> -            include:
> -          </p>
> -
> -          <dl>
> -            <dt><code>ftp</code></dt>
> -            <dd>
> -              Look for negotiation of FTP data connections.  Specify this
> -              option for FTP control connections to detect related data
> -              connections and populate the <code>rel</code> flag for the data
> -              connections.
> -            </dd>
> -
> -            <dt><code>tftp</code></dt>
> -            <dd>
> -              <p>
> -                Look for negotiation of TFTP data connections.  Specify this
> -                option for TFTP control connections to detect related data
> -                connections and populate the <code>rel</code> flag for the data
> -                connections.
> -              </p>
> -            </dd>
> -          </dl>
> -
> -          <p>
> -            Related connections inherit <code>ct_mark</code> from that stored
> -            with the original connection (i.e. the connection created by
> -            <code>ct(alg=</code>...<code>)</code>).
> -          </p>
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        With the Linux datapath, global sysctl options affect <code>ct</code>
> -        behavior.  In particular, if
> -        <code>net.netfilter.nf_conntrack_helper</code> is enabled, which it is
> -        by default until Linux 4.7, then application layer gateway helpers may
> -        be executed even if <code>alg</code> is not specified.  For security
> -        reasons, the netfilter team recommends users disable this option.  For
> -        further details, please see <url
> -        href="https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.netfilter.org%2Fnews.html%232012-04-03%2522%2F&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=RAbg1eYmNUSY2AXlFt0AcBsKjRSNnmXPXeJP7sSOkj8%3D&reserved=0>.
> -      </p>
> -
> -      <p>
> -        The <code>ct</code> action may be used as a primitive to construct
> -        stateful firewalls by selectively committing some traffic, then
> -        matching <code>ct_state</code> to allow established connections while
> -        denying new connections.  The following flows provide an example of how
> -        to implement a simple firewall that allows new connections from port 1
> -        to port 2, and only allows established connections to send traffic from
> -        port 2 to port 1:
> -      </p>
> -
> -      <pre>
> -table=0,priority=1,action=drop
> -table=0,priority=10,arp,action=normal
> -table=0,priority=100,ip,ct_state=-trk,action=ct(table=1)
> -table=1,in_port=1,ip,ct_state=+trk+new,action=ct(commit),2
> -table=1,in_port=1,ip,ct_state=+trk+est,action=2
> -table=1,in_port=2,ip,ct_state=+trk+new,action=drop
> -table=1,in_port=2,ip,ct_state=+trk+est,action=1
> -      </pre>
> -
> -      <p>
> -        If <code>ct</code> is executed on IPv4 (or IPv6) fragments, then the
> -        message is implicitly reassembled before sending to the connection
> -        tracker and refragmented upon output, to the original maximum received
> -        fragment size.  Reassembly occurs within the context of the zone,
> -        meaning that IP fragments in different zones are not assembled
> -        together.  Pipeline processing for the initial fragments is halted.
> -        When the final fragment is received, the message is assembled and
> -        pipeline processing continues for that flow.  Packet ordering is not
> -        guaranteed by IP protocols, so it is not possible to determine which IP
> -        fragment will cause message reassembly (and therefore continue pipeline
> -        processing). As such, it is strongly recommended that multiple flows
> -        should not execute <code>ct</code> to reassemble fragments from the
> -        same IP message.
> -      </p>
> -
> -      <conformance>
> -        The <code>ct</code> action was introduced in Open vSwitch 2.5.  Some of
> -        its features were introduced later, noted individually above.
> -      </conformance>
> -    </action>
> -
> -    <action name="CT_CLEAR">
> -      <h2>The <code>ct_clear</code> action</h2>
> -      <syntax><code>ct_clear</code></syntax>
> -
> -      <p>
> -        Clears connection tracking state from the flow, zeroing
> -        <code>ct_state</code>, <code>ct_zone</code>, <code>ct_mark</code>, and
> -        <code>ct_label</code>.
> -      </p>
> -
> -      <p>
> -        This action was introduced in Open vSwitch 2.6.90.
> -      </p>
> -    </action>
> -
> -    <action name="LEARN">
> -      <h2>The <code>learn</code> action</h2>
> -      <syntax><code>learn(<var>argument</var></code>...<code>)</code></syntax>
> -
> -      <p>
> -        The <code>learn</code> action adds or modifies a flow in an OpenFlow
> -        table, similar to <code>ovs-ofctl --strict mod-flows</code>.  The
> -        arguments specify the match fields, actions, and other properties of
> -        the flow to be added or modified.
> -      </p>
> -
> -      <p>
> -        Match fields for the new flow are specified as follows.  At least one
> -        match field should ordinarily be specified:
> -      </p>
> -
> -      <dl>
> -        <dt><code><var>field</var>=<var>value</var></code></dt>
> -        <dd>
> -          <p>
> -            Specifies that <var>field</var>, in the new flow, must match the
> -            literal <var>value</var>, e.g. <code>dl_type=0x800</code>.
> -            Shorthand match syntax, such as <code>ip</code> in place of
> -            <code>dl_type=0x800</code>, is not supported.
> -          </p>
> -        </dd>
> -
> -        <dt><code><var>field</var>=<var>src</var></code></dt>
> -        <dd>
> -          <p>
> -            Specifies that <var>field</var> in the new flow must match
> -            <var>src</var> taken from the packet currently being processed.
> -            For example, <code>udp_dst=udp_src</code>, applied to a UDP packet
> -            with source port 53, creates a flow which matches
> -            <code>udp_dst=53</code>.  <var>field</var> and <var>src</var> must
> -            have the same width.
> -          </p>
> -        </dd>
> -
> -        <dt><code><var>field</var></code></dt>
> -        <dd>
> -          Shorthand for the previous form when <var>field</var> and
> -          <var>src</var> are the same.  For example, <code>udp_dst</code>,
> -          applied to a UDP packet with destination port 53, creates a flow
> -          which matches <code>udp_dst=53</code>.
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        The <var>field</var> and <var>src</var> arguments above should be
> -        fields or subfields in the syntax described under ``Field
> -        Specifications'' above.
> -      </p>
> -
> -      <p>
> -        Match field specifications must honor prerequisites for both the flow
> -        with the <code>learn</code> and the new flow that it creates.  Consider
> -        the following complete flow, in the syntax accepted by
> -        <code>ovs-ofctl</code>.  If the flow's match on <code>udp</code> were
> -        omitted, then the flow would not satisfy the prerequisites for the
> -        <code>learn</code> action's use of <code>udp_src</code>.  If
> -        <code>dl_type=0x800</code> or <code>nw_proto</code> were omitted from
> -        <code>learn</code>, then the new flow would not satisfy the
> -        prerequisite for its match on <code>udp_dst</code>.  For more
> -        information on prerequisites, please refer to
> -        <code>ovs-fields</code>(7):
> -      </p>
> -
> -      <pre>
> -        udp, actions=learn(dl_type=0x800, nw_proto=17, udp_dst=udp_src)
> -      </pre>
> -
> -      <p>
> -        Actions for the new flow are specified as follows.  At least one action
> -        should ordinarily be specified:
> -      </p>
> -
> -      <dl>
> -        <dt><code>load:<var>value</var>-><var>dst</var></code></dt>
> -        <dd>
> -          Adds a <code>load</code> action to the new flow that loads the
> -          literal <var>value</var> into <var>dst</var>.  The syntax is the same
> -          as the <code>load</code> action explained in the ``Header
> -          Modification'' section.
> -        </dd>
> -
> -        <dt><code>load:<var>src</var>-><var>dst</var></code></dt>
> -        <dd>
> -          Adds a <code>load</code> action to the new flow that loads
> -          <var>src</var>, a field or subfield from the packet being processed,
> -          into <var>dst</var>.
> -        </dd>
> -
> -        <dt><code>output:<var>field</var></code></dt>
> -        <dd>
> -          Adds an <code>output</code> action to the new flow's actions that
> -          outputs to the OpenFlow port taken from <var>field</var>, which must
> -          be a field as described above.
> -        </dd>
> -
> -        <dt><code>fin_idle_timeout=<var>seconds</var></code></dt>
> -        <dt><code>fin_hard_timeout=<var>seconds</var></code></dt>
> -        <dd>
> -          Adds a <code>fin_timeout</code> action with the specified arguments
> -          to the new flow.  This feature was added in Open vSwitch 1.5.90.
> -        </dd>
> -      </dl>
> -
> -      The following additional arguments are optional:
> -
> -      <dl>
> -        <dt><code>idle_timeout=<var>seconds</var></code></dt>
> -        <dt><code>hard_timeout=<var>seconds</var></code></dt>
> -        <dt><code>priority=<var>value</var></code></dt>
> -        <dt><code>cookie=<var>value</var></code></dt>
> -        <dt><code>send_flow_rem</code></dt>
> -        <dd>
> -          These arguments have the same meaning as in the usual flow syntax
> -          documented in <code>ovs-ofctl</code>(8).
> -        </dd>
> -
> -        <dt><code>table=<var>table</var></code></dt>
> -        <dd>
> -          The table in which the new flow should be inserted.  Specify a
> -          decimal number between 0 and 254 inclusive or the name of a table.
> -          The default, if table is unspecified, is table 1 (not 0).
> -        </dd>
> -
> -        <dt><code>delete_learned</code></dt>
> -        <dd>
> -          <p>
> -            When this flag is specified, deleting the flow that contains the
> -            <code>learn</code> action will also delete the flows created by
> -            <code>learn</code>.  Specifically, when the last <code>learn</code>
> -            action with this flag and particular <code>table</code> and
> -            <code>cookie</code> values is removed, the switch deletes all of
> -            the flows in the specified table with the specified cookie.
> -          </p>
> -
> -          <p>
> -            This flag was added in Open vSwitch 2.4.
> -          </p>
> -        </dd>
> -
> -        <dt><code>limit=<var>number</var></code></dt>
> -        <dd>
> -          <p>
> -            If the number of flows in the new flow's table with the same cookie
> -            exceeds <code>number</code>, the action will not add a new flow.
> -            By default, or with <code>limit=0</code>, there is no limit.
> -          </p>
> -
> -          <p>
> -            This flag was added in Open vSwitch 2.8.
> -          </p>
> -        </dd>
> -
> -        <dt><code>result_dst=<var>field</var>[<var>bit</var>]</code></dt>
> -        <dd>
> -          <p>
> -            If learn fails (because the number of flows exceeds
> -            <code>limit</code>), the action sets
> -            <code><var>field</var>[<var>bit</var>]</code> to 0, otherwise it
> -            will be set to 1.  <code>field[bit]</code> must be a single bit.
> -          </p>
> -
> -          <p>
> -            This flag was added in Open vSwitch 2.8.
> -          </p>
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        By itself, the <code>learn</code> action can only put two kinds of
> -        actions into the flows that it creates: <code>load</code> and
> -        <code>output</code> actions.  If <code>learn</code> is used in
> -        isolation, these are severe limits.
> -      </p>
> -
> -      <p>
> -        However, <code>learn</code> is not meant to be used in isolation.  It
> -        is a primitive meant to be used together with other Open vSwitch
> -        features to accomplish a task.  Its existing features are enough to
> -        accomplish most tasks.
> -      </p>
> -
> -      <p>
> -        Here is an outline of a typical pipeline structure that allows for
> -        versatile behavior using <code>learn</code>:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          Flows in table <var>A</var> contain a <code>learn</code> action, that
> -          populates flows in table <var>L</var>, that use a <code>load</code>
> -          action to populate register <var>R</var> with information about what
> -          was learned.
> -        </li>
> -
> -        <li>
> -          Flows in table <var>B</var> contain two sequential resubmit actions:
> -          one to table <var>L</var> and another one to table <var>B</var>+1.
> -        </li>
> -
> -        <li>
> -          Flows in table <var>B</var>+1 match on register <var>R</var> and act
> -          differently depending on what the flows in table <var>L</var> loaded
> -          into it.
> -        </li>
> -      </ul>
> -
> -      <p>
> -        This approach can be used to implement many <code>learn</code>-based
> -        features.  For example:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          Resubmit to a table selected based on learned information, e.g. see
> -          <url href="https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.openvswitch.org%2Fpipermail%2Fovs-discuss%2F2016-June%2F021694.html%2522%2F&data=04%7C01%7Croid%40nvidia.com%7Cf92725006bb44426a04108d95935933b%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0%7C637638910859768354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=029qisAy0QhewCzpSHMxfcrugyqM%2BTtSKlAgnJOm5zM%3D&reserved=0>.
> -        </li>
> -
> -        <li>
> -          MAC learning in the middle of a pipeline, as described in the ``Open
> -          vSwitch Advanced Features Tutorial'' in the OVS documentation.
> -        </li>
> -
> -        <li>
> -          TCP state based firewalling, by learning outgoing connections based
> -          on SYN packets and matching them up with incoming packets.  (This is
> -          usually better implemented using the <code>ct</code> action.)
> -        </li>
> -
> -        <li>
> -          At least some of the features described in T. A. Hoff, ``Extending
> -          Open vSwitch to Facilitate Creation of Stateful SDN Applications''.
> -        </li>
> -      </ul>
> -
> -      <conformance>
> -        The <code>learn</code> action is an Open vSwitch extension to OpenFlow
> -        added in Open vSwitch 1.3.  Some features of <code>learn</code> were
> -        added in later versions, as noted individually above.
> -      </conformance>
> -    </action>
> -
> -    <action name="FIN_TIMEOUT">
> -      <h2>The <code>fin_timeout</code> action</h2>
> -      <syntax><code>fin_timeout(<var>key</var>=<var>value</var></code>...<code>)</code></syntax>
> -
> -      <p>
> -        This action changes the idle timeout or hard timeout, or both, of the
> -        OpenFlow flow that contains it, when the flow matches a TCP packet with
> -        the FIN or RST flag.  When such a packet is observed, the action
> -        reduces the rule's timeouts to those specified on the action.  If the
> -        rule's existing timeout is already shorter than the one that the action
> -        specifies, then that timeout is unaffected.
> -      </p>
> -
> -      <p>
> -        The timeouts are specified as key-value pairs:
> -      </p>
> -
> -      <dl>
> -        <dt><code>idle_timeout=</code><var>seconds</var></dt>
> -        <dd>
> -          Causes the flow to expire after the given number of seconds of
> -          inactivity.
> -        </dd>
> -
> -        <dt><code>hard_timeout=</code><var>seconds</var></dt>
> -        <dd>
> -          Causes the flow to expire after the given number of
> -          <var>seconds</var>, regardless of activity.  (<var>seconds</var>
> -          specifies time since the flow's creation, not since the receipt of
> -          the FIN or RST.)
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        This action is normally added to a learned flow by the
> -        <code>learn</code> action.  It is unlikely to be useful otherwise.
> -      </p>
> -
> -      <conformance>
> -        This Open vSwitch extension action was added in Open vSwitch 1.5.90.
> -      </conformance>
> -    </action>
> -  </group>
> -
> -  <group title="Programming and Control Flow Actions">
> -    <action name="RESUBMIT">
> -      <h2>The <code>resubmit</code> action</h2>
> -      <syntax><code>resubmit:<var>port</var></code></syntax>
> -      <syntax><code>resubmit(</code>[<code><var>port</var></code>]<code>,</code>[<code><var>table</var></code>][<code>,ct</code>]<code>)</code></syntax>
> -
> -      <p>
> -        Searches an OpenFlow flow table for a matching flow and executes the
> -        actions found, if any, before continuing to the following action in the
> -        current flow entry.  Arguments can customize the search:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          If <var>port</var> is given as an OpenFlow port number or name, then
> -          it specifies a value to use for the input port metadata field as part
> -          of the search, in place of the input port currently in the flow.
> -          Specifying <code>in_port</code> as <var>port</var> is equivalent to
> -          omitting it.
> -        </li>
> -
> -        <li>
> -          If <var>table</var> is given as an integer between 0 and 254 or a
> -          table name, it specifies the OpenFlow table to search.  If it is not
> -          specified, the table from the current flow is used.
> -        </li>
> -
> -        <li>
> -          <p>
> -            If <code>ct</code> is specified, then the search is done with
> -            packet 5-tuple fields swapped with the corresponding conntrack
> -            original direction tuple fields.  See the documentation for
> -            <code>ct</code> above, for more information about connection
> -            tracking, or <code>ovs-fields</code>(7) for details about the
> -            connection tracking fields.
> -          </p>
> -
> -          <p>
> -            This flag requires a valid connection tracking state as a match
> -            prerequisite in the flow where this action is placed.  Examples of
> -            valid connection tracking state matches include
> -            <code>ct_state=+new</code>, <code>ct_state=+est</code>,
> -            <code>ct_state=+rel</code>, and <code>ct_state=+trk-inv</code>.
> -          </p>
> -        </li>
> -      </ul>
> -
> -      <p>
> -        The changes, if any, to the input port and connection tracking fields
> -        are just for searching the flow table.  The changes are not visible to
> -        actions or to later flow table lookups.
> -      </p>
> -
> -      <p>
> -        The most common use of <code>resubmit</code> is to visit another flow
> -        table without <var>port</var> or <code>ct</code>, like this:
> -        <code>resubmit(,<var>table</var>)</code>.
> -      </p>
> -
> -      <p>
> -        Recursive <code>resubmit</code> actions are permitted.
> -      </p>
> -
> -      <conformance>
> -        <p>
> -          The <code>resubmit</code> action is an Open vSwitch extension.
> -          However, the <code>goto_table</code> instruction in OpenFlow 1.1 and
> -          later can be viewed as a kind of restricted <code>resubmit</code>.
> -        </p>
> -
> -        <p>
> -          Open vSwitch 1.2.90 added <var>table</var>.  Open vSwitch 2.7 added
> -          <code>ct</code>.
> -        </p>
> -
> -        <p>
> -          Open vSwitch imposes a limit on <code>resubmit</code> recursion that
> -          varies among version:
> -        </p>
> -
> -        <ul>
> -          <li>
> -            Open vSwitch 1.0.1 and earlier did not support recursion.
> -          </li>
> -
> -          <li>
> -            Open vSwitch 1.0.2 and 1.0.3 limited recursion to 8 levels.
> -          </li>
> -
> -          <li>
> -            Open vSwitch 1.1 and 1.2 limited recursion to 16 levels.
> -          </li>
> -
> -          <li>
> -            Open vSwitch 1.2 through 1.8 limited recursion to 32 levels.
> -          </li>
> -
> -          <li>
> -            Open vSwitch 1.9 through 2.0 limited recursion to 64 levels.
> -          </li>
> -
> -          <li>
> -            Open vSwitch 2.1 through 2.5 limited recursion to 64 levels and
> -            impose a total limit of 4,096 resubmits per flow translation
> -            (earlier versions did not impose any total limit).
> -          </li>
> -
> -          <li>
> -            Open vSwitch 2.6 and later imposes the same limits as 2.5, with one
> -            exception: resubmit from table <var>x</var> to any table
> -            <var>y</var> > <var>x</var> does not count against the recursion
> -            depth limit.
> -          </li>
> -        </ul>
> -      </conformance>
> -    </action>
> -
> -    <action name="CLONE">
> -      <h2>The <code>clone</code> action</h2>
> -      <syntax><code>clone(<var>action</var>...)</code></syntax>
> -
> -      <p>
> -         Executes each nested <var>action</var>, saving much of the packet and
> -         pipeline state beforehand and then restoring it afterward.  The state
> -         that is saved and restored includes all flow data and metadata
> -         (including, for example, <code>in_port</code> and
> -         <code>ct_state</code>), the stack accessed by <code>push</code> and
> -         <code>pop</code> actions, and the OpenFlow action set.
> -      </p>
> -
> -      <p>
> -        This action was added in Open vSwitch 2.6.90.
> -      </p>
> -    </action>
> -
> -    <action name="STACK_PUSH, STACK_POP">
> -      <h2>The <code>push</code> and <code>pop</code> actions</h2>
> -      <syntax><code>push:<var>src</var></code></syntax>
> -      <syntax><code>pop:<var>dst</var></code></syntax>
> -      <p>
> -        The <code>push</code> action pushes <var>src</var> on a general-purpose
> -        stack.  The <code>pop</code> action pops an entry off the stack into
> -        <var>dst</var>.  <var>src</var> and <var>dst</var> should be fields or
> -        subfields in the syntax described under ``Field Specifications'' above.
> -      </p>
> -
> -      <p>
> -        Controllers can use the stack for saving and restoring data or metadata
> -        around <code>resubmit</code> actions, for swapping or rearranging data
> -        and metadata, or for other purposes.  Any data or metadata field, or
> -        part of one, may be pushed, and any modifiable field or subfield may be
> -        popped.
> -      </p>
> -
> -      <p>
> -        The number of bits pushed in a stack entry do not have to match the
> -        number of bits later popped from that entry.  If more bits are popped
> -        from an entry than were pushed, then the entry is conceptually
> -        left-padded with 0-bits as needed.  If fewer bits are popped than
> -        pushed, then bits are conceptually trimmed from the left side of the
> -        entry.
> -      </p>
> -
> -      <p>
> -        The stack's size is limited.  The limit is intended to be high enough
> -        that ``normal'' use will not pose problems.  Stack overflow or
> -        underflow is an error that stops action execution (see ``Stack too
> -        deep'' under ``Error Handling'', above).
> -      </p>
> -
> -      <p>
> -        Examples:
> -      </p>
> -
> -      <ul>
> -        <li>
> -          <code>push:reg2[0..5]</code> or <code>push:NXM_NX_REG2[0..5]</code>
> -          pushes on the stack the 6 bits in register 2 bits 0 through 5.
> -        </li>
> -
> -        <li>
> -          <code>pop:reg2[0..5]</code> or <code>pop:NXM_NX_REG2[0..5]</code>
> -          pops the value from top of the stack and copy bits 0 through 5 of
> -          that value into bits 0 through 5 of register 2.
> -        </li>
> -      </ul>
> -
> -      <conformance>
> -        Open vSwitch 1.2 introduced <code>push</code> and <code>pop</code> as
> -        OpenFlow extension actions.
> -      </conformance>
> -    </action>
> -
> -    <action name="EXIT">
> -      <h2>The <code>exit</code> action</h2>
> -      <syntax><code>exit</code></syntax>
> -
> -      <p>
> -        This action causes Open vSwitch to immediately halt execution of
> -        further actions.  Actions which have already been executed are
> -        unaffected.  Any further actions, including those which may be in other
> -        tables, or different levels of the <code>resubmit</code> call stack,
> -        are ignored.  However, an <code>exit</code> action within a group
> -        bucket terminates only execution of that bucket, not other buckets or
> -        the overall pipeline.  Actions in the action set are still executed
> -        (specify <code>clear_actions</code> before <code>exit</code> to discard
> -        them).
> -      </p>
> -    </action>
> -
> -    <action name="MULTIPATH">
> -      <h2>The <code>multipath</code> action</h2>
> -      <syntax><code>multipath(<var>fields</var>, <var>basis</var>, <var>algorithm</var>, <var>n_links</var>, <var>arg</var>, <var>dst</var>)</code></syntax>
> -
> -      <p>
> -        Hashes <var>fields</var> using <var>basis</var> as a universal hash
> -        parameter, then the applies multipath link selection
> -        <var>algorithm</var> (with parameter <var>arg</var>) to choose one of
> -        <var>n_links</var> output links numbered 0 through <var>n_links</var>
> -        minus 1, and stores the link into <var>dst</var>, which must be a field
> -        or subfield in the syntax described under ``Field Specifications''
> -        above.
> -      </p>
> -
> -      <p>
> -        The <code>bundle</code> or <code>bundle_load</code> actions are usually
> -        easier to use than <code>multipath</code>.
> -      </p>
> -
> -      <p>
> -        <var>fields</var> must be one of the following:
> -      </p>
> -
> -      <dl>
> -        <dt><code>eth_src</code></dt>
> -        <dd>
> -          Hashes Ethernet source address only.
> -        </dd>
> -
> -        <dt><code>symmetric_l4</code></dt>
> -        <dd>
> -          Hashes Ethernet source, destination, and type, VLAN ID, IPv4/IPv6
> -          source, destination, and protocol, and TCP or SCTP (but not UDP)
> -          ports.  The hash is computed so that pairs of corresponding flows in
> -          each direction hash to the same value, in environments where L2 paths
> -          are the same in each direction.  UDP ports are not included in the
> -          hash to support protocols such as VXLAN that use asymmetric ports
> -          in each direction.
> -        </dd>
> -
> -        <dt><code>symmetric_l3l4</code></dt>
> -        <dd>
> -          Hashes IPv4/IPv6 source, destination, and protocol, and TCP or SCTP
> -          (but not UDP) ports.  Like <code>symmetric_l4</code>, this is a
> -          symmetric hash, but by excluding L2 headers it is more effective in
> -          environments with asymmetric L2 paths (e.g. paths involving VRRP IP
> -          addresses on a router).  Not an effective hash function for protocols
> -          other than IPv4 and IPv6, which hash to a constant zero.
> -        </dd>
> -
> -        <dt><code>symmetric_l3l4+udp</code></dt>
> -        <dd>
> -          Like <code>symmetric_l3l4+udp</code>, but UDP ports are included in
> -          the hash.  This is a more effective hash when asymmetric UDP
> -          protocols such as VXLAN are not a consideration.
> -        </dd>
> -
> -        <dt><code>symmetric_l3</code></dt>
> -        <dd>
> -          Hashes network source address and network destination address.
> -        </dd>
> -
> -        <dt><code>nw_src</code></dt>
> -        <dd>
> -          Hashes network source address only.
> -        </dd>
> -
> -        <dt><code>nw_dst</code></dt>
> -        <dd>
> -          Hashes network destination address only.
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        The <var>algorithm</var> used to compute the final result
> -        <var>link</var> must be one of the following:
> -      </p>
> -
> -      <dl>
> -        <dt><code>modulo_n</code></dt>
> -        <dd>
> -          <p>
> -            Computes <var>link</var> = hash(<var>flow</var>) % <var>n_links</var>.
> -          </p>
> -
> -          <p>
> -            This algorithm redistributes all traffic when <var>n_links</var>
> -            changes.  It has <i>O(1)</i> performance.
> -          </p>
> -
> -          <p>
> -            Use 65535 for <var>max_link</var> to get a raw hash value.
> -          </p>
> -
> -          <p>
> -            This algorithm is specified by RFC 2992.
> -          </p>
> -        </dd>
> -
> -        <dt><code>hash_threshold</code></dt>
> -        <dd>
> -          <p>
> -            Computes <var>link</var> = hash(<var>flow</var>) / (<code>MAX_HASH</code> / <var>n_links</var>).
> -          </p>
> -
> -          <p>
> -            Redistributes between one-quarter and one-half of traffic when
> -            n_links changes.  It has <i>O(1)</i> performance.
> -          </p>
> -
> -          <p>
> -            This algorithm is specified by RFC 2992.
> -          </p>
> -        </dd>
> -
> -        <dt><code>hrw</code> (Highest Random Weight)</dt>
> -        <dd>
> -          <p>
> -            Computes the following:
> -          </p>
> -
> -          <pre>
> -for <var>i</var> in [0,<var>n_links</var>]:
> -    <var>weights</var>[<var>i</var>] = hash(<var>flow</var>, <var>i</var>)
> -<var>link</var> = { <var>i</var> such that <var>weights</var>[<var>i</var>] >= <var>weights</var>[<var>j</var>] for all <var>j</var> != <var>i</var> }
> -          </pre>
> -
> -          <p>
> -            Redistributes 1/<var>n_links</var> of traffic when
> -            <var>n_links</var> changes.  It has <i>O(<var>n_links</var>)</i>
> -            performance.  If <var>n_links</var> is greater than a threshold
> -            (currently 64, but subject to change), Open vSwitch will substitute
> -            another algorithm automatically.
> -          </p>
> -
> -          <p>
> -            This algorithm is specified by RFC 2992.
> -          </p>
> -        </dd>
> -
> -        <dt><code>iter_hash</code> (Iterative Hash)</dt>
> -        <dd>
> -          <p>
> -            Computes the following:
> -          </p>
> -
> -          <pre>
> -<var>i</var> = 0
> -repeat:
> -    <var>i</var> = <var>i</var> + 1
> -    <var>link</var> = hash(<var>flow</var>, <var>i</var>) % <var>arg</var>
> -while <var>link</var> > <var>max_link</var>
> -          </pre>
> -
> -          <p>
> -            Redistributes 1/<var>n_links</var> of traffic when
> -            <var>n_links</var> changes.  O(1) performance when
> -            <var>arg</var>/<var>max_link</var> is bounded by a constant.
> -          </p>
> -
> -          <p>
> -             Redistributes all traffic when <var>arg</var> changes.
> -          </p>
> -
> -          <p>
> -            <var>arg</var> must be greater than <var>max_link</var> and for
> -            best performance should be no more than approximately
> -            <var>max_link</var> * 2.  If <var>arg</var> is outside the
> -            acceptable range, Open vSwitch will automatically substitute the
> -            least power of 2 greater than <var>max_link</var>.
> -          </p>
> -
> -          <p>
> -            This algorithm is specific to Open vSwitch.
> -          </p>
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        Only the <code>iter_hash</code> algorithm uses <var>arg</var>.
> -      </p>
> -
> -      <p>
> -        It is an error if <var>max_link</var> is greater than or equal to
> -        2**<var>n_bits</var>.
> -      </p>
> -
> -      <conformance>
> -        This is an OpenFlow extension added in Open vSwitch 1.1.
> -      </conformance>
> -    </action>
> -  </group>
> -
> -  <group title="Other Actions">
> -    <action name="CONJUNCTION">
> -      <h2>The <code>conjunction</code> action</h2>
> -      <syntax><code>conjunction(<var>id</var>, <var>k</var>/<var>n</var>)</code></syntax>
> -
> -      <p>
> -        This action allows for sophisticated ``conjunctive match'' flows.
> -        Refer to ``Conjunctive Match Fields'' in <code>ovs-fields</code>(7) for
> -        details.
> -      </p>
> -
> -      <p>
> -        A flow that has one or more <code>conjunction</code> actions may not
> -        have any other actions except for <code>note</code> actions.
> -      </p>
> -
> -      <conformance>
> -        Open vSwitch 2.4 introduced the <code>conjunction</code> action and
> -        <code>conj_id</code> field.  They are Open vSwitch extensions to
> -        OpenFlow.
> -      </conformance>
> -    </action>
> -
> -    <action name="NOTE">
> -      <h2>The <code>note</code> action</h2>
> -      <syntax><code>note:</code>[<var>hh</var>]...</syntax>
> -
> -      <p>
> -        This action does nothing at all.  OpenFlow controllers may use it to
> -        annotate flows with more data than can fit in a flow cookie.
> -      </p>
> -
> -      <p>
> -        The action may include any number of bytes represented as hex digits
> -        <var>hh</var>.  Periods may separate pairs of hex digits, for
> -        readability.  The <code>note</code> action's format doesn't include an
> -        exact length for its payload, so the provided bytes will be padded on
> -        the right by enough bytes with value 0 to make the total number 6 more
> -        than a multiple of 8.
> -      </p>
> -
> -      <p>
> -
> -      </p>
> -
> -      <conformance>
> -        This action is an extension to OpenFlow introduced in Open vSwitch 1.1.
> -      </conformance>
> -    </action>
> -
> -    <action name="SAMPLE">
> -      <h2>The <code>sample</code> action</h2>
> -      <syntax><code>sample(<var>argument</var>...)</code></syntax>
> -
> -      <p>
> -        Samples packets and sends one sample for every sampled packet.
> -      </p>
> -
> -      <p>
> -        The following <var>argument</var> forms are accepted:
> -      </p>
> -
> -      <dl>
> -        <dt><code>probability=<var>packets</var></code></dt>
> -        <dd>
> -          The number of sampled packets out of 65535.  Must be greater or equal
> -          to 1.
> -        </dd>
> -
> -        <dt><code>collector_set_id=<var>id</var></code></dt>
> -        <dd>
> -          The unsigned 32-bit integer identifier of the set of sample
> -          collectors to send sampled packets to.  Defaults to 0.
> -        </dd>
> -
> -        <dt><code>obs_domain_id=<var>id</var></code></dt>
> -        <dd>
> -          When sending samples to IPFIX collectors, the unsigned 32-bit integer
> -          Observation Domain ID sent in every IPFIX flow record.  Defaults to
> -          0.
> -        </dd>
> -
> -        <dt><code>obs_point_id=<var>id</var></code></dt>
> -        <dd>
> -          When sending samples to IPFIX collectors, the unsigned 32-bit integer
> -          Observation Point ID sent in every IPFIX flow record.  Defaults to 0.
> -        </dd>
> -
> -        <dt><code>sampling_port=<var>port</var></code></dt>
> -        <dd>
> -          Sample packets on <var>port</var>, which should be the ingress or
> -          egress port.  This option, which was added in Open vSwitch 2.5.90,
> -          allows the IPFIX implementation to export egress tunnel information.
> -        </dd>
> -
> -        <dt><code>ingress</code></dt>
> -        <dt><code>egress</code></dt>
> -        <dd>
> -          Specifies explicitly that the packet is being sampled on ingress to
> -          or egress from the switch.  IPFIX reports sent by Open vSwitch before
> -          version 2.5.90 did not include a direction.  From 2.5.90 until
> -          2.6.90, IPFIX reports inferred a direction from
> -          <var>sampling_port</var>: if it was the packet's output port, then
> -          the direction was reported as egress, otherwise as ingress.  Open
> -          vSwitch 2.6.90 introduced these options, which allow the inferred
> -          direction to be overridden.  This is particularly useful when the
> -          ingress (or egress) port is not a tunnel.
> -        </dd>
> -      </dl>
> -
> -      <p>
> -        Refer to <code>ovs-vswitchd.conf.db</code>(5) for more details on
> -        configuring sample collector sets.
> -      </p>
> -
> -      <conformance>
> -        This action is an OpenFlow extension added in Open vSwitch 2.4.
> -      </conformance>
> -    </action>
> -  </group>
> -
> -  <group title="Instructions">
> -    <p>
> -      Every version of OpenFlow includes actions.  OpenFlow 1.1 introduced the
> -      higher-level, related concept of <dfn>instructions</dfn>.  In OpenFlow
> -      1.1 and later, actions within a flow are always encapsulated within an
> -      instruction.  Each flow has at most one instruction of each kind, which
> -      are executed in the following fixed order defined in the OpenFlow
> -      specification:
> -    </p>
> -
> -    <ol>
> -      <li><code>Meter</code></li>
> -      <li><code>Apply-Actions</code></li>
> -      <li><code>Clear-Actions</code></li>
> -      <li><code>Write-Actions</code></li>
> -      <li><code>Write-Metadata</code></li>
> -      <li><code>Stat-Trigger</code> (not supported by Open vSwitch)</li>
> -      <li><code>Goto-Table</code></li>
> -    </ol>
> -
> -    <p>
> -      The most important instruction is <code>Apply-Actions</code>.  This
> -      instruction encapsulates any number of actions, which the instruction
> -      executes.  Open vSwitch does not explicitly represent
> -      <code>Apply-Actions</code>.  Instead, any action by itself is implicitly
> -      part of an <code>Apply-Actions</code> instructions.
> -    </p>
> -
> -    <p>
> -      Open vSwitch syntax requires other instructions, if present, to be in the
> -      order listed above.  Otherwise it will flag an error.
> -    </p>
> -
> -    <action name="METER">
> -      <h2>The <code>meter</code> action and instruction</h2>
> -      <syntax><code>meter:<var>meter_id</var></code></syntax>
> -
> -      <p>
> -        Apply meter <var>meter_id</var>.  If a meter band rate is exceeded, the
> -        packet may be dropped, or modified, depending on the meter band type.
> -      </p>
> -
> -      <conformance>
> -        <p>
> -          OpenFlow 1.3 introduced the <code>meter</code> instruction.  OpenFlow
> -          1.5 changes <code>meter</code> from an instruction to an action.
> -        </p>
> -
> -        <p>
> -          OpenFlow 1.5 allows implementations to restrict <code>meter</code> to
> -          be the first action in an action list and to exclude
> -          <code>meter</code> from action sets, for better compatibility with
> -          OpenFlow 1.3 and 1.4.  Open vSwitch restricts the <code>meter</code>
> -          action both ways.
> -        </p>
> -
> -        <p>
> -          Open vSwitch 2.0 introduced OpenFlow protocol support for meters, but
> -          it did not include a datapath implementation.  Open vSwitch 2.7 added
> -          meter support to the userspace datapath.  Open vSwitch 2.10 added
> -          meter support to the kernel datapath.  Open vSwitch 2.12 added
> -          support for meter as an action in OpenFlow 1.5.
> -        </p>
> -      </conformance>
> -    </action>
> -
> -    <action name="CLEAR_ACTIONS">
> -      <h2>The <code>clear_actions</code> instruction</h2>
> -      <syntax><code>clear_actions</code></syntax>
> -
> -      <p>
> -        Clears the action set.  See ``Action Sets'', above, for more
> -        information.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.1 introduced <code>clear_actions</code>.  Open vSwitch 2.1
> -        added support for <code>clear_actions</code>.
> -      </conformance>
> -    </action>
> -
> -    <action name="WRITE_ACTIONS">
> -      <h2>The <code>write_actions</code> instruction</h2>
> -      <syntax><code>write_actions(<var>action</var></code>...<code>)</code></syntax>
> -
> -      <p>
> -        Adds each <var>action</var> to the action set.  The action set is
> -        carried between flow tables and then executed at the end of the
> -        pipeline.  Only certain actions may be written to the action set.  See
> -        ``Action Sets'', above, for more information.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.1 introduced <code>write_actions</code>.  Open vSwitch 2.1
> -        added support for <code>write_actions</code>.
> -      </conformance>
> -    </action>
> -
> -    <action name="WRITE_METADATA">
> -      <h2>The <code>write_metadata</code> instruction</h2>
> -      <syntax><code>write_metadata:<var>value</var></code>[<code>/<var>mask</var></code>]</syntax>
> -
> -      <p>
> -        Updates the flow's <code>metadata</code> field.  If <var>mask</var> is
> -        omitted, <code>metadata</code> is set exactly to <var>value</var>; if
> -        <var>mask</var> is specified, then a 1-bit in <var>mask</var> indicates
> -        that the corresponding bit in <code>metadata</code> will be replaced
> -        with the corresponding bit from <var>value</var>.  Both
> -        <var>value</var> and <var>mask</var> are 64-bit values that are decimal
> -        by default; use a <code>0x</code> prefix to specify them in
> -        hexadecimal.
> -      </p>
> -
> -      <p>
> -        The <code>metadata</code> field can also be matched in the flow table
> -        and updated with actions such as <code>set_field</code> and
> -        <code>move</code>.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.1 introduced <code>write_metadata</code>.  Open vSwitch 2.1
> -        added support for <code>write_metadata</code>.
> -      </conformance>
> -    </action>
> -
> -    <action name="GOTO_TABLE">
> -      <h2>The <code>goto_table</code> instruction</h2>
> -      <syntax><code>goto_table:<var>table</var></code></syntax>
> -
> -      <p>
> -        Jumps to <var>table</var> as the next table in the process pipeline.
> -        The table may be a number between 0 and 254 or a table name.
> -      </p>
> -
> -      <p>
> -        It is an error if <var>table</var> is less than or equal to the table
> -        of the flow that contains it; that is, <code>goto_table</code> must
> -        move forward in the OpenFlow pipeline.  Since <code>goto_table</code>
> -        must be the last instruction in a flow, it never leads to recursion.
> -        The <code>resubmit</code> extension action is more flexible.
> -      </p>
> -
> -      <conformance>
> -        OpenFlow 1.1 introduced <code>goto_table</code>.  Open vSwitch 2.1
> -        added support for <code>goto_table</code>.
> -      </conformance>
> -    </action>
> -  </group>
> -</actions>
> 

I tested the patch and generated man and html pages.
as for the warning from the bot about ovs-actions.7 not in
automake.mk, looks like an issue in checkpatch.py.

Acked-by: Roi Dayan <roid at nvidia.com>


More information about the dev mailing list