|
|
ebb439 |
From 224b2ba1c53279f33eafe76ac46ffdf347f8a077 Mon Sep 17 00:00:00 2001
|
|
|
ebb439 |
From: Numan Siddique <numans@ovn.org>
|
|
|
ebb439 |
Date: Fri, 20 Nov 2020 16:22:53 +0530
|
|
|
ebb439 |
Subject: [PATCH] Fix OVN update issue when ovn-controller is updated first
|
|
|
ebb439 |
from 20.06 to 20.09.
|
|
|
ebb439 |
|
|
|
ebb439 |
The commit in the Fixes tag changed the ct_commit signature from
|
|
|
ebb439 |
ct_commit(..) to ct_commit{ ..}. When ovn-controllers are updated
|
|
|
ebb439 |
to a vesion which has this change and if ovn-northd is still not
|
|
|
ebb439 |
udated to this version, then the logical flow with the action
|
|
|
ebb439 |
ct_commit(..) will be rejected by ovn-controllers resulting in
|
|
|
ebb439 |
datapath disruptions. OVN recommends ovn-controller updates before
|
|
|
ebb439 |
ovn-northd, but it is broken now. This patch fixes this issue by
|
|
|
ebb439 |
adding back the support for the old ct_commit(..). We now support
|
|
|
ebb439 |
both the versions of ct_commit.
|
|
|
ebb439 |
|
|
|
ebb439 |
Fixes: 6cfb44a76c61("Used nested actions in ct_commit)
|
|
|
ebb439 |
CC: Mark Michelson <mmichels@redhat.com>
|
|
|
ebb439 |
Signed-off-by: Numan Siddique <numans@ovn.org>
|
|
|
ebb439 |
Acked-by: Flavio Fernandes <flavio@flaviof.com>
|
|
|
ebb439 |
---
|
|
|
ebb439 |
include/ovn/actions.h | 10 ++-
|
|
|
ebb439 |
lib/actions.c | 137 ++++++++++++++++++++++++++++++++++++++++--
|
|
|
ebb439 |
tests/ovn.at | 44 ++++++++++++++
|
|
|
ebb439 |
utilities/ovn-trace.c | 3 +-
|
|
|
ebb439 |
4 files changed, 186 insertions(+), 8 deletions(-)
|
|
|
ebb439 |
|
|
|
ebb439 |
diff --git a/include/ovn/actions.h b/include/ovn/actions.h
|
|
|
ebb439 |
index 7ba24cd60..9c1ebf4aa 100644
|
|
|
ebb439 |
--- a/include/ovn/actions.h
|
|
|
ebb439 |
+++ b/include/ovn/actions.h
|
|
|
ebb439 |
@@ -61,7 +61,8 @@ struct ovn_extend_table;
|
|
|
ebb439 |
OVNACT(EXCHANGE, ovnact_move) \
|
|
|
ebb439 |
OVNACT(DEC_TTL, ovnact_null) \
|
|
|
ebb439 |
OVNACT(CT_NEXT, ovnact_ct_next) \
|
|
|
ebb439 |
- OVNACT(CT_COMMIT, ovnact_nest) \
|
|
|
ebb439 |
+ OVNACT(CT_COMMIT_V1, ovnact_ct_commit_v1) \
|
|
|
ebb439 |
+ OVNACT(CT_COMMIT_V2, ovnact_nest) \
|
|
|
ebb439 |
OVNACT(CT_DNAT, ovnact_ct_nat) \
|
|
|
ebb439 |
OVNACT(CT_SNAT, ovnact_ct_nat) \
|
|
|
ebb439 |
OVNACT(CT_LB, ovnact_ct_lb) \
|
|
|
ebb439 |
@@ -230,6 +231,13 @@ struct ovnact_ct_next {
|
|
|
ebb439 |
uint8_t ltable; /* Logical table ID of next table. */
|
|
|
ebb439 |
};
|
|
|
ebb439 |
|
|
|
ebb439 |
+/* OVNACT_CT_COMMIT_V1. */
|
|
|
ebb439 |
+struct ovnact_ct_commit_v1 {
|
|
|
ebb439 |
+ struct ovnact ovnact;
|
|
|
ebb439 |
+ uint32_t ct_mark, ct_mark_mask;
|
|
|
ebb439 |
+ ovs_be128 ct_label, ct_label_mask;
|
|
|
ebb439 |
+};
|
|
|
ebb439 |
+
|
|
|
ebb439 |
/* OVNACT_CT_DNAT, OVNACT_CT_SNAT. */
|
|
|
ebb439 |
struct ovnact_ct_nat {
|
|
|
ebb439 |
struct ovnact ovnact;
|
|
|
ebb439 |
diff --git a/lib/actions.c b/lib/actions.c
|
|
|
ebb439 |
index 3219ab3be..4a9813218 100644
|
|
|
ebb439 |
--- a/lib/actions.c
|
|
|
ebb439 |
+++ b/lib/actions.c
|
|
|
ebb439 |
@@ -627,16 +627,75 @@ ovnact_ct_next_free(struct ovnact_ct_next *a OVS_UNUSED)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
+static void
|
|
|
ebb439 |
+parse_ct_commit_v1_arg(struct action_context *ctx,
|
|
|
ebb439 |
+ struct ovnact_ct_commit_v1 *cc)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ if (lexer_match_id(ctx->lexer, "ct_mark")) {
|
|
|
ebb439 |
+ if (!lexer_force_match(ctx->lexer, LEX_T_EQUALS)) {
|
|
|
ebb439 |
+ return;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ if (ctx->lexer->token.type == LEX_T_INTEGER) {
|
|
|
ebb439 |
+ cc->ct_mark = ntohll(ctx->lexer->token.value.integer);
|
|
|
ebb439 |
+ cc->ct_mark_mask = UINT32_MAX;
|
|
|
ebb439 |
+ } else if (ctx->lexer->token.type == LEX_T_MASKED_INTEGER) {
|
|
|
ebb439 |
+ cc->ct_mark = ntohll(ctx->lexer->token.value.integer);
|
|
|
ebb439 |
+ cc->ct_mark_mask = ntohll(ctx->lexer->token.mask.integer);
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
+ lexer_syntax_error(ctx->lexer, "expecting integer");
|
|
|
ebb439 |
+ return;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ lexer_get(ctx->lexer);
|
|
|
ebb439 |
+ } else if (lexer_match_id(ctx->lexer, "ct_label")) {
|
|
|
ebb439 |
+ if (!lexer_force_match(ctx->lexer, LEX_T_EQUALS)) {
|
|
|
ebb439 |
+ return;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ if (ctx->lexer->token.type == LEX_T_INTEGER) {
|
|
|
ebb439 |
+ cc->ct_label = ctx->lexer->token.value.be128_int;
|
|
|
ebb439 |
+ cc->ct_label_mask = OVS_BE128_MAX;
|
|
|
ebb439 |
+ } else if (ctx->lexer->token.type == LEX_T_MASKED_INTEGER) {
|
|
|
ebb439 |
+ cc->ct_label = ctx->lexer->token.value.be128_int;
|
|
|
ebb439 |
+ cc->ct_label_mask = ctx->lexer->token.mask.be128_int;
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
+ lexer_syntax_error(ctx->lexer, "expecting integer");
|
|
|
ebb439 |
+ return;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ lexer_get(ctx->lexer);
|
|
|
ebb439 |
+ } else {
|
|
|
ebb439 |
+ lexer_syntax_error(ctx->lexer, NULL);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static void
|
|
|
ebb439 |
+parse_CT_COMMIT_V1(struct action_context *ctx)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ add_prerequisite(ctx, "ip");
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ struct ovnact_ct_commit_v1 *ct_commit =
|
|
|
ebb439 |
+ ovnact_put_CT_COMMIT_V1(ctx->ovnacts);
|
|
|
ebb439 |
+ if (lexer_match(ctx->lexer, LEX_T_LPAREN)) {
|
|
|
ebb439 |
+ while (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
|
|
|
ebb439 |
+ parse_ct_commit_v1_arg(ctx, ct_commit);
|
|
|
ebb439 |
+ if (ctx->lexer->error) {
|
|
|
ebb439 |
+ return;
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ lexer_match(ctx->lexer, LEX_T_COMMA);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
parse_CT_COMMIT(struct action_context *ctx)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
if (ctx->lexer->token.type == LEX_T_LCURLY) {
|
|
|
ebb439 |
- parse_nested_action(ctx, OVNACT_CT_COMMIT, "ip",
|
|
|
ebb439 |
+ parse_nested_action(ctx, OVNACT_CT_COMMIT_V2, "ip",
|
|
|
ebb439 |
WR_CT_COMMIT);
|
|
|
ebb439 |
+ } else if (ctx->lexer->token.type == LEX_T_LPAREN) {
|
|
|
ebb439 |
+ parse_CT_COMMIT_V1(ctx);
|
|
|
ebb439 |
} else {
|
|
|
ebb439 |
/* Add an empty nested action to allow for "ct_commit;" syntax */
|
|
|
ebb439 |
add_prerequisite(ctx, "ip");
|
|
|
ebb439 |
- struct ovnact_nest *on = ovnact_put(ctx->ovnacts, OVNACT_CT_COMMIT,
|
|
|
ebb439 |
+ struct ovnact_nest *on = ovnact_put(ctx->ovnacts, OVNACT_CT_COMMIT_V2,
|
|
|
ebb439 |
OVNACT_ALIGN(sizeof *on));
|
|
|
ebb439 |
on->nested_len = 0;
|
|
|
ebb439 |
on->nested = NULL;
|
|
|
ebb439 |
@@ -644,7 +703,73 @@ parse_CT_COMMIT(struct action_context *ctx)
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
-format_CT_COMMIT(const struct ovnact_nest *on, struct ds *s)
|
|
|
ebb439 |
+format_CT_COMMIT_V1(const struct ovnact_ct_commit_v1 *cc, struct ds *s)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ ds_put_cstr(s, "ct_commit(");
|
|
|
ebb439 |
+ if (cc->ct_mark_mask) {
|
|
|
ebb439 |
+ ds_put_format(s, "ct_mark=%#"PRIx32, cc->ct_mark);
|
|
|
ebb439 |
+ if (cc->ct_mark_mask != UINT32_MAX) {
|
|
|
ebb439 |
+ ds_put_format(s, "/%#"PRIx32, cc->ct_mark_mask);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ if (!ovs_be128_is_zero(cc->ct_label_mask)) {
|
|
|
ebb439 |
+ if (ds_last(s) != '(') {
|
|
|
ebb439 |
+ ds_put_cstr(s, ", ");
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ ds_put_format(s, "ct_label=");
|
|
|
ebb439 |
+ ds_put_hex(s, &cc->ct_label, sizeof cc->ct_label);
|
|
|
ebb439 |
+ if (!ovs_be128_equals(cc->ct_label_mask, OVS_BE128_MAX)) {
|
|
|
ebb439 |
+ ds_put_char(s, '/');
|
|
|
ebb439 |
+ ds_put_hex(s, &cc->ct_label_mask, sizeof cc->ct_label_mask);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ if (!ds_chomp(s, '(')) {
|
|
|
ebb439 |
+ ds_put_char(s, ')');
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+ ds_put_char(s, ';');
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static void
|
|
|
ebb439 |
+encode_CT_COMMIT_V1(const struct ovnact_ct_commit_v1 *cc,
|
|
|
ebb439 |
+ const struct ovnact_encode_params *ep OVS_UNUSED,
|
|
|
ebb439 |
+ struct ofpbuf *ofpacts)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+ struct ofpact_conntrack *ct = ofpact_put_CT(ofpacts);
|
|
|
ebb439 |
+ ct->flags = NX_CT_F_COMMIT;
|
|
|
ebb439 |
+ ct->recirc_table = NX_CT_RECIRC_NONE;
|
|
|
ebb439 |
+ ct->zone_src.field = mf_from_id(MFF_LOG_CT_ZONE);
|
|
|
ebb439 |
+ ct->zone_src.ofs = 0;
|
|
|
ebb439 |
+ ct->zone_src.n_bits = 16;
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ size_t set_field_offset = ofpacts->size;
|
|
|
ebb439 |
+ ofpbuf_pull(ofpacts, set_field_offset);
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (cc->ct_mark_mask) {
|
|
|
ebb439 |
+ const ovs_be32 value = htonl(cc->ct_mark);
|
|
|
ebb439 |
+ const ovs_be32 mask = htonl(cc->ct_mark_mask);
|
|
|
ebb439 |
+ ofpact_put_set_field(ofpacts, mf_from_id(MFF_CT_MARK), &value, &mask);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ if (!ovs_be128_is_zero(cc->ct_label_mask)) {
|
|
|
ebb439 |
+ ofpact_put_set_field(ofpacts, mf_from_id(MFF_CT_LABEL), &cc->ct_label,
|
|
|
ebb439 |
+ &cc->ct_label_mask);
|
|
|
ebb439 |
+ }
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ ofpacts->header = ofpbuf_push_uninit(ofpacts, set_field_offset);
|
|
|
ebb439 |
+ ct = ofpacts->header;
|
|
|
ebb439 |
+ ofpact_finish(ofpacts, &ct->ofpact);
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static void
|
|
|
ebb439 |
+ovnact_ct_commit_v1_free(struct ovnact_ct_commit_v1 *cc OVS_UNUSED)
|
|
|
ebb439 |
+{
|
|
|
ebb439 |
+}
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+static void
|
|
|
ebb439 |
+format_CT_COMMIT_V2(const struct ovnact_nest *on, struct ds *s)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
if (on->nested_len) {
|
|
|
ebb439 |
format_nested_action(on, "ct_commit", s);
|
|
|
ebb439 |
@@ -654,9 +779,9 @@ format_CT_COMMIT(const struct ovnact_nest *on, struct ds *s)
|
|
|
ebb439 |
}
|
|
|
ebb439 |
|
|
|
ebb439 |
static void
|
|
|
ebb439 |
-encode_CT_COMMIT(const struct ovnact_nest *on,
|
|
|
ebb439 |
- const struct ovnact_encode_params *ep OVS_UNUSED,
|
|
|
ebb439 |
- struct ofpbuf *ofpacts)
|
|
|
ebb439 |
+encode_CT_COMMIT_V2(const struct ovnact_nest *on,
|
|
|
ebb439 |
+ const struct ovnact_encode_params *ep OVS_UNUSED,
|
|
|
ebb439 |
+ struct ofpbuf *ofpacts)
|
|
|
ebb439 |
{
|
|
|
ebb439 |
struct ofpact_conntrack *ct = ofpact_put_CT(ofpacts);
|
|
|
ebb439 |
ct->flags = NX_CT_F_COMMIT;
|
|
|
ebb439 |
diff --git a/tests/ovn.at b/tests/ovn.at
|
|
|
ebb439 |
index f56f8a696..396e60eeb 100644
|
|
|
ebb439 |
--- a/tests/ovn.at
|
|
|
ebb439 |
+++ b/tests/ovn.at
|
|
|
ebb439 |
@@ -1102,6 +1102,50 @@ ct_commit { ct_label=0x181716151413121110090807060504030201; };
|
|
|
ebb439 |
ct_commit { ip4.dst = 192.168.0.1; };
|
|
|
ebb439 |
Field ip4.dst is not modifiable.
|
|
|
ebb439 |
|
|
|
ebb439 |
+# Legact ct_commit_v1 action.
|
|
|
ebb439 |
+ct_commit();
|
|
|
ebb439 |
+ formats as ct_commit;
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15])
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_mark=1);
|
|
|
ebb439 |
+ formats as ct_commit(ct_mark=0x1);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_mark=1/1);
|
|
|
ebb439 |
+ formats as ct_commit(ct_mark=0x1/0x1);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_label=1);
|
|
|
ebb439 |
+ formats as ct_commit(ct_label=0x1);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_label=1/1);
|
|
|
ebb439 |
+ formats as ct_commit(ct_label=0x1/0x1);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_mark=1, ct_label=2);
|
|
|
ebb439 |
+ formats as ct_commit(ct_mark=0x1, ct_label=0x2);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+
|
|
|
ebb439 |
+ct_commit(ct_label=0x01020304050607080910111213141516);
|
|
|
ebb439 |
+ formats as ct_commit(ct_label=0x1020304050607080910111213141516);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_label=0x181716151413121110090807060504030201);
|
|
|
ebb439 |
+ formats as ct_commit(ct_label=0x16151413121110090807060504030201);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_label=18446744073709551615);
|
|
|
ebb439 |
+ formats as ct_commit(ct_label=0xffffffffffffffff);
|
|
|
ebb439 |
+ encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
|
|
|
ebb439 |
+ has prereqs ip
|
|
|
ebb439 |
+ct_commit(ct_label=18446744073709551616);
|
|
|
ebb439 |
+ Decimal constants must be less than 2**64.
|
|
|
ebb439 |
+
|
|
|
ebb439 |
ct_mark = 12345
|
|
|
ebb439 |
Field ct_mark is not modifiable.
|
|
|
ebb439 |
ct_label = 0xcafe
|
|
|
ebb439 |
diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c
|
|
|
ebb439 |
index cc1cd1b16..8421c0682 100644
|
|
|
ebb439 |
--- a/utilities/ovn-trace.c
|
|
|
ebb439 |
+++ b/utilities/ovn-trace.c
|
|
|
ebb439 |
@@ -2334,7 +2334,8 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len,
|
|
|
ebb439 |
execute_ct_next(ovnact_get_CT_NEXT(a), dp, uflow, pipeline, super);
|
|
|
ebb439 |
break;
|
|
|
ebb439 |
|
|
|
ebb439 |
- case OVNACT_CT_COMMIT:
|
|
|
ebb439 |
+ case OVNACT_CT_COMMIT_V1:
|
|
|
ebb439 |
+ case OVNACT_CT_COMMIT_V2:
|
|
|
ebb439 |
/* Nothing to do. */
|
|
|
ebb439 |
break;
|
|
|
ebb439 |
|
|
|
ebb439 |
--
|
|
|
ebb439 |
2.28.0
|
|
|
ebb439 |
|