+ union mf_value src_value;
+ union mf_value dst_value;
+
+ mf_get_value(move->dst.field, flow, &dst_value);
+ mf_get_value(move->src.field, flow, &src_value);
+ bitwise_copy(&src_value, move->src.field->n_bytes, move->src.ofs,
+ &dst_value, move->dst.field->n_bytes, move->dst.ofs,
+ move->src.n_bits);
+ mf_set_flow_value(move->dst.field, &dst_value, flow);
+}
+
+void
+nxm_execute_reg_load(const struct ofpact_reg_load *load, struct flow *flow)
+{
+ mf_write_subfield_flow(&load->dst, &load->subvalue, flow);
+}
+
+void
+nxm_reg_load(const struct mf_subfield *dst, uint64_t src_data,
+ struct flow *flow)
+{
+ union mf_subvalue src_subvalue;
+ ovs_be64 src_data_be = htonll(src_data);
+
+ bitwise_copy(&src_data_be, sizeof src_data_be, 0,
+ &src_subvalue, sizeof src_subvalue, 0,
+ sizeof src_data_be * 8);
+ mf_write_subfield_flow(dst, &src_subvalue, flow);
+}
+\f
+/* nxm_parse_stack_action, works for both push() and pop(). */
+void
+nxm_parse_stack_action(struct ofpact_stack *stack_action, const char *s)
+{
+ s = mf_parse_subfield(&stack_action->subfield, s);
+ if (*s != '\0') {
+ ovs_fatal(0, "%s: trailing garbage following push or pop", s);
+ }
+}
+
+void
+nxm_format_stack_push(const struct ofpact_stack *push, struct ds *s)
+{
+ ds_put_cstr(s, "push:");
+ mf_format_subfield(&push->subfield, s);
+}
+
+void
+nxm_format_stack_pop(const struct ofpact_stack *pop, struct ds *s)
+{
+ ds_put_cstr(s, "pop:");
+ mf_format_subfield(&pop->subfield, s);
+}
+
+/* Common set for both push and pop actions. */
+static void
+stack_action_from_openflow__(const struct nx_action_stack *nasp,
+ struct ofpact_stack *stack_action)
+{
+ stack_action->subfield.field = mf_from_nxm_header(ntohl(nasp->field));
+ stack_action->subfield.ofs = ntohs(nasp->offset);
+ stack_action->subfield.n_bits = ntohs(nasp->n_bits);
+}
+
+static void
+nxm_stack_to_nxast__(const struct ofpact_stack *stack_action,
+ struct nx_action_stack *nasp)
+{
+ nasp->offset = htons(stack_action->subfield.ofs);
+ nasp->n_bits = htons(stack_action->subfield.n_bits);
+ nasp->field = htonl(stack_action->subfield.field->nxm_header);
+}
+
+enum ofperr
+nxm_stack_push_from_openflow(const struct nx_action_stack *nasp,
+ struct ofpbuf *ofpacts)
+{
+ struct ofpact_stack *push;
+
+ push = ofpact_put_STACK_PUSH(ofpacts);
+ stack_action_from_openflow__(nasp, push);
+
+ return nxm_stack_push_check(push, NULL);
+}
+
+enum ofperr
+nxm_stack_pop_from_openflow(const struct nx_action_stack *nasp,
+ struct ofpbuf *ofpacts)
+{
+ struct ofpact_stack *pop;