Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp> --- v4 - clear-actions part is split outed. - check zero padding - man page --- lib/ofp-actions.c | 33 ++++++++++++++++++++++++++------- lib/ofp-actions.h | 14 +++++++++----- lib/ofp-parse.c | 5 +---- ofproto/ofproto-dpif.c | 8 ++++++++ tests/ofp-actions.at | 12 ++++++++++-- utilities/ovs-ofctl.8.in | 3 +++ 6 files changed, 57 insertions(+), 18 deletions(-)
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 0774dd3..b4c2d10 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -904,7 +904,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]) { @@ -921,8 +930,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; } @@ -1000,6 +1008,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; @@ -1195,6 +1204,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(); } @@ -1285,6 +1295,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: return OFPERR_OFPET_BAD_ACTION; @@ -1402,6 +1413,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(); @@ -1477,10 +1489,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; @@ -1542,6 +1557,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; @@ -1788,6 +1804,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(); } @@ -1842,10 +1859,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 e41745c..666a4c5 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,11 @@ ofpact_end(const struct ofpact *ofpacts, size_t ofpacts_len) /* Action structure for each OFPACT_*. */ -/* OFPACT_STRIP_VLAN, OFPACT_DEC_TTL, OFPACT_POP_QUEUE, OFPACT_EXIT. +/* OFPACT_STRIP_VLAN, OFPACT_DEC_TTL, 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. */ @@ -547,8 +550,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 b6094e7..4ba775f 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -486,7 +486,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: @@ -536,9 +536,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 8947b91..1e5dce6 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -5567,6 +5567,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 1792532..3dea320 100644 --- a/tests/ofp-actions.at +++ b/tests/ofp-actions.at @@ -293,9 +293,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 e2cdd2c..6514630 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -1122,6 +1122,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 dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev