Update the "ct_commit;" logical flow action to optionally take a parameter, setting the value of "ct_mark" to a 32-bit integer. Supported ct_commit syntax now includes:
ct_commit; ct_commit(); ct_commit(ct_mark=1); Setting ct_mark via this type of logical flow results in an OpenFlow flow that looks like: actions=ct(commit,zone=NXM_NX_REG5[0..15],exec(set_field:0x1->ct_mark)) A future commit will make use of this feature. Signed-off-by: Russell Bryant <russ...@ovn.org> --- ovn/lib/actions.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- ovn/ovn-sb.xml | 13 ++++++++++-- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c index 42e7f3b..7119f62 100644 --- a/ovn/lib/actions.c +++ b/ovn/lib/actions.c @@ -184,7 +184,8 @@ add_prerequisite(struct action_context *ctx, const char *prerequisite) } static void -emit_ct(struct action_context *ctx, bool recirc_next, bool commit) +emit_ct(struct action_context *ctx, bool recirc_next, bool commit, + int *ct_mark) { struct ofpact_conntrack *ct = ofpact_put_CT(ctx->ofpacts); ct->flags |= commit ? NX_CT_F_COMMIT : 0; @@ -210,6 +211,58 @@ emit_ct(struct action_context *ctx, bool recirc_next, bool commit) /* CT only works with IP, so set up a prerequisite. */ add_prerequisite(ctx, "ip"); + + if (ct_mark) { + size_t set_field_offset = ctx->ofpacts->size; + ofpbuf_pull(ctx->ofpacts, set_field_offset); + + struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ctx->ofpacts); + sf->field = mf_from_id(MFF_CT_MARK); + sf->value.be32 = htonl(*ct_mark); + sf->mask.be32 = 0xFFFFFFFF; + + ctx->ofpacts->header = ofpbuf_push_uninit(ctx->ofpacts, set_field_offset); + ct = ctx->ofpacts->header; + ofpact_finish(ctx->ofpacts, &ct->ofpact); + } +} + +static void +parse_ct_commit_action(struct action_context *ctx) +{ + if (!lexer_match(ctx->lexer, LEX_T_LPAREN)) { + /* ct_commit; */ + emit_ct(ctx, false, true, NULL); + return; + } else if (lexer_match(ctx->lexer, LEX_T_RPAREN)) { + /* ct_commit(); */ + emit_ct(ctx, false, true, NULL); + return; + } + + /* ct_commit(ct_mark=0); */ + + if (!lexer_match_id(ctx->lexer, "ct_mark")) { + action_error(ctx, "Expected ct_mark after ct_commit("); + return; + } + + if (!lexer_match(ctx->lexer, LEX_T_EQUALS)) { + action_error(ctx, "Expected '=' after ct_commit(ct_mark"); + return; + } + + int mark_value = 0; + if (!action_get_int(ctx, &mark_value)) { + return; + } + + if (!lexer_match(ctx->lexer, LEX_T_RPAREN)) { + action_error(ctx, "Expected closing ) for ct_commit()"); + return; + } + + emit_ct(ctx, false, true, &mark_value); } static bool @@ -236,9 +289,9 @@ parse_action(struct action_context *ctx) action_syntax_error(ctx, "expecting `--'"); } } else if (lexer_match_id(ctx->lexer, "ct_next")) { - emit_ct(ctx, true, false); + emit_ct(ctx, true, false, NULL); } else if (lexer_match_id(ctx->lexer, "ct_commit")) { - emit_ct(ctx, false, true); + parse_ct_commit_action(ctx); } else { action_syntax_error(ctx, "expecting action"); } diff --git a/ovn/ovn-sb.xml b/ovn/ovn-sb.xml index 476e870..10fb9b5 100644 --- a/ovn/ovn-sb.xml +++ b/ovn/ovn-sb.xml @@ -904,15 +904,24 @@ </dd> <dt><code>ct_commit;</code></dt> + <dt><code>ct_commit(ct_mark=VALUE);</code></dt> <dd> <p> Commit the flow to the connection tracking entry associated - with it by a previous call to <code>ct_next</code>. + with it by a previous call to <code>ct_next</code>. When + the ct_mark=VALUE parameter is supplied, ct_mark will be set + to the 32-bit integer indicated by VALUE on the connection + tracking entry. </p> + <p> Note that if you want processing to continue in the next table, you must execute the <code>next</code> action after - <code>ct_commit</code>. + <code>ct_commit</code>. You may also leave out <code>next</code> + which will commit connection tracking state, and then drop the + packet. This could be useful for seting <code>ct_mark</code> + on a connection tracking entry before dropping a packet, + for example. </p> </dd> </dl> -- 2.5.0 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev