* this flow when actions change header fields. */
struct flow flow;
+ /* stack for the push and pop actions.
+ * Each stack element is of the type "union mf_subvalue". */
+ struct ofpbuf stack;
+ union mf_subvalue init_stack[1024 / sizeof(union mf_subvalue)];
+
/* The packet corresponding to 'flow', or a null pointer if we are
* revalidating without a packet to refer to. */
const struct ofpbuf *packet;
return error;
}
-static int
-get_cfm_fault(const struct ofport *ofport_)
-{
- struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
-
- return ofport->cfm ? cfm_get_fault(ofport->cfm) : -1;
-}
-
-static int
-get_cfm_opup(const struct ofport *ofport_)
-{
- struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
-
- return ofport->cfm ? cfm_get_opup(ofport->cfm) : -1;
-}
-
-static int
-get_cfm_remote_mpids(const struct ofport *ofport_, const uint64_t **rmps,
- size_t *n_rmps)
+static bool
+get_cfm_status(const struct ofport *ofport_,
+ struct ofproto_cfm_status *status)
{
struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
if (ofport->cfm) {
- cfm_get_remote_mpids(ofport->cfm, rmps, n_rmps);
- return 0;
+ status->faults = cfm_get_fault(ofport->cfm);
+ status->remote_opstate = cfm_get_opup(ofport->cfm);
+ status->health = cfm_get_health(ofport->cfm);
+ cfm_get_remote_mpids(ofport->cfm, &status->rmps, &status->n_rmps);
+ return true;
} else {
- return -1;
+ return false;
}
}
-
-static int
-get_cfm_health(const struct ofport *ofport_)
-{
- struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
-
- return ofport->cfm ? cfm_get_health(ofport->cfm) : -1;
-}
\f
/* Spanning Tree. */
}
}
+static bool
+execute_set_mpls_ttl_action(struct action_xlate_ctx *ctx, uint8_t ttl)
+{
+ if (!eth_type_mpls(ctx->flow.dl_type)) {
+ return true;
+ }
+
+ set_mpls_lse_ttl(&ctx->flow.mpls_lse, ttl);
+ return false;
+}
+
static bool
execute_dec_mpls_ttl_action(struct action_xlate_ctx *ctx)
{
nxm_execute_reg_load(ofpact_get_REG_LOAD(a), &ctx->flow);
break;
+ case OFPACT_STACK_PUSH:
+ nxm_execute_stack_push(ofpact_get_STACK_PUSH(a), &ctx->flow,
+ &ctx->stack);
+ break;
+
+ case OFPACT_STACK_POP:
+ nxm_execute_stack_pop(ofpact_get_STACK_POP(a), &ctx->flow,
+ &ctx->stack);
+ break;
+
case OFPACT_PUSH_MPLS:
execute_mpls_push_action(ctx, ofpact_get_PUSH_MPLS(a)->ethertype);
break;
execute_mpls_pop_action(ctx, ofpact_get_POP_MPLS(a)->ethertype);
break;
+ case OFPACT_SET_MPLS_TTL:
+ if (execute_set_mpls_ttl_action(ctx, ofpact_get_SET_MPLS_TTL(a)->ttl)) {
+ goto out;
+ }
+ break;
+
case OFPACT_DEC_MPLS_TTL:
if (execute_dec_mpls_ttl_action(ctx)) {
goto out;
ctx->table_id = 0;
ctx->exit = false;
+ ofpbuf_use_stub(&ctx->stack, ctx->init_stack, sizeof ctx->init_stack);
+
if (ctx->ofproto->has_mirrors || hit_resubmit_limit) {
/* Do this conditionally because the copy is expensive enough that it
* shows up in profiles. */
}
fix_sflow_action(ctx);
}
+
+ ofpbuf_uninit(&ctx->stack);
}
/* Translates the 'ofpacts_len' bytes of "struct ofpact"s starting at 'ofpacts'
get_netflow_ids,
set_sflow,
set_cfm,
- get_cfm_fault,
- get_cfm_opup,
- get_cfm_remote_mpids,
- get_cfm_health,
+ get_cfm_status,
set_stp,
get_stp_status,
set_stp_port,