Setting tag sliver-openvswitch-2.2.90-1
[sliver-openvswitch.git] / DESIGN
diff --git a/DESIGN b/DESIGN
index ec29e39..f864135 100644 (file)
--- a/DESIGN
+++ b/DESIGN
@@ -17,8 +17,14 @@ 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 explicitly configures a miss_send_len greater than zero with
-an OFPT_SET_CONFIG message.
+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
@@ -78,8 +84,8 @@ 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
+The OpenFlow specification for the behavior of OFPT_FLOW_MOD is
+confusing.  The following tables summarize the Open vSwitch
 implementation of its behavior in the following categories:
 
     - "match on priority": Whether the flow_mod acts only on flows
@@ -87,7 +93,12 @@ implementation of its behavior in the following categories:
 
     - "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).
+      out_port is not OFPP_NONE).  OpenFlow 1.1 and later have a
+      similar feature (not listed separately here) for out_group.
+
+    - "match on flow_cookie": Whether the flow_mod acts only on flows
+      whose flow_cookie matches an optional controller-specified value
+      and mask.
 
     - "updates flow_cookie": Whether the flow_mod changes the
       flow_cookie of the flow or flows that it matches to the
@@ -114,6 +125,11 @@ implementation of its behavior in the following categories:
     - "zeros counters": Whether the flow_mod resets per-flow packet
       and byte counters to zero.
 
+    - "may add a new flow": Whether the flow_mod may add a new flow to
+      the flow table.  (Obviously this is always true for "add"
+      commands but in some OpenFlow versions "modify" and
+      "modify-strict" can also add new flows.)
+
     - "sends flow_removed message": Whether the flow_mod generates a
       flow_removed message for the flow or flows that it affects.
 
@@ -122,11 +138,17 @@ 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.
 
+OpenFlow 1.0
+------------
+
                                           MODIFY          DELETE
                              ADD  MODIFY  STRICT  DELETE  STRICT
                              ===  ======  ======  ======  ======
-match on priority            ---    ---     yes     ---     yes
+match on priority            yes    ---     yes     ---     yes
 match on out_port            ---    ---     ---     yes     yes
+match on flow_cookie         ---    ---     ---     ---     ---
+match on table_id            ---    ---     ---     ---     ---
+controller chooses table_id  ---    ---     ---
 updates flow_cookie          yes    yes     yes
 updates OFPFF_SEND_FLOW_REM  yes     +       +
 honors OFPFF_CHECK_OVERLAP   yes     +       +
@@ -135,6 +157,7 @@ updates hard_timeout         yes     +       +
 resets idle timer            yes     +       +
 resets hard timer            yes    yes     yes
 zeros counters               yes     +       +
+may add a new flow           yes    yes     yes
 sends flow_removed message   ---    ---     ---      %       %
 
 (+) "modify" and "modify-strict" only take these actions when they
@@ -145,6 +168,356 @@ sends flow_removed message   ---    ---     ---      %       %
     (Each controller can separately control whether it wants to
     receive the generated messages.)
 
