NXAST_BUNDLE_LOAD, /* struct nx_action_bundle */
NXAST_RESUBMIT_TABLE, /* struct nx_action_resubmit */
NXAST_OUTPUT_REG, /* struct nx_action_output_reg */
- NXAST_LEARN /* struct nx_action_learn */
+ NXAST_LEARN, /* struct nx_action_learn */
+ NXAST_EXIT /* struct nx_action_header */
};
/* Header for Nicira-defined actions. */
};
OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
\f
+/* NXAST_EXIT
+ *
+ * Discontinues action processing.
+ *
+ * The NXAST_EXIT action causes the switch to immediately halt processing
+ * actions for the flow. Any actions which have already been processed are
+ * executed by the switch. However, any further actions, including those which
+ * may be in different tables, or different levels of the NXAST_RESUBMIT
+ * hierarchy, will be ignored.
+ *
+ * Uses the nx_action_header structure. */
+\f
/* Flexible flow specifications (aka NXM = Nicira Extended Match).
*
* OpenFlow 1.0 has "struct ofp_match" for specifying flow matches. This
case OFPUTIL_NXAST_LEARN:
learn_parse(b, arg, flow);
break;
+ case OFPUTIL_NXAST_EXIT:
+ ofputil_put_NXAST_EXIT(b);
+ break;
}
}
learn_format((const struct nx_action_learn *) a, s);
break;
+ case OFPUTIL_NXAST_EXIT:
+ ds_put_cstr(s, "exit");
+ break;
+
default:
break;
}
case OFPUTIL_NXAST_POP_QUEUE:
case OFPUTIL_NXAST_NOTE:
case OFPUTIL_NXAST_SET_TUNNEL64:
+ case OFPUTIL_NXAST_EXIT:
break;
}
NXAST_ACTION(NXAST_RESUBMIT_TABLE, nx_action_resubmit, 0, NULL)
NXAST_ACTION(NXAST_OUTPUT_REG, nx_action_output_reg, 0, NULL)
NXAST_ACTION(NXAST_LEARN, nx_action_learn, 1, "learn")
+NXAST_ACTION(NXAST_EXIT, nx_action_header, 0, "exit")
#undef NXAST_ACTION
uint32_t sflow_n_outputs; /* Number of output ports. */
uint16_t sflow_odp_port; /* Output port for composing sFlow action. */
uint16_t user_cookie_offset;/* Used for user_action_cookie fixup. */
+ bool exit; /* No further actions should be processed. */
};
static void action_xlate_ctx_init(struct action_xlate_ctx *,
enum ofputil_action_code code;
ovs_be64 tun_id;
+ if (ctx->exit) {
+ break;
+ }
+
code = ofputil_decode_action_unsafe(ia);
switch (code) {
case OFPUTIL_OFPAT_OUTPUT:
xlate_learn_action(ctx, (const struct nx_action_learn *) ia);
}
break;
+
+ case OFPUTIL_NXAST_EXIT:
+ ctx->exit = true;
+ break;
}
}
ctx->base_flow = ctx->flow;
ctx->base_flow.tun_id = 0;
ctx->table_id = 0;
+ ctx->exit = false;
if (ctx->flow.tos_frag & FLOW_FRAG_ANY) {
switch (ctx->ofproto->up.frag_handling) {
done
OVS_VSWITCHD_STOP
AT_CLEANUP
+
+AT_SETUP([ofproto-dpif - exit])
+OVS_VSWITCHD_START
+AT_DATA([flows.txt], [dnl
+in_port=1 actions=output:10,exit,output:11
+in_port=2 actions=output:12,resubmit:1,output:12
+in_port=3 actions=output:13,resubmit:2,output:14
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,frag=no),icmp(type=8,code=0)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+ [Datapath actions: 10
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,frag=no),icmp(type=8,code=0)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+ [Datapath actions: 12,10
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,frag=no),icmp(type=8,code=0)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+ [Datapath actions: 13,12,10
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
actions=output:1,bundle_load(eth_src,0,hrw,ofport,NXM_NX_REG0[16..31],slaves:1),output:2
actions=resubmit:1,resubmit(2),resubmit(,3),resubmit(2,3)
actions=output:1,output:NXM_NX_REG0[],output:2,output:NXM_NX_REG1[16..31],output:3
+actions=output:1,exit,output:2
]])
AT_CHECK([ovs-ofctl parse-flows flows.txt
NXT_FLOW_MOD: ADD table:255 actions=output:1,bundle_load(eth_src,0,hrw,ofport,NXM_NX_REG0[16..31],slaves:1),output:2
NXT_FLOW_MOD: ADD table:255 actions=resubmit:1,resubmit:2,resubmit(,3),resubmit(2,3)
NXT_FLOW_MOD: ADD table:255 actions=output:1,output:NXM_NX_REG0[],output:2,output:NXM_NX_REG1[16..31],output:3
+NXT_FLOW_MOD: ADD table:255 actions=output:1,exit,output:2
]])
AT_CLEANUP
keep the learned flows separate from the primary flow table 0.)
.RE
.
+.IP "\fBexit\fR"
+This action causes Open vSwitch to immediately halt execution of further
+actions. Those actions which have already been executed are unaffected. Any
+further actions, including those which may be in other tables, or different
+levels of the \fBresubmit\fR call stack, are ignored.
+.
.PP
The \fBadd\-flow\fR, \fBadd\-flows\fR, and \fBmod\-flows\fR commands
support an additional optional field: