ofproto: Add support for NXAST_RESUBMIT recursion.
authorBen Pfaff <blp@nicira.com>
Fri, 13 Aug 2010 16:57:25 +0000 (09:57 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 13 Aug 2010 16:57:25 +0000 (09:57 -0700)
CC: Teemu Koponen <koponen@nicira.com>
include/openflow/nicira-ext.h
ofproto/ofproto.c

index e6f34ba..a80439c 100644 (file)
@@ -118,14 +118,16 @@ enum nx_action_subtype {
      * Following the lookup, the original in_port is restored.
      *
      * If the modified flow matched in the flow table, then the corresponding
-     * actions are executed, except that NXAST_RESUBMIT actions found in the
-     * secondary set of actions are ignored.  Afterward, actions following
-     * NXAST_RESUBMIT in the original set of actions, if any, are executed; any
-     * changes made to the packet (e.g. changes to VLAN) by secondary actions
-     * persist when those actions are executed, although the original in_port
-     * is restored.
+     * actions are executed.  Afterward, actions following NXAST_RESUBMIT in
+     * the original set of actions, if any, are executed; any changes made to
+     * the packet (e.g. changes to VLAN) by secondary actions persist when
+     * those actions are executed, although the original in_port is restored.
      *
      * NXAST_RESUBMIT may be used any number of times within a set of actions.
+     *
+     * NXAST_RESUBMIT may nest to an implementation-defined depth.  Beyond this
+     * implementation-defined depth, further NXAST_RESUBMIT actions are simply
+     * ignored.  (Open vSwitch 1.0.1 and earlier did not support recursion.)
      */
     NXAST_RESUBMIT,
 
index b6c83f8..d74f321 100644 (file)
@@ -2414,6 +2414,10 @@ struct action_xlate_ctx {
     uint16_t nf_output_iface;   /* Output interface index for NetFlow. */
 };
 
+/* Maximum depth of flow table recursion (due to NXAST_RESUBMIT actions) in a
+ * flow translation. */
+#define MAX_RESUBMIT_RECURSION 8
+
 static void do_xlate_actions(const union ofp_action *in, size_t n_in,
                              struct action_xlate_ctx *ctx);
 
@@ -2461,7 +2465,7 @@ lookup_valid_rule(struct ofproto *ofproto, const flow_t *flow)
 static void
 xlate_table_action(struct action_xlate_ctx *ctx, uint16_t in_port)
 {
-    if (!ctx->recurse) {
+    if (ctx->recurse < MAX_RESUBMIT_RECURSION) {
         uint16_t old_in_port;
         struct rule *rule;
 
@@ -2482,6 +2486,11 @@ xlate_table_action(struct action_xlate_ctx *ctx, uint16_t in_port)
             do_xlate_actions(rule->actions, rule->n_actions, ctx);
             ctx->recurse--;
         }
+    } else {
+        struct vlog_rate_limit recurse_rl = VLOG_RATE_LIMIT_INIT(1, 1);
+
+        VLOG_ERR_RL(&recurse_rl, "NXAST_RESUBMIT recursed over %d times",
+                    MAX_RESUBMIT_RECURSION);
     }
 }