+OpenFlow 1.1
+------------
+
+OpenFlow 1.1 makes these changes:
+
+    - The controller now must specify the table_id of the flow match
+      searched and into which a flow may be inserted.  Behavior for a
+      table_id of 255 is undefined.
+
+    - A flow_mod, except an "add", can now match on the flow_cookie.
+
+    - When a flow_mod matches on the flow_cookie, "modify" and
+      "modify-strict" never insert a new flow.
+
+                                          MODIFY          DELETE
+                             ADD  MODIFY  STRICT  DELETE  STRICT
+                             ===  ======  ======  ======  ======
+match on priority            yes    ---     yes     ---     yes
+match on out_port            ---    ---     ---     yes     yes
+match on flow_cookie         ---    yes     yes     yes     yes
+match on table_id            yes    yes     yes     yes     yes
+controller chooses table_id  yes    yes     yes
+updates flow_cookie          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     +       +
+may add a new flow           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.)
+
+(#) "modify" and "modify-strict" only add a new flow if the flow_mod
+    does not match on any bits of the flow cookie
+
+OpenFlow 1.2
+------------
+
+OpenFlow 1.2 makes these changes:
+
+    - Only "add" commands ever add flows, "modify" and "modify-strict"
+      never do.
+
+    - A new flag OFPFF_RESET_COUNTS now controls whether "modify" and
+      "modify-strict" reset counters, whereas previously they never
+      reset counters (except when they inserted a new flow).
+
+                                          MODIFY          DELETE
+                             ADD  MODIFY  STRICT  DELETE  STRICT
+                             ===  ======  ======  ======  ======
+match on priority            yes    ---     yes     ---     yes
+match on out_port            ---    ---     ---     yes     yes
+match on flow_cookie         ---    yes     yes     yes     yes
+match on table_id            yes    yes     yes     yes     yes
+controller chooses table_id  yes    yes     yes
+updates flow_cookie          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     &       &
+may add a new flow           yes    ---     ---
+sends flow_removed message   ---    ---     ---      %       %
+
+(%) "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.)
+
+(&) "modify" and "modify-strict" reset counters if the
+    OFPFF_RESET_COUNTS flag is specified.
+
+OpenFlow 1.3
+------------
+
+OpenFlow 1.3 makes these changes:
+
+    - Behavior for a table_id of 255 is now defined, for "delete" and
+      "delete-strict" commands, as meaning to delete from all tables.
+      A table_id of 255 is now explicitly invalid for other commands.
+
+    - New flags OFPFF_NO_PKT_COUNTS and OFPFF_NO_BYT_COUNTS for "add"
+      operations.
+
+The table for 1.3 is the same as the one shown above for 1.2.
+
+
+OpenFlow 1.4
+------------
+
+OpenFlow 1.4 does not change flow_mod semantics.
+
+
+OFPT_PACKET_IN
+==============
+
+The OpenFlow 1.1 specification for OFPT_PACKET_IN is confusing.  The
+definition in OF1.1 openflow.h is[*]:
+
+  /* Packet received on port (datapath -> controller). */
+  struct ofp_packet_in {
+      struct ofp_header header;
+      uint32_t buffer_id;     /* ID assigned by datapath. */
+      uint32_t in_port;       /* Port on which frame was received. */
+      uint32_t in_phy_port;   /* Physical Port on which frame was received. */
+      uint16_t total_len;     /* Full length of frame. */
+      uint8_t reason;         /* Reason packet is being sent (one of OFPR_*) */
+      uint8_t table_id;       /* ID of the table that was looked up */
+      uint8_t data[0];        /* Ethernet frame, halfway through 32-bit word,
+                                 so the IP header is 32-bit aligned.  The
+                                 amount of data is inferred from the length
+                                 field in the header.  Because of padding,
+                                 offsetof(struct ofp_packet_in, data) ==
+                                 sizeof(struct ofp_packet_in) - 2. */
+  };
+  OFP_ASSERT(sizeof(struct ofp_packet_in) == 24);
+
+The confusing part is the comment on the data[] member.  This comment
+is a leftover from OF1.0 openflow.h, in which the comment was correct:
+sizeof(struct ofp_packet_in) is 20 in OF1.0 and offsetof(struct
+ofp_packet_in, data) is 18.  When OF1.1 was written, the structure
+members were changed but the comment was carelessly not updated, and
+the comment became wrong: sizeof(struct ofp_packet_in) and
+offsetof(struct ofp_packet_in, data) are both 24 in OF1.1.
+
+That leaves the question of how to implement ofp_packet_in in OF1.1.
+The OpenFlow reference implementation for OF1.1 does not include any
+padding, that is, the first byte of the encapsulated frame immediately
+follows the 'table_id' member without a gap.  Open vSwitch therefore
+implements it the same way for compatibility.
+
+For an earlier discussion, please see the thread archived at:
+https://mailman.stanford.edu/pipermail/openflow-discuss/2011-August/002604.html
+
+[*] The quoted definition is directly from OF1.1.  Definitions used
+    inside OVS omit the 8-byte ofp_header members, so the sizes in
+    this discussion are 8 bytes larger than those declared in OVS
+    header files.
+
+
+VLAN Matching
+=============
+
+The 802.1Q VLAN header causes more trouble than any other 4 bytes in
+networking.  More specifically, three versions of OpenFlow and Open
+vSwitch have among them four different ways to match the contents and
+presence of the VLAN header.  The following table describes how each
+version works.
+
+       Match        NXM        OF1.0        OF1.1         OF1.2
+       -----  ---------  -----------  -----------  ------------
+         [1]  0000/0000  ????/1,??/?  ????/1,??/?  0000/0000,--
+         [2]  0000/ffff  ffff/0,??/?  ffff/0,??/?  0000/ffff,--
+         [3]  1xxx/1fff  0xxx/0,??/1  0xxx/0,??/1  1xxx/ffff,--
+         [4]  z000/f000  ????/1,0y/0  fffe/0,0y/0  1000/1000,0y
+         [5]  zxxx/ffff  0xxx/0,0y/0  0xxx/0,0y/0  1xxx/ffff,0y
+         [6]  0000/0fff    <none>       <none>        <none>
+         [7]  0000/f000    <none>       <none>        <none>
+         [8]  0000/efff    <none>       <none>        <none>
+         [9]  1001/1001    <none>       <none>     1001/1001,--
+        [10]  3000/3000    <none>       <none>        <none>
+
+Each column is interpreted as follows.
+
+    - Match: See the list below.
+
+    - NXM: xxxx/yyyy means NXM_OF_VLAN_TCI_W with value xxxx and mask
+      yyyy.  A mask of 0000 is equivalent to omitting
+      NXM_OF_VLAN_TCI(_W), a mask of ffff is equivalent to
+      NXM_OF_VLAN_TCI.
+
+    - OF1.0 and OF1.1: wwww/x,yy/z means dl_vlan wwww, OFPFW_DL_VLAN
+      x, dl_vlan_pcp yy, and OFPFW_DL_VLAN_PCP z.  ? means that the
+      given nibble is ignored (and conventionally 0 for wwww or yy,
+      conventionally 1 for x or z).  <none> means that the given match
+      is not supported.
+
+    - OF1.2: xxxx/yyyy,zz means OXM_OF_VLAN_VID_W with value xxxx and
+      mask yyyy, and OXM_OF_VLAN_PCP (which is not maskable) with
+      value zz.  A mask of 0000 is equivalent to omitting
+      OXM_OF_VLAN_VID(_W), a mask of ffff is equivalent to
+      OXM_OF_VLAN_VID.  -- means that OXM_OF_VLAN_PCP is omitted.
+      <none> means that the given match is not supported.
+
+The matches are:
+
+ [1] Matches any packet, that is, one without an 802.1Q header or with
+     an 802.1Q header with any TCI value.
+
+ [2] Matches only packets without an 802.1Q header.
+
+     NXM: Any match with (vlan_tci == 0) and (vlan_tci_mask & 0x1000)
+     != 0 is equivalent to the one listed in the table.
+
+     OF1.0: The spec doesn't define behavior if dl_vlan is set to
+     0xffff and OFPFW_DL_VLAN_PCP is not set.
+
+     OF1.1: The spec says explicitly to ignore dl_vlan_pcp when
+     dl_vlan is set to 0xffff.
+
+     OF1.2: The spec doesn't say what should happen if (vlan_vid == 0)
+     and (vlan_vid_mask & 0x1000) != 0 but (vlan_vid_mask != 0x1000),
+     but it would be straightforward to also interpret as [2].
+
+ [3] Matches only packets that have an 802.1Q header with VID xxx (and
+     any PCP).
+
+ [4] Matches only packets that have an 802.1Q header with PCP y (and
+     any VID).
+
+     NXM: z is ((y << 1) | 1).
+
+     OF1.0: The spec isn't very clear, but OVS implements it this way.
+
+     OF1.2: Presumably other masks such that (vlan_vid_mask & 0x1fff)
+     == 0x1000 would also work, but the spec doesn't define their
+     behavior.
+
+ [5] Matches only packets that have an 802.1Q header with VID xxx and
+     PCP y.
+
+     NXM: z is ((y << 1) | 1).
+
+     OF1.2: Presumably other masks such that (vlan_vid_mask & 0x1fff)
+     == 0x1fff would also work.
+
+ [6] Matches packets with no 802.1Q header or with an 802.1Q header
+     with a VID of 0.  Only possible with NXM.
+
+ [7] Matches packets with no 802.1Q header or with an 802.1Q header
+     with a PCP of 0.  Only possible with NXM.
+
+ [8] Matches packets with no 802.1Q header or with an 802.1Q header
+     with both VID and PCP of 0.  Only possible with NXM.
+
+ [9] Matches only packets that have an 802.1Q header with an
+     odd-numbered VID (and any PCP).  Only possible with NXM and
+     OF1.2.  (This is just an example; one can match on any desired
+     VID bit pattern.)
+
+[10] Matches only packets that have an 802.1Q header with an
+     odd-numbered PCP (and any VID).  Only possible with NXM.  (This
+     is just an example; one can match on any desired VID bit
+     pattern.)
+
+Additional notes:
+
+    - OF1.2: The top three bits of OXM_OF_VLAN_VID are fixed to zero,
+      so bits 13, 14, and 15 in the masks listed in the table may be
+      set to arbitrary values, as long as the corresponding value bits
+      are also zero.  The suggested ffff mask for [2], [3], and [5]
+      allows a shorter OXM representation (the mask is omitted) than
+      the minimal 1fff mask.
+
+
+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
 ======================
@@ -232,22 +605,151 @@ vSwitch doesn't process jumbograms.
 In-Band Control
 ===============
 
-In-band control allows a single network to be used for OpenFlow traffic and
-other data traffic.  See ovs-vswitchd.conf.db(5) for a description of
-configuring in-band control.
+Motivation
+----------
+
+An OpenFlow switch must establish and maintain a TCP network
+connection to its controller.  There are two basic ways to categorize
+the network that this connection traverses: either it is completely
+separate from the one that the switch is otherwise controlling, or its
+path may overlap the network that the switch controls.  We call the
+former case "out-of-band control", the latter case "in-band control".
+
+Out-of-band control has the following benefits:
+
+    - Simplicity: Out-of-band control slightly simplifies the switch
+      implementation.
 
-This comment is an attempt to describe how in-band control works at a
-wire- and implementation-level.  Correctly implementing in-band
-control has proven difficult due to its many subtleties, and has thus
-gone through many iterations.  Please read through and understand the
-reasoning behind the chosen rules before making modifications.
+    - Reliability: Excessive switch traffic volume cannot interfere
+      with control traffic.
 
-In Open vSwitch, in-band control is implemented as "hidden" flows (in that
-they are not visible through OpenFlow) and at a higher priority than
-wildcarded flows can be set up by through OpenFlow.  This is done so that
-the OpenFlow controller cannot interfere with them and possibly break
-connectivity with its switches.  It is possible to see all flows, including
-in-band ones, with the ovs-appctl "bridge/dump-flows" command.
+    - Integrity: Machines not on the control network cannot
+      impersonate a switch or a controller.
+
+    - Confidentiality: Machines not on the control network cannot
+      snoop on control traffic.
+
+In-band control, on the other hand, has the following advantages:
+
+    - No dedicated port: There is no need to dedicate a physical
+      switch port to control, which is important on switches that have
+      few ports (e.g. wireless routers, low-end embedded platforms).
+
+    - No dedicated network: There is no need to build and maintain a
+      separate control network.  This is important in many
+      environments because it reduces proliferation of switches and
+      wiring.
+
+Open vSwitch supports both out-of-band and in-band control.  This
+section describes the principles behind in-band control.  See the
+description of the Controller table in ovs-vswitchd.conf.db(5) to
+configure OVS for in-band control.
+
+Principles
+----------
+
+The fundamental principle of in-band control is that an OpenFlow
+switch must recognize and switch control traffic without involving the
+OpenFlow controller.  All the details of implementing in-band control
+are special cases of this principle.
+
+The rationale for this principle is simple.  If the switch does not
+handle in-band control traffic itself, then it will be caught in a
+contradiction: it must contact the controller, but it cannot, because
+only the controller can set up the flows that are needed to contact
+the controller.
+
+The following points describe important special cases of this
+principle.
+
+   - In-band control must be implemented regardless of whether the
+     switch is connected.
+
+     It is tempting to implement the in-band control rules only when
+     the switch is not connected to the controller, using the
+     reasoning that the controller should have complete control once
+     it has established a connection with the switch.
+
+     This does not work in practice.  Consider the case where the
+     switch is connected to the controller.  Occasionally it can
+     happen that the controller forgets or otherwise needs to obtain
+     the MAC address of the switch.  To do so, the controller sends a
+     broadcast ARP request.  A switch that implements the in-band
+     control rules only when it is disconnected will then send an
+     OFPT_PACKET_IN message up to the controller.  The controller will
+     be unable to respond, because it does not know the MAC address of
+     the switch.  This is a deadlock situation that can only be
+     resolved by the switch noticing that its connection to the
+     controller has hung and reconnecting.
+
+   - In-band control must override flows set up by the controller.
+
+     It is reasonable to assume that flows set up by the OpenFlow
+     controller should take precedence over in-band control, on the
+     basis that the controller should be in charge of the switch.
+
+     Again, this does not work in practice.  Reasonable controller
+     implementations may set up a "last resort" fallback rule that
+     wildcards every field and, e.g., sends it up to the controller or
+     discards it.  If a controller does that, then it will isolate
+     itself from the switch.
+
+   - The switch must recognize all control traffic.
+
+     The fundamental principle of in-band control states, in part,
+     that a switch must recognize control traffic without involving
+     the OpenFlow controller.  More specifically, the switch must
+     recognize *all* control traffic.  "False negatives", that is,
+     packets that constitute control traffic but that the switch does
+     not recognize as control traffic, lead to control traffic storms.
+
+     Consider an OpenFlow switch that only recognizes control packets
+     sent to or from that switch.  Now suppose that two switches of
+     this type, named A and B, are connected to ports on an Ethernet
+     hub (not a switch) and that an OpenFlow controller is connected
+     to a third hub port.  In this setup, control traffic sent by
+     switch A will be seen by switch B, which will send it to the
+     controller as part of an OFPT_PACKET_IN message.  Switch A will
+     then see the OFPT_PACKET_IN message's packet, re-encapsulate it
+     in another OFPT_PACKET_IN, and send it to the controller.  Switch
+     B will then see that OFPT_PACKET_IN, and so on in an infinite
+     loop.
+
+     Incidentally, the consequences of "false positives", where
+     packets that are not control traffic are nevertheless recognized
+     as control traffic, are much less severe.  The controller will
+     not be able to control their behavior, but the network will
+     remain in working order.  False positives do constitute a
+     security problem.
+
+   - The switch should use echo-requests to detect disconnection.
+
+     TCP will notice that a connection has hung, but this can take a
+     considerable amount of time.  For example, with default settings
+     the Linux kernel TCP implementation will retransmit for between
+     13 and 30 minutes, depending on the connection's retransmission
+     timeout, according to kernel documentation.  This is far too long
+     for a switch to be disconnected, so an OpenFlow switch should
+     implement its own connection timeout.  OpenFlow OFPT_ECHO_REQUEST
+     messages are the best way to do this, since they test the
+     OpenFlow connection itself.
+
+Implementation
+--------------
+
+This section describes how Open vSwitch implements in-band control.
+Correctly implementing in-band control has proven difficult due to its
+many subtleties, and has thus gone through many iterations.  Please
+read through and understand the reasoning behind the chosen rules
+before making modifications.
+
+Open vSwitch implements in-band control as "hidden" flows, that is,
+flows that are not visible through OpenFlow, and at a higher priority
+than wildcarded flows can be set up through OpenFlow.  This is done so
+that the OpenFlow controller cannot interfere with them and possibly
+break connectivity with its switches.  It is possible to see all
+flows, including in-band ones, with the ovs-appctl "bridge/dump-flows"
+command.
 
 The Open vSwitch implementation of in-band control can hide traffic to
 arbitrary "remotes", where each remote is one TCP port on one IP address.
@@ -392,6 +894,39 @@ The following are explicitly *not* supported by in-band control:
      gateway.
 
 
+Action Reproduction
+===================
+
+It seems likely that many controllers, at least at startup, use the
+OpenFlow "flow statistics" request to obtain existing flows, then
+compare the flows' actions against the actions that they expect to
+find.  Before version 1.8.0, Open vSwitch always returned exact,
+byte-for-byte copies of the actions that had been added to the flow
+table.  The current version of Open vSwitch does not always do this in
+some exceptional cases.  This section lists the exceptions that
+controller authors must keep in mind if they compare actual actions
+against desired actions in a bytewise fashion:
+
+        - Open vSwitch zeros padding bytes in action structures,
+          regardless of their values when the flows were added.
+
+        - Open vSwitch "normalizes" the instructions in OpenFlow 1.1
+          (and later) in the following way:
+
+              * OVS sorts the instructions into the following order:
+                Apply-Actions, Clear-Actions, Write-Actions,
+                Write-Metadata, Goto-Table.
+
+              * OVS drops Apply-Actions instructions that have empty
+                action lists.
+
+              * OVS drops Write-Actions instructions that have empty
+                action sets.
+
+Please report other discrepancies, if you notice any, so that we can
+fix or document them.
+
+
 Suggestions
 ===========