From: Ben Pfaff Date: Fri, 13 Aug 2010 16:57:25 +0000 (-0700) Subject: ofproto: Add support for NXAST_RESUBMIT recursion. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f8bfd69fd6173d525e6fe92902dd8c6628fc327;p=openvswitch ofproto: Add support for NXAST_RESUBMIT recursion. CC: Teemu Koponen --- diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h index e6f34baa..a80439c5 100644 --- a/include/openflow/nicira-ext.h +++ b/include/openflow/nicira-ext.h @@ -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, diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index b6c83f86..d74f321d 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -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); } }