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:
1. strip_vlan
2. pop_mpls
3. decap
4. encap
5. push_mpls
6. push_vlan
7. dec_ttl
8. dec_mpls_ttl
9. dec_nsh_ttl
10. 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
11. set_queue
12. 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)