Signed-off-by: Isaku Yamahata <yamah...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev