Signed-off-by: Isaku Yamahata <[email protected]>
---
v5
- manual rebase
v4
- clear-actions part is split outed.
- check zero padding
- man page
---
lib/ofp-actions.c | 33 ++++++++++++++++++++++++++-------
lib/ofp-actions.h | 13 ++++++++-----
lib/ofp-parse.c | 5 +----
ofproto/ofproto-dpif.c | 8 ++++++++
tests/ofp-actions.at | 12 ++++++++++--
utilities/ovs-ofctl.8.in | 3 +++
6 files changed, 56 insertions(+), 18 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 1ff35cc..bfcbe5c 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -955,7 +955,16 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf
*openflow,
goto exit;
}
}
- /* TODO:XXX Clear-Actions */
+ if (insts[OVSINST_OFPIT11_CLEAR_ACTIONS]) {
+ const struct ofp11_instruction *oi;
+
+ oi = instruction_get_OFPIT11_CLEAR_ACTIONS(
+ insts[OVSINST_OFPIT11_CLEAR_ACTIONS]);
+ if (!is_all_zeros(oi->pad, sizeof oi->pad)) {
+ return OFPERR_OFPBAC_BAD_ARGUMENT;
+ }
+ ofpact_put_CLEAR_ACTIONS(ofpacts);
+ }
/* TODO:XXX Write-Actions */
/* TODO:XXX Write-Metadata */
if (insts[OVSINST_OFPIT11_GOTO_TABLE]) {
@@ -972,8 +981,7 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf
*openflow,
}
if (insts[OVSINST_OFPIT11_WRITE_METADATA] ||
- insts[OVSINST_OFPIT11_WRITE_ACTIONS] ||
- insts[OVSINST_OFPIT11_CLEAR_ACTIONS]) {
+ insts[OVSINST_OFPIT11_WRITE_ACTIONS]) {
error = OFPERR_OFPBIC_UNSUP_INST;
goto exit;
}
@@ -1051,6 +1059,7 @@ ofpact_check__(const struct ofpact *a, const struct flow
*flow, int max_ports)
case OFPACT_EXIT:
return 0;
+ case OFPACT_CLEAR_ACTIONS:
case OFPACT_GOTO_TABLE:
return 0;
@@ -1269,6 +1278,7 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf
*out)
case OFPACT_SET_IPV4_DSCP:
case OFPACT_SET_L4_SRC_PORT:
case OFPACT_SET_L4_DST_PORT:
+ case OFPACT_CLEAR_ACTIONS:
case OFPACT_GOTO_TABLE:
NOT_REACHED();
}
@@ -1359,6 +1369,7 @@ ofpact_to_openflow10(const struct ofpact *a, struct
ofpbuf *out)
= htons(ofpact_get_SET_L4_DST_PORT(a)->port);
break;
+ case OFPACT_CLEAR_ACTIONS:
case OFPACT_GOTO_TABLE:
/* TODO:XXX */
break;
@@ -1471,6 +1482,7 @@ ofpact_to_openflow11(const struct ofpact *a, struct
ofpbuf *out)
= htons(ofpact_get_SET_L4_DST_PORT(a)->port);
break;
+ case OFPACT_CLEAR_ACTIONS:
case OFPACT_GOTO_TABLE:
NOT_REACHED();
@@ -1544,10 +1556,13 @@ ofpacts_put_openflow11_instructions(const struct ofpact
ofpacts[],
ofs = 0;
}
- /* TODO:XXX Clear-Actions */
/* TODO:XXX Write-Actions */
/* TODO:XXX Write-Metadata */
- if (a->type == OFPACT_GOTO_TABLE) {
+ if (a->type == OFPACT_CLEAR_ACTIONS) {
+ struct ofp11_instruction *oi;
+ oi = instruction_put_OFPIT11_CLEAR_ACTIONS(openflow);
+ memset(oi->pad, 0, sizeof oi->pad);
+ } else if (a->type == OFPACT_GOTO_TABLE) {
struct ofp11_instruction_goto_table *oigt;
oigt = instruction_put_OFPIT11_GOTO_TABLE(openflow);
oigt->table_id = ofpact_get_GOTO_TABLE(a)->table_id;
@@ -1603,6 +1618,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact,
uint16_t port)
case OFPACT_AUTOPATH:
case OFPACT_NOTE:
case OFPACT_EXIT:
+ case OFPACT_CLEAR_ACTIONS:
case OFPACT_GOTO_TABLE:
default:
return false;
@@ -1868,6 +1884,7 @@ ofpact_format(const struct ofpact *a, struct ds *s)
ds_put_cstr(s, "exit");
break;
+ case OFPACT_CLEAR_ACTIONS:
case OFPACT_GOTO_TABLE:
NOT_REACHED();
}
@@ -1922,10 +1939,12 @@ ofpacts_format(const struct ofpact *ofpacts, size_t
ofpacts_len,
n_actions = 0;
}
- /* TODO:XXX clear-actions */
/* TODO:XXX write-actions */
/* TODO:XXX write-metadata */
- if (a->type == OFPACT_GOTO_TABLE) {
+ if (a->type == OFPACT_CLEAR_ACTIONS) {
+ ds_put_format(string, "%s", ofpact_instruction_name_from_type(
+ OVSINST_OFPIT11_CLEAR_ACTIONS));
+ } else if (a->type == OFPACT_GOTO_TABLE) {
ds_put_format(string, "%s:%"PRIu8,
ofpact_instruction_name_from_type(
OVSINST_OFPIT11_GOTO_TABLE),
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 4995c66..c899868 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -90,7 +90,8 @@
DEFINE_OFPACT(EXIT, ofpact_null, ofpact) \
\
/* Instructions */ \
- /* TODO:XXX Clear-Actions, Write-Actions, Write-Metadata */ \
+ /* TODO:XXX Write-Actions, Write-Metadata */ \
+ DEFINE_OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact) \
DEFINE_OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact)
/* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */
@@ -149,9 +150,10 @@ ofpact_end(const struct ofpact *ofpacts, size_t
ofpacts_len)
/* Action structure for each OFPACT_*. */
-/* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT.
+/* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT, OFPACT_CLEAR_ACTIONS.
*
- * Used for OFPAT10_STRIP_VLAN, NXAST_DEC_TTL, NXAST_POP_QUEUE, NXAST_EXIT.
+ * Used for OFPAT10_STRIP_VLAN, NXAST_DEC_TTL, NXAST_POP_QUEUE, NXAST_EXIT,
+ * OFPIT11_CLEAR_ACTIONS.
*
* Action structure for actions that do not have any extra data beyond the
* action type. */
@@ -557,8 +559,9 @@ enum {
static inline bool
ofpact_is_instruction(const struct ofpact *a)
{
- /* TODO:XXX Clear-Actions, Write-Actions, Write-Metadata */
- return a->type == OFPACT_GOTO_TABLE;
+ /* TODO:XXX Write-Actions, Write-Metadata */
+ return a->type == OFPACT_CLEAR_ACTIONS
+ || a->type == OFPACT_GOTO_TABLE;
}
const char *ofpact_instruction_name_from_type(enum ovs_instruction_type type);
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 8248830..50925c9 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -522,7 +522,7 @@ parse_named_instruction(enum ovs_instruction_type type,
break;
case OVSINST_OFPIT11_CLEAR_ACTIONS:
- NOT_REACHED(); /* TODO:XXX */
+ ofpact_put_CLEAR_ACTIONS(ofpacts);
break;
case OVSINST_OFPIT11_WRITE_METADATA:
@@ -572,9 +572,6 @@ str_to_inst_ofpacts(const struct flow *flow, char *str,
struct ofpbuf *ofpacts)
}
/* TODO:XXX */
- if (inst_args[OVSINST_OFPIT11_CLEAR_ACTIONS]) {
- ovs_fatal(0, "instruction clear-actions is not supported yet");
- }
if (inst_args[OVSINST_OFPIT11_WRITE_ACTIONS]) {
ovs_fatal(0, "instruction write-actions is not supported yet");
}
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 77a8bbf..d35a0bd 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -5602,6 +5602,14 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t
ofpacts_len,
xlate_fin_timeout(ctx, ofpact_get_FIN_TIMEOUT(a));
break;
+ case OFPACT_CLEAR_ACTIONS:
+ /* TODO:XXX
+ * Nothing to do because writa-actions is not supported for now.
+ * When writa-actions is supported, clear-actions also must
+ * be supported at the same time.
+ */
+ break;
+
case OFPACT_GOTO_TABLE: {
/* TODO:XXX remove recursion */
/* It is assumed that goto-table is last action */
diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at
index acc9e13..0e77893 100644
--- a/tests/ofp-actions.at
+++ b/tests/ofp-actions.at
@@ -299,9 +299,17 @@ dnl Write-Actions not supported yet.
# bad OF1.1 instructions: OFPBIC_UNSUP_INST
0003 0008 01 000000
-dnl Clear-Actions not supported yet.
+dnl Clear-Actions too-long
+# bad OF1.1 instructions: OFPBIC_BAD_LEN
+0005 0010 00000000 0000000000000000
+
+dnl Clear-Actions non-zero padding
+# bad OF1.1 instructions: OFPBAC_BAD_ARGUMENT
+0005 0008 00000001
+
+dnl Clear-Actions
# instructions=clear_actions
-0005 0008 01 000000
+0005 0008 00000000
dnl Experimenter actions not supported yet.
# bad OF1.1 instructions: OFPBIC_BAD_EXPERIMENTER
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index 8d9bcec..f72c0b1 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -1136,6 +1136,9 @@ keywords:
Applies the specific action(s) immediately. The syntax of actions are same
to \fBactions=\fR field.
.
+.IP \fBclear_actions\fR
+Clears all the actions in the action set immediately.
+.
.IP \fBgoto_table\fR:\fItable\fR
Indicates the next table in the process pipeline.
.RE
--
1.7.1.1
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev