diff options
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/automake.mk | 1 | ||||
-rw-r--r-- | Documentation/conf.py | 4 | ||||
-rw-r--r-- | Documentation/ref/index.rst | 5 | ||||
-rw-r--r-- | Documentation/ref/ovs-actions.7.rst | 2332 |
4 files changed, 2337 insertions, 5 deletions
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) <http://www.openvswitch.org/support/dist-docs/ovs-actions.7.pdf>`__ - - `(html) <http://www.openvswitch.org/support/dist-docs/ovs-actions.7.html>`__ - - `(plain text) <http://www.openvswitch.org/support/dist-docs/ovs-actions.7.txt>`__ * - ovs-bugtool(8) - `(pdf) <http://www.openvswitch.org/support/dist-docs/ovs-bugtool.8.pdf>`__ - `(html) <http://www.openvswitch.org/support/dist-docs/ovs-bugtool.8.html>`__ 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 + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + License for the specific language governing permissions and limitations + under the License. + + 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://mailman.stanford.edu/pipermail/openflow-spec/2009-August/000394.html + +**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 +http://www.netfilter.org/news.html#2012-04-03 . + +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://mail.openvswitch.org/pipermail/ovs-discuss/2016-June/021694.html . + + - 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``. |