OVN allows only an integer (or masked integer) to be assigned to ct_mark and ct_label.
This patch, enhances the parser code to allow ct_mark and ct_label to be assigned from registers as well. Signed-off-by: Ankur Sharma <ankur.sha...@nutanix.com> --- include/ovn/actions.h | 3 +++ lib/actions.c | 72 ++++++++++++++++++++++++++++++++++++++++++++------- ovn-sb.xml | 41 +++++++++++++++++++++-------- tests/ovn.at | 31 ++++++++++++++++++++++ 4 files changed, 126 insertions(+), 21 deletions(-) diff --git a/include/ovn/actions.h b/include/ovn/actions.h index f4997e9..dda9a66 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -218,8 +218,11 @@ struct ovnact_ct_next { /* OVNACT_CT_COMMIT. */ struct ovnact_ct_commit { struct ovnact ovnact; + bool is_ct_mark_reg, is_ct_label_reg; /* If the value is from a register */ uint32_t ct_mark, ct_mark_mask; ovs_be128 ct_label, ct_label_mask; + enum mf_field_id ct_mark_reg, ct_label_reg; + uint16_t ct_mark_reg_bits, ct_label_reg_bits; }; /* OVNACT_CT_DNAT, OVNACT_CT_SNAT. */ diff --git a/lib/actions.c b/lib/actions.c index a999a4f..2b00469 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -634,8 +634,21 @@ parse_ct_commit_arg(struct action_context *ctx, } else if (ctx->lexer->token.type == LEX_T_MASKED_INTEGER) { cc->ct_mark = ntohll(ctx->lexer->token.value.integer); cc->ct_mark_mask = ntohll(ctx->lexer->token.mask.integer); + } else if (ctx->lexer->token.type == LEX_T_ID) { + + cc->ct_mark_mask = UINT32_MAX; + + const struct mf_field *mf = mf_from_name(ctx->lexer->token.s); + if (mf && mf_is_register(mf->id)) { + cc->is_ct_mark_reg = true; + cc->ct_mark_reg = mf->id; + } else { + lexer_syntax_error(ctx->lexer, "invalid field name: %s", + ctx->lexer->token.s); + return; + } } else { - lexer_syntax_error(ctx->lexer, "expecting integer"); + lexer_syntax_error(ctx->lexer, "invalid token type"); return; } lexer_get(ctx->lexer); @@ -649,9 +662,21 @@ parse_ct_commit_arg(struct action_context *ctx, } else if (ctx->lexer->token.type == LEX_T_MASKED_INTEGER) { cc->ct_label = ctx->lexer->token.value.be128_int; cc->ct_label_mask = ctx->lexer->token.mask.be128_int; + } else if (ctx->lexer->token.type == LEX_T_ID) { + + const struct mf_field *mf = mf_from_name(ctx->lexer->token.s); + if (mf && mf_is_register(mf->id)) { + cc->is_ct_label_reg = true; + cc->ct_label_reg = mf->id; + } else { + lexer_syntax_error(ctx->lexer, "invalid field name: %s", + ctx->lexer->token.s); + return; + } + } else { - lexer_syntax_error(ctx->lexer, "expecting integer"); - return; + lexer_syntax_error(ctx->lexer, "invalid token type"); + return; } lexer_get(ctx->lexer); } else { @@ -719,15 +744,42 @@ encode_CT_COMMIT(const struct ovnact_ct_commit *cc, size_t set_field_offset = ofpacts->size; ofpbuf_pull(ofpacts, set_field_offset); - if (cc->ct_mark_mask) { + if (cc->is_ct_mark_reg) { + struct ofpact_reg_move *move = ofpact_put_REG_MOVE(ofpacts); + const struct mf_field *src_reg = mf_from_id(cc->ct_mark_reg); + const struct mf_field *ct_mark = mf_from_id(MFF_CT_MARK); + + move->src.field = src_reg; + move->src.ofs = 0; + move->src.n_bits = src_reg->n_bits < ct_mark->n_bits ? + src_reg->n_bits : ct_mark->n_bits; + move->dst.field = mf_from_id(MFF_CT_MARK); + move->dst.ofs = 0; + move->dst.n_bits = src_reg->n_bits < ct_mark->n_bits ? + src_reg->n_bits : ct_mark->n_bits; + } else if (cc->ct_mark_mask) { const ovs_be32 value = htonl(cc->ct_mark); const ovs_be32 mask = htonl(cc->ct_mark_mask); - ofpact_put_set_field(ofpacts, mf_from_id(MFF_CT_MARK), &value, &mask); - } - - if (!ovs_be128_is_zero(cc->ct_label_mask)) { - ofpact_put_set_field(ofpacts, mf_from_id(MFF_CT_LABEL), &cc->ct_label, - &cc->ct_label_mask); + ofpact_put_set_field(ofpacts, mf_from_id(MFF_CT_MARK), &value, + &mask); + } + + if (cc->is_ct_label_reg) { + struct ofpact_reg_move *move = ofpact_put_REG_MOVE(ofpacts); + const struct mf_field *src_reg = mf_from_id(cc->ct_label_reg); + const struct mf_field *ct_label = mf_from_id(MFF_CT_LABEL); + + move->src.field = src_reg; + move->src.ofs = 0; + move->src.n_bits = src_reg->n_bits < ct_label->n_bits ? + src_reg->n_bits : ct_label->n_bits; + move->dst.field = ct_label; + move->dst.ofs = 0; + move->dst.n_bits = src_reg->n_bits < ct_label->n_bits ? + src_reg->n_bits : ct_label->n_bits; + } else if (!ovs_be128_is_zero(cc->ct_label_mask)) { + ofpact_put_set_field(ofpacts, mf_from_id(MFF_CT_LABEL), + &cc->ct_label, &cc->ct_label_mask); } ofpacts->header = ofpbuf_push_uninit(ofpacts, set_field_offset); diff --git a/ovn-sb.xml b/ovn-sb.xml index e5fb51a..c8306ab 100644 --- a/ovn-sb.xml +++ b/ovn-sb.xml @@ -1243,20 +1243,39 @@ </dd> <dt><code>ct_commit;</code></dt> - <dt><code>ct_commit(ct_mark=<var>value[/mask]</var>);</code></dt> - <dt><code>ct_commit(ct_label=<var>value[/mask]</var>);</code></dt> - <dt><code>ct_commit(ct_mark=<var>value[/mask]</var>, ct_label=<var>value[/mask]</var>);</code></dt> + <dt> + <code> + ct_commit(ct_mark=(<var>value[/mask]</var> OR <var>regX</var> OR <var>xregX</var> OR <var>xxregX</var>)); + </code> + </dt> + <dt> + <code> + ct_commit(ct_label=(<var>value[/mask]</var> OR <var>regX</var> OR <var>xregX</var> OR <var>xxregX</var>)); + </code> + </dt> + <dt> + <code> + ct_commit(ct_mark=(<var>value[/mask]</var> OR <var>regX</var> OR <var>xregX</var> OR <var>xxregX</var>), + ct_label=(<var>value[/mask]</var> OR <var>regX</var> OR <var>xregX</var> OR <var>xxregX</var> )); + </code> + </dt> <dd> <p> Commit the flow to the connection tracking entry associated with it - by a previous call to <code>ct_next</code>. When - <code>ct_mark=<var>value[/mask]</var></code> and/or - <code>ct_label=<var>value[/mask]</var></code> are supplied, - <code>ct_mark</code> and/or <code>ct_label</code> will be set to the - values indicated by <var>value[/mask]</var> on the connection - tracking entry. <code>ct_mark</code> is a 32-bit field. - <code>ct_label</code> is a 128-bit field. The <var>value[/mask]</var> - should be specified in hex string if more than 64bits are to be used. + by a previous call to <code>ct_next</code>. When + <code>ct_mark=<var>value[/mask]</var> OR <var>regX</var> OR + <var>xregX</var> OR <var>xxregX</var> </code> and/or + <code>ct_label=<var>value[/mask]</var> OR <var>regX + </var> OR <var>xregX</var> OR <var>xxregX</var> </code> are + supplied, <code>ct_mark</code> and/or <code>ct_label</code> + will be set to the values indicated by <var>value[/mask]</var> + or 32 bit/128 bit registers on the connection tracking entry. + <code>ct_mark</code> is a 32-bit field and hence will read + value only from a 32 bit register (reg0 - reg9). + <code>ct_label</code> is a 128-bit field and hence + will read value only from a 128 bit register (xxreg0 - xxreg1). + The <var>value[/mask]</var> should be specified in hex string if + more than 64bits are to be used. </p> <p> diff --git a/tests/ovn.at b/tests/ovn.at index 3e20c84..042abee 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -1037,6 +1037,37 @@ ct_commit(ct_label=18446744073709551615); ct_commit(ct_label=18446744073709551616); Decimal constants must be less than 2**64. +ct_commit(ct_label=xxreg1); + formats as ct_commit; + encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(move:NXM_NX_XXREG1[]->NXM_NX_CT_LABEL[])) + has prereqs ip + +ct_commit(ct_label=xreg1); + formats as ct_commit; + encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(move:OXM_OF_PKT_REG1[]->NXM_NX_CT_LABEL[0..63])) + has prereqs ip + +ct_commit(ct_label=reg1); + formats as ct_commit; + encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(move:NXM_NX_REG1[]->NXM_NX_CT_LABEL[0..31])) + has prereqs ip + +ct_commit(ct_mark=xxreg1); + formats as ct_commit(ct_mark=0); + encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(move:NXM_NX_XXREG1[0..31]->NXM_NX_CT_MARK[])) + has prereqs ip + +ct_commit(ct_mark=xreg1); + formats as ct_commit(ct_mark=0); + encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(move:OXM_OF_PKT_REG1[0..31]->NXM_NX_CT_MARK[])) + has prereqs ip + +ct_commit(ct_mark=reg1); + formats as ct_commit(ct_mark=0); + encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(move:NXM_NX_REG1[]->NXM_NX_CT_MARK[])) + has prereqs ip + + # ct_dnat ct_dnat; encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat) -- 1.8.3.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev