static void
xlate_recursively(struct xlate_ctx *ctx, struct rule_dpif *rule)
- OVS_RELEASES(rule)
{
struct rule_dpif *old_rule = ctx->rule;
struct rule_actions *actions;
rule_actions_unref(actions);
ctx->rule = old_rule;
ctx->recurse--;
-
- rule_dpif_release(rule);
}
static void
struct rule_dpif *rule;
ofp_port_t old_in_port = ctx->xin->flow.in_port.ofp_port;
uint8_t old_table_id = ctx->table_id;
- bool got_rule;
ctx->table_id = table_id;
* original input port (otherwise OFPP_NORMAL and OFPP_IN_PORT will
* have surprising behavior). */
ctx->xin->flow.in_port.ofp_port = in_port;
- got_rule = rule_dpif_lookup_in_table(ctx->xbridge->ofproto,
- &ctx->xin->flow, &ctx->xout->wc,
- table_id, &rule);
+ rule_dpif_lookup_in_table(ctx->xbridge->ofproto,
+ &ctx->xin->flow, &ctx->xout->wc,
+ table_id, &rule);
ctx->xin->flow.in_port.ofp_port = old_in_port;
if (ctx->xin->resubmit_hook) {
ctx->xin->resubmit_hook(ctx->xin, rule, ctx->recurse);
}
- if (got_rule) {
- xlate_recursively(ctx, rule);
- } else if (may_packet_in) {
+ if (!rule && may_packet_in) {
struct xport *xport;
/* XXX
choose_miss_rule(xport ? xport->config : 0,
ctx->xbridge->miss_rule,
ctx->xbridge->no_packet_in_rule, &rule);
+ }
+ if (rule) {
xlate_recursively(ctx, rule);
+ rule_dpif_unref(rule);
}
ctx->table_id = old_table_id;
xlate_learn_action(struct xlate_ctx *ctx,
const struct ofpact_learn *learn)
{
- struct ofputil_flow_mod *fm;
+ uint64_t ofpacts_stub[1024 / 8];
+ struct ofputil_flow_mod fm;
struct ofpbuf ofpacts;
ctx->xout->has_learn = true;
return;
}
- fm = xmalloc(sizeof *fm);
- ofpbuf_init(&ofpacts, 0);
- learn_execute(learn, &ctx->xin->flow, fm, &ofpacts);
-
- ofproto_dpif_flow_mod(ctx->xbridge->ofproto, fm);
+ ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
+ learn_execute(learn, &ctx->xin->flow, &fm, &ofpacts);
+ ofproto_dpif_flow_mod(ctx->xbridge->ofproto, &fm);
+ ofpbuf_uninit(&ofpacts);
}
static void