diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index 0db685d298..d7ee84dac0 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -119,6 +119,8 @@ struct ovn_extend_table;
OVNACT(CHECK_IN_PORT_SEC, ovnact_result) \
OVNACT(CHECK_OUT_PORT_SEC, ovnact_result) \
OVNACT(COMMIT_ECMP_NH, ovnact_commit_ecmp_nh) \
+ OVNACT(CHK_ECMP_NH_MAC, ovnact_result) \
+ OVNACT(CHK_ECMP_NH, ovnact_result) \
/* enum ovnact_type, with a member OVNACT_ for each action. */
enum OVS_PACKED_ENUM ovnact_type {
diff --git a/lib/actions.c b/lib/actions.c
index a8ea94cf86..adbb42db4f 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -4554,6 +4554,52 @@ encode_COMMIT_ECMP_NH(const struct ovnact_commit_ecmp_nh *ecmp_nh,
commit_ecmp_learn_action(ofpacts, false, ecmp_nh->ipv6, ecmp_nh->proto);
}
+static void
+parse_chk_ecmp_nh_mac(struct action_context *ctx, const struct expr_field *dst,
+ struct ovnact_result *res)
+{
+ parse_ovnact_result(ctx, "chk_ecmp_nh_mac", NULL, dst, res);
+}
+
+static void
+format_CHK_ECMP_NH_MAC(const struct ovnact_result *res, struct ds *s)
+{
+ expr_field_format(&res->dst, s);
+ ds_put_cstr(s, " = chk_ecmp_nh_mac();");
+}
+
+static void
+encode_CHK_ECMP_NH_MAC(const struct ovnact_result *res,
+ const struct ovnact_encode_params *ep OVS_UNUSED,
+ struct ofpbuf *ofpacts)
+{
+ encode_result_action__(res, OFTABLE_ECMP_NH_MAC,
+ MLF_LOOKUP_COMMIT_ECMP_NH_BIT, ofpacts);
+}
+
+static void
+parse_chk_ecmp_nh(struct action_context *ctx, const struct expr_field *dst,
+ struct ovnact_result *res)
+{
+ parse_ovnact_result(ctx, "chk_ecmp_nh", NULL, dst, res);
+}
+
+static void
+format_CHK_ECMP_NH(const struct ovnact_result *res, struct ds *s)
+{
+ expr_field_format(&res->dst, s);
+ ds_put_cstr(s, " = chk_ecmp_nh();");
+}
+
+static void
+encode_CHK_ECMP_NH(const struct ovnact_result *res,
+ const struct ovnact_encode_params *ep OVS_UNUSED,
+ struct ofpbuf *ofpacts)
+{
+ encode_result_action__(res, OFTABLE_ECMP_NH,
+ MLF_LOOKUP_COMMIT_ECMP_NH_BIT, ofpacts);
+}
+
/* Parses an assignment or exchange or put_dhcp_opts action. */
static void
parse_set_action(struct action_context *ctx)
@@ -4630,6 +4676,14 @@ parse_set_action(struct action_context *ctx)
&& lexer_lookahead(ctx->lexer) == LEX_T_LPAREN) {
parse_check_out_port_sec(
ctx, &lhs, ovnact_put_CHECK_OUT_PORT_SEC(ctx->ovnacts));
+ } else if (!strcmp(ctx->lexer->token.s, "chk_ecmp_nh_mac")
+ && lexer_lookahead(ctx->lexer) == LEX_T_LPAREN) {
+ parse_chk_ecmp_nh_mac(ctx, &lhs,
+ ovnact_put_CHK_ECMP_NH_MAC(ctx->ovnacts));
+ } else if (!strcmp(ctx->lexer->token.s, "chk_ecmp_nh")
+ && lexer_lookahead(ctx->lexer) == LEX_T_LPAREN) {
+ parse_chk_ecmp_nh(ctx, &lhs,
+ ovnact_put_CHK_ECMP_NH(ctx->ovnacts));
} else {
parse_assignment_action(ctx, false, &lhs);
}
diff --git a/ovn-sb.xml b/ovn-sb.xml
index cc12ac9745..37a709f83b 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -2606,6 +2606,24 @@ tcp.flags = RST;
if it is routed via an ECMP route
+
+ R = check_ecmp_nh_mac();
+
+
+ This action checks if the packet under consideration matches
+ any flow in table 76. If it is so, then the 1-bit destination
+ register R is set to 1.
+
+
+
+ R = check_ecmp_nh();
+
+
+ This action checks if the packet under consideration matches
+ the any flow in table 77. If it is so, then the 1-bit destination
+ register R is set to 1.
+
+
diff --git a/tests/ovn.at b/tests/ovn.at
index 37bb04d54b..c8d144135f 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -2084,6 +2084,14 @@ commit_ecmp_nh(ipv6 = "true", proto = udp);
commit_ecmp_nh(proto = sctp);
Syntax error at `proto' invalid parameter.
+# chk_ecmp_nh_mac
+reg9[5] = chk_ecmp_nh_mac();
+ encodes as set_field:0/0x2000->reg10,resubmit(,76),move:NXM_NX_REG10[13]->OXM_OF_PKT_REG4[5]
+
+# chk_ecmp_nh
+reg9[5] = chk_ecmp_nh();
+ encodes as set_field:0/0x2000->reg10,resubmit(,77),move:NXM_NX_REG10[13]->OXM_OF_PKT_REG4[5]
+
# push/pop
push(xxreg0);push(xxreg1[10..20]);push(eth.src);pop(xxreg0[0..47]);pop(xxreg0[48..57]);pop(xxreg1);
formats as push(xxreg0); push(xxreg1[10..20]); push(eth.src); pop(xxreg0[0..47]); pop(xxreg0[48..57]); pop(xxreg1);
diff --git a/utilities/ovn-trace.c b/utilities/ovn-trace.c
index 6fed20aaab..d9e7129d92 100644
--- a/utilities/ovn-trace.c
+++ b/utilities/ovn-trace.c
@@ -3294,6 +3294,10 @@ trace_actions(const struct ovnact *ovnacts, size_t ovnacts_len,
break;
case OVNACT_COMMIT_ECMP_NH:
break;
+ case OVNACT_CHK_ECMP_NH_MAC:
+ break;
+ case OVNACT_CHK_ECMP_NH:
+ break;
}
}
ofpbuf_uninit(&stack);