+Asynchronous Messages
+=====================
+
+Over time, Open vSwitch has added many knobs that control whether a
+given controller receives OpenFlow asynchronous messages. This
+section describes how all of these features interact.
+
+First, a service controller never receives any asynchronous messages
+unless it changes its miss_send_len from the service controller
+default of zero in one of the following ways:
+
+ - Sending an OFPT_SET_CONFIG message with nonzero miss_send_len.
+
+ - Sending any NXT_SET_ASYNC_CONFIG message: as a side effect, this
+ message changes the miss_send_len to
+ OFP_DEFAULT_MISS_SEND_LEN (128) for service controllers.
+
+Second, OFPT_FLOW_REMOVED and NXT_FLOW_REMOVED messages are generated
+only if the flow that was removed had the OFPFF_SEND_FLOW_REM flag
+set.
+
+Third, OFPT_PACKET_IN and NXT_PACKET_IN messages are sent only to
+OpenFlow controller connections that have the correct connection ID
+(see "struct nx_controller_id" and "struct nx_action_controller"):
+
+ - For packet-in messages generated by a NXAST_CONTROLLER action,
+ the controller ID specified in the action.
+
+ - For other packet-in messages, controller ID zero. (This is the
+ default ID when an OpenFlow controller does not configure one.)
+
+Finally, Open vSwitch consults a per-connection table indexed by the
+message type, reason code, and current role. The following table
+shows how this table is initialized by default when an OpenFlow
+connection is made. An entry labeled "yes" means that the message is
+sent, an entry labeled "---" means that the message is suppressed.
+
+ master/
+ message and reason code other slave
+ ---------------------------------------- ------- -----
+ OFPT_PACKET_IN / NXT_PACKET_IN
+ OFPR_NO_MATCH yes ---
+ OFPR_ACTION yes ---
+ OFPR_INVALID_TTL --- ---
+
+ OFPT_FLOW_REMOVED / NXT_FLOW_REMOVED
+ OFPRR_IDLE_TIMEOUT yes ---
+ OFPRR_HARD_TIMEOUT yes ---
+ OFPRR_DELETE yes ---
+
+ OFPT_PORT_STATUS
+ OFPPR_ADD yes yes
+ OFPPR_DELETE yes yes
+ OFPPR_MODIFY yes yes
+
+The NXT_SET_ASYNC_CONFIG message directly sets all of the values in
+this table for the current connection. The
+OFPC_INVALID_TTL_TO_CONTROLLER bit in the OFPT_SET_CONFIG message
+controls the setting for OFPR_INVALID_TTL for the "master" role.
+
+
+OFPAT_ENQUEUE
+=============
+
+The OpenFlow 1.0 specification requires the output port of the OFPAT_ENQUEUE
+action to "refer to a valid physical port (i.e. < OFPP_MAX) or OFPP_IN_PORT".
+Although OFPP_LOCAL is not less than OFPP_MAX, it is an 'internal' port which
+can have QoS applied to it in Linux. Since we allow the OFPAT_ENQUEUE to apply
+to 'internal' ports whose port numbers are less than OFPP_MAX, we interpret
+OFPP_LOCAL as a physical port and support OFPAT_ENQUEUE on it as well.
+
+
+OFPT_FLOW_MOD
+=============
+
+The OpenFlow 1.0 specification for the behavior of OFPT_FLOW_MOD is
+confusing. The following table summarizes the Open vSwitch
+implementation of its behavior in the following categories:
+
+ - "match on priority": Whether the flow_mod acts only on flows
+ whose priority matches that included in the flow_mod message.
+
+ - "match on out_port": Whether the flow_mod acts only on flows
+ that output to the out_port included in the flow_mod message (if
+ out_port is not OFPP_NONE).
+
+ - "updates flow_cookie": Whether the flow_mod changes the
+ flow_cookie of the flow or flows that it matches to the
+ flow_cookie included in the flow_mod message.
+
+ - "updates OFPFF_ flags": Whether the flow_mod changes the
+ OFPFF_SEND_FLOW_REM flag of the flow or flows that it matches to
+ the setting included in the flags of the flow_mod message.
+
+ - "honors OFPFF_CHECK_OVERLAP": Whether the OFPFF_CHECK_OVERLAP
+ flag in the flow_mod is significant.
+
+ - "updates idle_timeout" and "updates hard_timeout": Whether the
+ idle_timeout and hard_timeout in the flow_mod, respectively,
+ have an effect on the flow or flows matched by the flow_mod.
+
+ - "updates idle timer": Whether the flow_mod resets the per-flow
+ timer that measures how long a flow has been idle.
+
+ - "updates hard timer": Whether the flow_mod resets the per-flow
+ timer that measures how long it has been since a flow was
+ modified.
+
+ - "zeros counters": Whether the flow_mod resets per-flow packet
+ and byte counters to zero.
+
+ - "sends flow_removed message": Whether the flow_mod generates a
+ flow_removed message for the flow or flows that it affects.
+
+An entry labeled "yes" means that the flow mod type does have the
+indicated behavior, "---" means that it does not, an empty cell means
+that the property is not applicable, and other values are explained
+below the table.
+
+ MODIFY DELETE
+ ADD MODIFY STRICT DELETE STRICT
+ === ====== ====== ====== ======
+match on priority --- --- yes --- yes
+match on out_port --- --- --- yes yes
+updates flow_cookie yes yes yes
+updates OFPFF_SEND_FLOW_REM yes + +
+honors OFPFF_CHECK_OVERLAP yes + +
+updates idle_timeout yes + +
+updates hard_timeout yes + +
+resets idle timer yes + +
+resets hard timer yes yes yes
+zeros counters yes + +
+sends flow_removed message --- --- --- % %
+
+(+) "modify" and "modify-strict" only take these actions when they
+ create a new flow, not when they update an existing flow.
+
+(%) "delete" and "delete_strict" generates a flow_removed message if
+ the deleted flow or flows have the OFPFF_SEND_FLOW_REM flag set.
+ (Each controller can separately control whether it wants to
+ receive the generated messages.)
+
+
+Flow Cookies
+============
+
+OpenFlow 1.0 and later versions have the concept of a "flow cookie",
+which is a 64-bit integer value attached to each flow. The treatment
+of the flow cookie has varied greatly across OpenFlow versions,
+however.
+
+In OpenFlow 1.0:
+
+ - OFPFC_ADD set the cookie in the flow that it added.
+
+ - OFPFC_MODIFY and OFPFC_MODIFY_STRICT updated the cookie for
+ the flow or flows that it modified.
+
+ - OFPST_FLOW messages included the flow cookie.
+
+ - OFPT_FLOW_REMOVED messages reported the cookie of the flow
+ that was removed.
+
+OpenFlow 1.1 made the following changes:
+
+ - Flow mod operations OFPFC_MODIFY, OFPFC_MODIFY_STRICT,
+ OFPFC_DELETE, and OFPFC_DELETE_STRICT, plus flow stats
+ requests and aggregate stats requests, gained the ability to
+ match on flow cookies with an arbitrary mask.
+
+ - OFPFC_MODIFY and OFPFC_MODIFY_STRICT were changed to add a
+ new flow, in the case of no match, only if the flow table
+ modification operation did not match on the cookie field.
+ (In OpenFlow 1.0, modify operations always added a new flow
+ when there was no match.)
+
+ - OFPFC_MODIFY and OFPFC_MODIFY_STRICT no longer updated flow
+ cookies.
+
+OpenFlow 1.2 made the following changes:
+
+ - OFPC_MODIFY and OFPFC_MODIFY_STRICT were changed to never
+ add a new flow, regardless of whether the flow cookie was
+ used for matching.
+
+Open vSwitch support for OpenFlow 1.0 implements the OpenFlow 1.0
+behavior with the following extensions:
+
+ - An NXM extension field NXM_NX_COOKIE(_W) allows the NXM
+ versions of OFPFC_MODIFY, OFPFC_MODIFY_STRICT, OFPFC_DELETE,
+ and OFPFC_DELETE_STRICT flow_mods, plus flow stats requests
+ and aggregate stats requests, to match on flow cookies with
+ arbitrary masks. This is much like the equivalent OpenFlow
+ 1.1 feature.
+
+ - Like OpenFlow 1.1, OFPC_MODIFY and OFPFC_MODIFY_STRICT add a
+ new flow if there is no match and the mask is zero (or not
+ given).
+
+ - The "cookie" field in OFPT_FLOW_MOD and NXT_FLOW_MOD messages
+ is used as the cookie value for OFPFC_ADD commands, as
+ described in OpenFlow 1.0. For OFPFC_MODIFY and
+ OFPFC_MODIFY_STRICT commands, the "cookie" field is used as a
+ new cookie for flows that match unless it is UINT64_MAX, in
+ which case the flow's cookie is not updated.
+
+ - NXT_PACKET_IN (the Nicira extended version of
+ OFPT_PACKET_IN) reports the cookie of the rule that
+ generated the packet, or all-1-bits if no rule generated the
+ packet. (Older versions of OVS used all-0-bits instead of
+ all-1-bits.)
+
+The following table shows the handling of different protocols when
+receiving OFPFC_MODIFY and OFPFC_MODIFY_STRICT messages. A mask of 0
+indicates either an explicit mask of zero or an implicit one by not
+specifying the NXM_NX_COOKIE(_W) field.
+
+ Match Update Add on miss Add on miss
+ cookie cookie mask!=0 mask==0
+ ====== ====== =========== ===========
+OpenFlow 1.0 no yes <always add on miss>
+OpenFlow 1.1 yes no no yes
+OpenFlow 1.2 yes no no no
+NXM yes yes* no yes
+
+* Updates the flow's cookie unless the "cookie" field is UINT64_MAX.
+
+
+Multiple Table Support
+======================
+
+OpenFlow 1.0 has only rudimentary support for multiple flow tables.
+Notably, OpenFlow 1.0 does not allow the controller to specify the
+flow table to which a flow is to be added. Open vSwitch adds an
+extension for this purpose, which is enabled on a per-OpenFlow
+connection basis using the NXT_FLOW_MOD_TABLE_ID message. When the
+extension is enabled, the upper 8 bits of the 'command' member in an
+OFPT_FLOW_MOD or NXT_FLOW_MOD message designates the table to which a
+flow is to be added.
+
+The Open vSwitch software switch implementation offers 255 flow
+tables. On packet ingress, only the first flow table (table 0) is
+searched, and the contents of the remaining tables are not considered
+in any way. Tables other than table 0 only come into play when an
+NXAST_RESUBMIT_TABLE action specifies another table to search.
+
+Tables 128 and above are reserved for use by the switch itself.
+Controllers should use only tables 0 through 127.
+