+ mirror_mask_t mirrors; /* Bitmap of associated mirrors. */
+
+ /* These are used for non-bond recirculation. The recirculation IDs are
+ * stored in xout and must be associated with a datapath flow (ukey),
+ * otherwise they will be freed when the xout is uninitialized.
+ *
+ *
+ * Steps in Recirculation Translation
+ * ==================================
+ *
+ * At some point during translation, the code recognizes the need for
+ * recirculation. For example, recirculation is necessary when, after
+ * popping the last MPLS label, an action or a match tries to examine or
+ * modify a field that has been newly revealed following the MPLS label.
+ *
+ * The simplest part of the work to be done is to commit existing changes to
+ * the packet, which produces datapath actions corresponding to the changes,
+ * and after this, add an OVS_ACTION_ATTR_RECIRC datapath action.
+ *
+ * The main problem here is preserving state. When the datapath executes
+ * OVS_ACTION_ATTR_RECIRC, it will upcall to userspace to get a translation
+ * for the post-recirculation actions. At this point userspace has to
+ * resume the translation where it left off, which means that it has to
+ * execute the following:
+ *
+ * - The action that prompted recirculation, and any actions following
+ * it within the same flow.
+ *
+ * - If the action that prompted recirculation was invoked within a
+ * NXAST_RESUBMIT, then any actions following the resubmit. These
+ * "resubmit"s can be nested, so this has to go all the way up the
+ * control stack.
+ *
+ * - The OpenFlow 1.1+ action set.
+ *
+ * State that actions and flow table lookups can depend on, such as the
+ * following, must also be preserved:
+ *
+ * - Metadata fields (input port, registers, OF1.1+ metadata, ...).
+ *
+ * - Action set, stack
+ *
+ * - The table ID and cookie of the flow being translated at each level
+ * of the control stack (since OFPAT_CONTROLLER actions send these to
+ * the controller).
+ *
+ * Translation allows for the control of this state preservation via these
+ * members. When a need for recirculation is identified, the translation
+ * process:
+ *
+ * 1. Sets 'recirc_action_offset' to the current size of 'action_set'. The
+ * action set is part of what needs to be preserved, so this allows the
+ * action set and the additional state to share the 'action_set' buffer.
+ * Later steps can tell that setup for recirculation is in progress from
+ * the nonnegative value of 'recirc_action_offset'.
+ *
+ * 2. Sets 'exit' to true to tell later steps that we're exiting from the
+ * translation process.
+ *
+ * 3. Adds an OFPACT_UNROLL_XLATE action to 'action_set'. This action
+ * holds the current table ID and cookie so that they can be restored
+ * during a post-recirculation upcall translation.
+ *
+ * 4. Adds the action that prompted recirculation and any actions following
+ * it within the same flow to 'action_set', so that they can be executed
+ * during a post-recirculation upcall translation.
+ *
+ * 5. Returns.
+ *
+ * 6. The action that prompted recirculation might be nested in a stack of
+ * nested "resubmit"s that have actions remaining. Each of these notices
+ * that we're exiting (from 'exit') and that recirculation setup is in
+ * progress (from 'recirc_action_offset') and responds by adding more
+ * OFPACT_UNROLL_XLATE actions to 'action_set', as necessary, and any
+ * actions that were yet unprocessed.
+ *
+ * The caller stores all the state produced by this process associated with
+ * the recirculation ID. For post-recirculation upcall translation, the
+ * caller passes it back in for the new translation to execute. The
+ * process yielded a set of ofpacts that can be translated directly, so it
+ * is not much of a special case at that point.
+ */
+ int recirc_action_offset; /* Offset in 'action_set' to actions to be
+ * executed after recirculation, or -1. */
+ int last_unroll_offset; /* Offset in 'action_set' to the latest unroll
+ * action, or -1. */