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 32 bit registers (MFF_REG0 - MFF_REG15) and 128 bit registers (MFF_XXREG0 - MFF_XXREG3) respectively. signed-off-by: Ankur Sharma <[email protected]> --- include/ovn/actions.h | 3 +++ ovn/lib/actions.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/include/ovn/actions.h b/include/ovn/actions.h index 1c0c67c..58b96a1 100644 --- a/include/ovn/actions.h +++ b/include/ovn/actions.h @@ -24,6 +24,7 @@ #include "openvswitch/dynamic-string.h" #include "openvswitch/hmap.h" #include "openvswitch/uuid.h" +#include "openvswitch/meta-flow.h" #include "util.h" struct expr; @@ -196,8 +197,10 @@ 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; }; /* OVNACT_CT_DNAT, OVNACT_CT_SNAT. */ diff --git a/ovn/lib/actions.c b/ovn/lib/actions.c index 7b7a894..c0c8da7 100644 --- a/ovn/lib/actions.c +++ b/ovn/lib/actions.c @@ -627,8 +627,28 @@ 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) { + + if (mf->id >= MFF_REG0 && mf->id <= MFF_REG15) { + cc->is_ct_mark_reg = true; + cc->ct_mark_reg = mf->id; + } else { + lexer_syntax_error(ctx->lexer, "input: %s, not a 32 bit " + "register", mf->name); + return; + } + } 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); @@ -642,9 +662,28 @@ 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) { + + cc->ct_label_mask = OVS_BE128_MAX; + const struct mf_field *mf = mf_from_name(ctx->lexer->token.s); + if (mf) { + if (mf->id >= MFF_XXREG0 && mf->id <= MFF_XXREG3) { + cc->is_ct_label_reg = true; + cc->ct_label_reg = mf->id; + } else { + lexer_syntax_error(ctx->lexer, "input: %s, not a 128 bit " + "register", mf->name); + return; + } + } 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 { @@ -713,14 +752,36 @@ encode_CT_COMMIT(const struct ovnact_ct_commit *cc, ofpbuf_pull(ofpacts, set_field_offset); 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 (cc->is_ct_mark_reg) { + struct ofpact_reg_move *move = ofpact_put_REG_MOVE(ofpacts); + + move->src.field = mf_from_id(cc->ct_mark_reg); + move->src.ofs = 0; + move->src.n_bits = 32; + move->dst.field = mf_from_id(MFF_CT_MARK); + move->dst.ofs = 0; + move->dst.n_bits = 32; + } else { + 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)) { + if (cc->is_ct_label_reg) { + struct ofpact_reg_move *move = ofpact_put_REG_MOVE(ofpacts); + + move->src.field = mf_from_id(cc->ct_label_reg); + move->src.ofs = 0; + move->src.n_bits = 128; + move->dst.field = mf_from_id(MFF_CT_LABEL); + move->dst.ofs = 0; + move->dst.n_bits = 128; + } else { 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); -- 1.8.3.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
