[ovs-dev] [PATCH v5 6/6] instruction/write-actions: add text parser/formater, of packet decoder/encoder
Isaku Yamahata
yamahata at valinux.co.jp
Tue Aug 28 17:19:05 UTC 2012
Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
---
v5
- manual rebase
v4
- write-action part is split out
- man page
---
lib/ofp-actions.c | 55 +++++++++++++++++++++++++++++++++++++--------
lib/ofp-actions.h | 11 ++++++---
lib/ofp-parse.c | 6 +---
ofproto/ofproto-dpif.c | 10 ++++----
tests/ofp-actions.at | 18 ++++++++++++--
utilities/ovs-ofctl.8.in | 4 +++
6 files changed, 78 insertions(+), 26 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index bfcbe5c..d541ea9 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -902,6 +902,18 @@ ofpacts_pull_openflow11_actions(struct ofpbuf *openflow,
ofpacts_from_openflow11);
}
+static enum ofperr
+ofpacts_pull_openflow11_inst_actions(const struct ofp11_instruction *inst,
+ struct ofpbuf *ofpacts)
+
+{
+ const union ofp_action *actions;
+ size_t n_actions;
+
+ get_actions_from_instruction(inst, &actions, &n_actions);
+ return ofpacts_from_openflow11(actions, n_actions, ofpacts);
+}
+
enum ofperr
ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
unsigned int instructions_len,
@@ -940,17 +952,14 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
if (insts[OVSINST_OFPIT11_APPLY_ACTIONS]) {
const struct ofp11_instruction_actions *oia;
- const union ofp_action *actions;
- size_t n_actions;
oia = instruction_get_OFPIT11_APPLY_ACTIONS(
insts[OVSINST_OFPIT11_APPLY_ACTIONS]);
if (!is_all_zeros(oia->pad, sizeof oia->pad)) {
return OFPERR_OFPBAC_BAD_ARGUMENT;
}
- get_actions_from_instruction(insts[OVSINST_OFPIT11_APPLY_ACTIONS],
- &actions, &n_actions);
- error = ofpacts_from_openflow11(actions, n_actions, ofpacts);
+ error = ofpacts_pull_openflow11_inst_actions(
+ insts[OVSINST_OFPIT11_APPLY_ACTIONS], ofpacts);
if (error) {
goto exit;
}
@@ -965,7 +974,21 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
}
ofpact_put_CLEAR_ACTIONS(ofpacts);
}
- /* TODO:XXX Write-Actions */
+ if (insts[OVSINST_OFPIT11_WRITE_ACTIONS]) {
+ const struct ofp11_instruction_actions *oia;
+
+ oia = instruction_get_OFPIT11_WRITE_ACTIONS(
+ insts[OVSINST_OFPIT11_WRITE_ACTIONS]);
+ if (!is_all_zeros(oia->pad, sizeof oia->pad)) {
+ return OFPERR_OFPBAC_BAD_ARGUMENT;
+ }
+ ofpact_put_WRITE_ACTIONS(ofpacts);
+ error = ofpacts_pull_openflow11_inst_actions(
+ insts[OVSINST_OFPIT11_WRITE_ACTIONS], ofpacts);
+ if (error) {
+ goto exit;
+ }
+ }
/* TODO:XXX Write-Metadata */
if (insts[OVSINST_OFPIT11_GOTO_TABLE]) {
const struct ofp11_instruction_goto_table *oigt;
@@ -980,8 +1003,7 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
ogt->table_id = oigt->table_id;
}
- if (insts[OVSINST_OFPIT11_WRITE_METADATA] ||
- insts[OVSINST_OFPIT11_WRITE_ACTIONS]) {
+ if (insts[OVSINST_OFPIT11_WRITE_METADATA]) {
error = OFPERR_OFPBIC_UNSUP_INST;
goto exit;
}
@@ -1060,6 +1082,7 @@ ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports)
return 0;
case OFPACT_CLEAR_ACTIONS:
+ case OFPACT_WRITE_ACTIONS:
case OFPACT_GOTO_TABLE:
return 0;
@@ -1279,6 +1302,7 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out)
case OFPACT_SET_L4_SRC_PORT:
case OFPACT_SET_L4_DST_PORT:
case OFPACT_CLEAR_ACTIONS:
+ case OFPACT_WRITE_ACTIONS:
case OFPACT_GOTO_TABLE:
NOT_REACHED();
}
@@ -1370,6 +1394,7 @@ ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out)
break;
case OFPACT_CLEAR_ACTIONS:
+ case OFPACT_WRITE_ACTIONS:
case OFPACT_GOTO_TABLE:
/* TODO:XXX */
break;
@@ -1483,6 +1508,7 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out)
break;
case OFPACT_CLEAR_ACTIONS:
+ case OFPACT_WRITE_ACTIONS:
case OFPACT_GOTO_TABLE:
NOT_REACHED();
@@ -1556,12 +1582,15 @@ ofpacts_put_openflow11_instructions(const struct ofpact ofpacts[],
ofs = 0;
}
- /* TODO:XXX Write-Actions */
/* TODO:XXX Write-Metadata */
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_WRITE_ACTIONS) {
+ in_instruction = true;
+ ofs = openflow->size;
+ instruction_put_OFPIT11_WRITE_ACTIONS(openflow);
} else if (a->type == OFPACT_GOTO_TABLE) {
struct ofp11_instruction_goto_table *oigt;
oigt = instruction_put_OFPIT11_GOTO_TABLE(openflow);
@@ -1619,6 +1648,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, uint16_t port)
case OFPACT_NOTE:
case OFPACT_EXIT:
case OFPACT_CLEAR_ACTIONS:
+ case OFPACT_WRITE_ACTIONS:
case OFPACT_GOTO_TABLE:
default:
return false;
@@ -1885,6 +1915,7 @@ ofpact_format(const struct ofpact *a, struct ds *s)
break;
case OFPACT_CLEAR_ACTIONS:
+ case OFPACT_WRITE_ACTIONS:
case OFPACT_GOTO_TABLE:
NOT_REACHED();
}
@@ -1939,11 +1970,15 @@ ofpacts_format(const struct ofpact *ofpacts, size_t ofpacts_len,
n_actions = 0;
}
- /* TODO:XXX write-actions */
/* TODO:XXX write-metadata */
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_WRITE_ACTIONS) {
+ ds_put_format(string, "%s(", ofpact_instruction_name_from_type(
+ OVSINST_OFPIT11_WRITE_ACTIONS));
+ in_instruction = true;
+ n_actions = 0;
} else if (a->type == OFPACT_GOTO_TABLE) {
ds_put_format(string, "%s:%"PRIu8,
ofpact_instruction_name_from_type(
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index c899868..e5cb019 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -90,8 +90,9 @@
DEFINE_OFPACT(EXIT, ofpact_null, ofpact) \
\
/* Instructions */ \
- /* TODO:XXX Write-Actions, Write-Metadata */ \
+ /* TODO:XXX Write-Metadata */ \
DEFINE_OFPACT(CLEAR_ACTIONS, ofpact_null, ofpact) \
+ DEFINE_OFPACT(WRITE_ACTIONS, ofpact_null, ofpact) \
DEFINE_OFPACT(GOTO_TABLE, ofpact_goto_table, ofpact)
/* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */
@@ -150,10 +151,11 @@ ofpact_end(const struct ofpact *ofpacts, size_t ofpacts_len)
/* Action structure for each OFPACT_*. */
-/* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT, OFPACT_CLEAR_ACTIONS.
+/* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT, OFPACT_CLEAR_ACTIONS,
+ * OFPACT_WRITE_ACTIONS.
*
* Used for OFPAT10_STRIP_VLAN, NXAST_DEC_TTL, NXAST_POP_QUEUE, NXAST_EXIT,
- * OFPIT11_CLEAR_ACTIONS.
+ * OFPIT11_CLEAR_ACTIONS, OFPIT11_WRITE_ACTIONS.
*
* Action structure for actions that do not have any extra data beyond the
* action type. */
@@ -559,8 +561,9 @@ enum {
static inline bool
ofpact_is_instruction(const struct ofpact *a)
{
- /* TODO:XXX Write-Actions, Write-Metadata */
+ /* TODO:XXX Write-Metadata */
return a->type == OFPACT_CLEAR_ACTIONS
+ || a->type == OFPACT_WRITE_ACTIONS
|| a->type == OFPACT_GOTO_TABLE;
}
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 50925c9..4b7dc37 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -518,7 +518,8 @@ parse_named_instruction(enum ovs_instruction_type type,
break;
case OVSINST_OFPIT11_WRITE_ACTIONS:
- NOT_REACHED(); /* TODO:XXX */
+ ofpact_put_WRITE_ACTIONS(ofpacts);
+ str_to_ofpacts(flow, arg, ofpacts);
break;
case OVSINST_OFPIT11_CLEAR_ACTIONS:
@@ -572,9 +573,6 @@ str_to_inst_ofpacts(const struct flow *flow, char *str, struct ofpbuf *ofpacts)
}
/* TODO:XXX */
- if (inst_args[OVSINST_OFPIT11_WRITE_ACTIONS]) {
- ovs_fatal(0, "instruction write-actions is not supported yet");
- }
if (inst_args[OVSINST_OFPIT11_WRITE_METADATA]) {
ovs_fatal(0, "instruction write-metadata is not supported yet");
}
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index d35a0bd..1964837 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -5603,11 +5603,11 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
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.
- */
+ NOT_REACHED(); /* TODO:XXX */
+ break;
+
+ case OFPACT_WRITE_ACTIONS:
+ NOT_REACHED(); /* TODO:XXX */
break;
case OFPACT_GOTO_TABLE: {
diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at
index 0e77893..7469859 100644
--- a/tests/ofp-actions.at
+++ b/tests/ofp-actions.at
@@ -295,9 +295,21 @@ dnl Write-Metadata too long.
# bad OF1.1 instructions: OFPBIC_BAD_LEN
0002 0020 00000000 fedcba9876543210 ffffffffffffffff 0000000000000000
-dnl Write-Actions not supported yet.
-# bad OF1.1 instructions: OFPBIC_UNSUP_INST
-0003 0008 01 000000
+dnl Write-Actions non-zero padding
+# bad OF1.1 instructions: OFPBAC_BAD_ARGUMENT
+0003 0008 00000001
+
+dnl Write-Actions
+# instructions=write_actions(drop)
+# 0: 00 -> (none)
+# 1: 03 -> (none)
+# 2: 00 -> (none)
+# 3: 08 -> (none)
+# 4: 00 -> (none)
+# 5: 00 -> (none)
+# 6: 00 -> (none)
+# 7: 00 -> (none)
+0003 0008 00000000
dnl Clear-Actions too-long
# bad OF1.1 instructions: OFPBIC_BAD_LEN
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index f72c0b1..64c9c32 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -1139,6 +1139,10 @@ to \fBactions=\fR field.
.IP \fBclear_actions\fR
Clears all the actions in the action set immediately.
.
+.IP \fBwrite_actions(\fR[\fIaction\fR][\fB,\fIaction\fR...]\fB)
+Merges the specified actions(s) into the current actions set.
+The syntax of actions are same to \fBactions=\fR field.
+.
.IP \fBgoto_table\fR:\fItable\fR
Indicates the next table in the process pipeline.
.RE
--
1.7.1.1
More information about the dev
mailing list