special = process_special(ctx, &ctx->xin->flow, peer,
ctx->xin->packet);
if (special) {
- ctx->xout->slow = special;
+ ctx->xout->slow |= special;
} else if (may_receive(peer, ctx)) {
if (xport_stp_forward_state(peer)) {
xlate_table_action(ctx, flow->in_port.ofp_port, 0, true);
struct ofpbuf *packet;
struct flow key;
- ovs_assert(!ctx->xout->slow || ctx->xout->slow == SLOW_CONTROLLER);
- ctx->xout->slow = SLOW_CONTROLLER;
+ ctx->xout->slow |= SLOW_CONTROLLER;
if (!ctx->xin->packet) {
return;
}
{
struct flow_wildcards *wc = &xout->wc;
struct flow *flow = &xin->flow;
+ struct rule_dpif *rule = NULL;
struct rule_actions *actions = NULL;
enum slow_path_reason special;
ctx.exit = false;
ctx.mpls_depth_delta = 0;
+ if (!xin->ofpacts && !ctx.rule) {
+ rule_dpif_lookup(ctx.xbridge->ofproto, flow, wc, &rule);
+ if (ctx.xin->resubmit_stats) {
+ rule_dpif_credit_stats(rule, ctx.xin->resubmit_stats);
+ }
+ ctx.rule = rule;
+ }
+ xout->fail_open = ctx.rule && rule_dpif_fail_open(ctx.rule);
+
if (xin->ofpacts) {
ofpacts = xin->ofpacts;
ofpacts_len = xin->ofpacts_len;
- } else if (xin->rule) {
- actions = rule_dpif_get_actions(xin->rule);
+ } else if (ctx.rule) {
+ actions = rule_dpif_get_actions(ctx.rule);
ofpacts = actions->ofpacts;
ofpacts_len = actions->ofpacts_len;
} else {
in_port = get_ofp_port(ctx.xbridge, flow->in_port.ofp_port);
special = process_special(&ctx, flow, in_port, ctx.xin->packet);
if (special) {
- ctx.xout->slow = special;
+ ctx.xout->slow |= special;
} else {
size_t sample_actions_len;
out:
rule_actions_unref(actions);
+ rule_dpif_unref(rule);
}
/* Sends 'packet' out 'ofport'.