Skip to content

Commit

Permalink
nicira-ext: New action "exit".
Browse files Browse the repository at this point in the history
The exit action causes the switch to immediately halt processing of
further actions. It's intended to be used in conjunction with
multi table support.  It allows a table to force tables which call
it to discontinue processing a flow.
  • Loading branch information
ejj committed Oct 29, 2011
1 parent db96831 commit 848e880
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 1 deletion.
15 changes: 14 additions & 1 deletion include/openflow/nicira-ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ enum nx_action_subtype {
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. */
Expand Down Expand Up @@ -1034,6 +1035,18 @@ struct nx_action_output_reg {
};
OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);

/* 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. */

/* Flexible flow specifications (aka NXM = Nicira Extended Match).
*
* OpenFlow 1.0 has "struct ofp_match" for specifying flow matches. This
Expand Down
3 changes: 3 additions & 0 deletions lib/ofp-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,9 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow,
case OFPUTIL_NXAST_LEARN:
learn_parse(b, arg, flow);
break;
case OFPUTIL_NXAST_EXIT:
ofputil_put_NXAST_EXIT(b);
break;
}
}

Expand Down
4 changes: 4 additions & 0 deletions lib/ofp-print.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ ofp_print_action(struct ds *s, const union ofp_action *a,
learn_format((const struct nx_action_learn *) a, s);
break;

case OFPUTIL_NXAST_EXIT:
ds_put_cstr(s, "exit");
break;

default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions lib/ofp-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -2185,6 +2185,7 @@ validate_actions(const union ofp_action *actions, size_t n_actions,
case OFPUTIL_NXAST_POP_QUEUE:
case OFPUTIL_NXAST_NOTE:
case OFPUTIL_NXAST_SET_TUNNEL64:
case OFPUTIL_NXAST_EXIT:
break;
}

Expand Down
1 change: 1 addition & 0 deletions lib/ofp-util.def
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ NXAST_ACTION(NXAST_BUNDLE_LOAD, nx_action_bundle, 1, "bundle_load")
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
10 changes: 10 additions & 0 deletions ofproto/ofproto-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ struct action_xlate_ctx {
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 *,
Expand Down Expand Up @@ -4123,6 +4124,10 @@ do_xlate_actions(const union ofp_action *in, size_t n_in,
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:
Expand Down Expand Up @@ -4258,6 +4263,10 @@ do_xlate_actions(const union ofp_action *in, size_t n_in,
xlate_learn_action(ctx, (const struct nx_action_learn *) ia);
}
break;

case OFPUTIL_NXAST_EXIT:
ctx->exit = true;
break;
}
}

Expand Down Expand Up @@ -4300,6 +4309,7 @@ xlate_actions(struct action_xlate_ctx *ctx,
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) {
Expand Down
23 changes: 23 additions & 0 deletions tests/ofproto-dpif.at
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,26 @@ do
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
2 changes: 2 additions & 0 deletions tests/ovs-ofctl.at
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ actions=bundle_load(symmetric_l4,60,hrw,ofport,NXM_NX_REG0[0..30],slaves:)
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
Expand Down Expand Up @@ -56,6 +57,7 @@ NXT_FLOW_MOD: ADD table:255 actions=bundle_load(symmetric_l4,60,hrw,ofport,NXM_N
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

Expand Down
6 changes: 6 additions & 0 deletions utilities/ovs-ofctl.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,12 @@ with no match criteria. (This is why the default \fBtable\fR is 1, to
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:
Expand Down

0 comments on commit 848e880

Please sign in to comment.