[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