There was a missing dot in the commit message > On Jul 31, 2015, at 1:40 PM, Jarno Rajahalme <jrajaha...@nicira.com> wrote: > > Acked-by: Jarno Rajahalme <jrajaha...@nicira.com> > >> On Jul 29, 2015, at 11:42 PM, Ben Pfaff <b...@nicira.com> wrote: >> >> Until now, struct xlate_out has embedded an ofpbuf for actions and a large >> stub for it, which xlate_actions() filled in during the flow translation >> process This commit removes the embedded ofpbuf and stub, instead putting a >> pointer to an ofpbuf into struct xlate_in, for a caller to fill in with a >> pointer to its own structure if desired. (If none is supplied, >> xlate_actions() uses an internal scratch buffer and destroys it before >> returning.) >> >> This commit eliminates the last large data structure from >> struct xlate_out, making the initialization of an entire xlate_out at >> the beginning of xlate_actions() now reasonable. More members will be >> eliminated in upcoming commits, but this is no longer essential. >> >> Signed-off-by: Ben Pfaff <b...@nicira.com> >> --- >> ofproto/ofproto-dpif-upcall.c | 44 +++++++++--------- >> ofproto/ofproto-dpif-xlate.c | 101 >> +++++++++++++++++++++--------------------- >> ofproto/ofproto-dpif-xlate.h | 11 ++--- >> ofproto/ofproto-dpif.c | 20 ++++++--- >> 4 files changed, 91 insertions(+), 85 deletions(-) >> >> diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c >> index 6a02d60..59010c2 100644 >> --- a/ofproto/ofproto-dpif-upcall.c >> +++ b/ofproto/ofproto-dpif-upcall.c >> @@ -170,6 +170,7 @@ struct upcall { >> >> bool xout_initialized; /* True if 'xout' must be uninitialized. */ >> struct xlate_out xout; /* Result of xlate_actions(). */ >> + struct ofpbuf odp_actions; /* Datapath actions from >> xlate_actions(). */ >> struct flow_wildcards wc; /* Dependencies that megaflow must match. >> */ >> struct ofpbuf put_actions; /* Actions 'put' in the fastpath. */ >> >> @@ -190,6 +191,8 @@ struct upcall { >> const struct nlattr *key; /* Datapath flow key. */ >> size_t key_len; /* Datapath flow key length. */ >> const struct nlattr *out_tun_key; /* Datapath output tunnel key. */ >> + >> + uint64_t odp_actions_stub[1024 / 8]; /* Stub for odp_actions. */ >> }; >> >> /* 'udpif_key's are responsible for tracking the little bit of state udpif >> @@ -706,7 +709,8 @@ recv_upcalls(struct handler *handler) >> pkt_metadata_from_flow(&dupcall->packet.md, flow); >> flow_extract(&dupcall->packet, flow); >> >> - error = process_upcall(udpif, upcall, NULL, &upcall->wc); >> + error = process_upcall(udpif, upcall, >> + &upcall->odp_actions, &upcall->wc); >> if (error) { >> goto cleanup; >> } >> @@ -927,6 +931,8 @@ upcall_receive(struct upcall *upcall, const struct >> dpif_backer *backer, >> upcall->pmd_id = pmd_id; >> upcall->type = type; >> upcall->userdata = userdata; >> + ofpbuf_use_stub(&upcall->odp_actions, upcall->odp_actions_stub, >> + sizeof upcall->odp_actions_stub); >> ofpbuf_init(&upcall->put_actions, 0); >> >> upcall->xout_initialized = false; >> @@ -956,8 +962,7 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall, >> stats.tcp_flags = ntohs(upcall->flow->tcp_flags); >> >> xlate_in_init(&xin, upcall->ofproto, upcall->flow, upcall->in_port, NULL, >> - stats.tcp_flags, upcall->packet, wc); >> - xin.odp_actions = odp_actions; >> + stats.tcp_flags, upcall->packet, wc, odp_actions); >> >> if (upcall->type == DPIF_UC_MISS) { >> xin.resubmit_stats = &stats; >> @@ -1011,8 +1016,7 @@ upcall_xlate(struct udpif *udpif, struct upcall >> *upcall, >> >> if (!upcall->xout.slow) { >> ofpbuf_use_const(&upcall->put_actions, >> - upcall->xout.odp_actions->data, >> - upcall->xout.odp_actions->size); >> + odp_actions->data, odp_actions->size); >> } else { >> ofpbuf_init(&upcall->put_actions, 0); >> compose_slow_path(udpif, &upcall->xout, upcall->flow, >> @@ -1035,6 +1039,7 @@ upcall_uninit(struct upcall *upcall) >> if (upcall->xout_initialized) { >> xlate_out_uninit(&upcall->xout); >> } >> + ofpbuf_uninit(&upcall->odp_actions); >> ofpbuf_uninit(&upcall->put_actions); >> if (upcall->ukey) { >> if (!upcall->ukey_persists) { >> @@ -1234,7 +1239,7 @@ handle_upcalls(struct udpif *udpif, struct upcall >> *upcalls, >> * actions were composed assuming that the packet contained no >> * VLAN. So, we must remove the VLAN header from the packet >> before >> * trying to execute the actions. */ >> - if (upcall->xout.odp_actions->size) { >> + if (upcall->odp_actions.size) { >> eth_pop_vlan(CONST_CAST(struct dp_packet *, upcall->packet)); >> } >> >> @@ -1272,15 +1277,15 @@ handle_upcalls(struct udpif *udpif, struct upcall >> *upcalls, >> op->dop.u.flow_put.actions_len = ukey->actions->size; >> } >> >> - if (upcall->xout.odp_actions->size) { >> + if (upcall->odp_actions.size) { >> op = &ops[n_ops++]; >> op->ukey = NULL; >> op->dop.type = DPIF_OP_EXECUTE; >> op->dop.u.execute.packet = CONST_CAST(struct dp_packet *, packet); >> odp_key_to_pkt_metadata(upcall->key, upcall->key_len, >> &op->dop.u.execute.packet->md); >> - op->dop.u.execute.actions = upcall->xout.odp_actions->data; >> - op->dop.u.execute.actions_len = upcall->xout.odp_actions->size; >> + op->dop.u.execute.actions = upcall->odp_actions.data; >> + op->dop.u.execute.actions_len = upcall->odp_actions.size; >> op->dop.u.execute.needs_help = (upcall->xout.slow & SLOW_ACTION) >> != 0; >> op->dop.u.execute.probe = false; >> } >> @@ -1663,12 +1668,13 @@ revalidate_ukey(struct udpif *udpif, struct >> udpif_key *ukey, >> const struct dpif_flow_stats *stats, uint64_t reval_seq) >> OVS_REQUIRES(ukey->mutex) >> { >> - uint64_t slow_path_buf[128 / 8]; >> + uint64_t odp_actions_stub[1024 / 8]; >> + struct ofpbuf odp_actions = OFPBUF_STUB_INITIALIZER(odp_actions_stub); >> + >> struct xlate_out xout, *xoutp; >> struct netflow *netflow; >> struct ofproto_dpif *ofproto; >> struct dpif_flow_stats push; >> - struct ofpbuf xout_actions; >> struct flow flow, dp_mask; >> struct flow_wildcards wc; >> uint64_t *dp64, *xout64; >> @@ -1733,7 +1739,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key >> *ukey, >> } >> >> xlate_in_init(&xin, ofproto, &flow, ofp_in_port, NULL, push.tcp_flags, >> - NULL, need_revalidate ? &wc : NULL); >> + NULL, need_revalidate ? &wc : NULL, &odp_actions); >> if (push.n_packets) { >> xin.resubmit_stats = &push; >> xin.may_learn = true; >> @@ -1747,16 +1753,13 @@ revalidate_ukey(struct udpif *udpif, struct >> udpif_key *ukey, >> goto exit; >> } >> >> - if (!xout.slow) { >> - ofpbuf_use_const(&xout_actions, xout.odp_actions->data, >> - xout.odp_actions->size); >> - } else { >> - ofpbuf_use_stack(&xout_actions, slow_path_buf, sizeof >> slow_path_buf); >> + if (xout.slow) { >> + ofpbuf_clear(&odp_actions); >> compose_slow_path(udpif, &xout, &flow, flow.in_port.odp_port, >> - &xout_actions); >> + &odp_actions); >> } >> >> - if (!ofpbuf_equal(&xout_actions, ukey->actions)) { >> + if (!ofpbuf_equal(&odp_actions, ukey->actions)) { >> goto exit; >> } >> >> @@ -1788,6 +1791,7 @@ exit: >> netflow_flow_clear(netflow, &flow); >> } >> xlate_out_uninit(xoutp); >> + ofpbuf_uninit(&odp_actions); >> return ok; >> } >> >> @@ -1880,7 +1884,7 @@ push_ukey_ops__(struct udpif *udpif, struct ukey_op >> *ops, size_t n_ops) >> struct xlate_in xin; >> >> xlate_in_init(&xin, ofproto, &flow, ofp_in_port, NULL, >> - push->tcp_flags, NULL, NULL); >> + push->tcp_flags, NULL, NULL, NULL); >> xin.resubmit_stats = push->n_packets ? push : NULL; >> xin.may_learn = push->n_packets > 0; >> xlate_actions_for_side_effects(&xin); >> diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c >> index a219936..eb1e17a 100644 >> --- a/ofproto/ofproto-dpif-xlate.c >> +++ b/ofproto/ofproto-dpif-xlate.c >> @@ -187,6 +187,13 @@ struct xlate_ctx { >> * caller really wants wildcards. */ >> struct flow_wildcards *wc; >> >> + /* Output buffer for datapath actions. When 'xin->odp_actions' is >> nonnull, >> + * this is the same pointer. When 'xin->odp_actions' is null, this >> points >> + * to a scratch ofpbuf. This allows code to add actions to >> + * 'ctx->odp_actions' without worrying about whether the caller really >> + * wants actions. */ >> + struct ofpbuf *odp_actions; >> + >> /* Resubmit statistics, via xlate_table_action(). */ >> int recurse; /* Current resubmit nesting depth. */ >> int resubmits; /* Total number of resubmits. */ >> @@ -1548,7 +1555,7 @@ add_mirror_actions(struct xlate_ctx *ctx, const struct >> flow *orig_flow) >> "%s, which is reserved exclusively for mirroring", >> ctx->xbridge->name, in_xbundle->name); >> } >> - ofpbuf_clear(ctx->xout->odp_actions); >> + ofpbuf_clear(ctx->odp_actions); >> return; >> } >> >> @@ -2597,7 +2604,7 @@ static void >> add_sflow_action(struct xlate_ctx *ctx) >> { >> ctx->user_cookie_offset = compose_sflow_action(ctx->xbridge, >> - ctx->xout->odp_actions, >> + ctx->odp_actions, >> &ctx->xin->flow, >> ODPP_NONE); >> ctx->sflow_odp_port = 0; >> ctx->sflow_n_outputs = 0; >> @@ -2608,14 +2615,14 @@ add_sflow_action(struct xlate_ctx *ctx) >> static void >> add_ipfix_action(struct xlate_ctx *ctx) >> { >> - compose_ipfix_action(ctx->xbridge, ctx->xout->odp_actions, >> + compose_ipfix_action(ctx->xbridge, ctx->odp_actions, >> &ctx->xin->flow, ODPP_NONE); >> } >> >> static void >> add_ipfix_output_action(struct xlate_ctx *ctx, odp_port_t port) >> { >> - compose_ipfix_action(ctx->xbridge, ctx->xout->odp_actions, >> + compose_ipfix_action(ctx->xbridge, ctx->odp_actions, >> &ctx->xin->flow, port); >> } >> >> @@ -2632,7 +2639,7 @@ fix_sflow_action(struct xlate_ctx *ctx) >> return; >> } >> >> - cookie = ofpbuf_at(ctx->xout->odp_actions, ctx->user_cookie_offset, >> + cookie = ofpbuf_at(ctx->odp_actions, ctx->user_cookie_offset, >> sizeof cookie->sflow); >> ovs_assert(cookie->type == USER_ACTION_COOKIE_SFLOW); >> >> @@ -2817,7 +2824,7 @@ build_tunnel_send(struct xlate_ctx *ctx, const struct >> xport *xport, >> } >> tnl_push_data.tnl_port = odp_to_u32(tunnel_odp_port); >> tnl_push_data.out_port = odp_to_u32(out_dev->odp_port); >> - odp_put_tnl_push_action(ctx->xout->odp_actions, &tnl_push_data); >> + odp_put_tnl_push_action(ctx->odp_actions, &tnl_push_data); >> return 0; >> } >> >> @@ -2924,13 +2931,13 @@ compose_output_action__(struct xlate_ctx *ctx, >> ofp_port_t ofp_port, >> /* Forwarding is disabled by STP and RSTP. Let OFPP_NORMAL >> and >> * the learning action look at the packet, then drop it. */ >> struct flow old_base_flow = ctx->base_flow; >> - size_t old_size = ctx->xout->odp_actions->size; >> + size_t old_size = ctx->odp_actions->size; >> mirror_mask_t old_mirrors = ctx->xout->mirrors; >> >> xlate_table_action(ctx, flow->in_port.ofp_port, 0, true, >> true); >> ctx->xout->mirrors = old_mirrors; >> ctx->base_flow = old_base_flow; >> - ctx->xout->odp_actions->size = old_size; >> + ctx->odp_actions->size = old_size; >> >> /* Undo changes that may have been done for recirculation. */ >> if (exit_recirculates(ctx)) { >> @@ -3023,8 +3030,7 @@ compose_output_action__(struct xlate_ctx *ctx, >> ofp_port_t ofp_port, >> tnl_push_pop_send = true; >> } else { >> xlate_report(ctx, "output to kernel tunnel"); >> - commit_odp_tunnel_action(flow, &ctx->base_flow, >> - ctx->xout->odp_actions); >> + commit_odp_tunnel_action(flow, &ctx->base_flow, >> ctx->odp_actions); >> flow->tunnel = flow_tnl; /* Restore tunnel metadata */ >> } >> } else { >> @@ -3047,21 +3053,21 @@ compose_output_action__(struct xlate_ctx *ctx, >> ofp_port_t ofp_port, >> bool use_masked = ctx->xbridge->support.masked_set_action; >> >> ctx->xout->slow |= commit_odp_actions(flow, &ctx->base_flow, >> - ctx->xout->odp_actions, >> + ctx->odp_actions, >> wc, use_masked); >> >> if (xr) { >> struct ovs_action_hash *act_hash; >> >> /* Hash action. */ >> - act_hash = nl_msg_put_unspec_uninit(ctx->xout->odp_actions, >> + act_hash = nl_msg_put_unspec_uninit(ctx->odp_actions, >> OVS_ACTION_ATTR_HASH, >> sizeof *act_hash); >> act_hash->hash_alg = xr->hash_alg; >> act_hash->hash_basis = xr->hash_basis; >> >> /* Recirc action. */ >> - nl_msg_put_u32(ctx->xout->odp_actions, OVS_ACTION_ATTR_RECIRC, >> + nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_RECIRC, >> xr->recirc_id); >> } else { >> >> @@ -3080,14 +3086,14 @@ compose_output_action__(struct xlate_ctx *ctx, >> ofp_port_t ofp_port, >> } >> >> if (odp_tnl_port != ODPP_NONE) { >> - nl_msg_put_odp_port(ctx->xout->odp_actions, >> + nl_msg_put_odp_port(ctx->odp_actions, >> OVS_ACTION_ATTR_TUNNEL_POP, >> odp_tnl_port); >> } else { >> /* Tunnel push-pop action is not compatible with >> * IPFIX action. */ >> add_ipfix_output_action(ctx, out_port); >> - nl_msg_put_odp_port(ctx->xout->odp_actions, >> + nl_msg_put_odp_port(ctx->odp_actions, >> OVS_ACTION_ATTR_OUTPUT, >> out_port); >> } >> @@ -3145,7 +3151,7 @@ xlate_resubmit_resource_check(struct xlate_ctx *ctx) >> MAX_RESUBMIT_RECURSION); >> } else if (ctx->resubmits >= MAX_RESUBMITS + MAX_INTERNAL_RESUBMITS) { >> VLOG_ERR_RL(&rl, "over %d resubmit actions", MAX_RESUBMITS); >> - } else if (ctx->xout->odp_actions->size > UINT16_MAX) { >> + } else if (ctx->odp_actions->size > UINT16_MAX) { >> VLOG_ERR_RL(&rl, "resubmits yielded over 64 kB of actions"); >> } else if (ctx->stack.size >= 65536) { >> VLOG_ERR_RL(&rl, "resubmits yielded over 64 kB of stack"); >> @@ -3504,12 +3510,11 @@ execute_controller_action(struct xlate_ctx *ctx, int >> len, >> >> use_masked = ctx->xbridge->support.masked_set_action; >> ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow, >> - ctx->xout->odp_actions, >> + ctx->odp_actions, >> ctx->wc, use_masked); >> >> odp_execute_actions(NULL, &packet, 1, false, >> - ctx->xout->odp_actions->data, >> - ctx->xout->odp_actions->size, NULL); >> + ctx->odp_actions->data, ctx->odp_actions->size, >> NULL); >> >> pin = xmalloc(sizeof *pin); >> pin->up.packet_len = dp_packet_size(packet); >> @@ -3552,7 +3557,7 @@ compose_recirculate_action(struct xlate_ctx *ctx) >> >> use_masked = ctx->xbridge->support.masked_set_action; >> ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow, >> - ctx->xout->odp_actions, >> + ctx->odp_actions, >> ctx->wc, use_masked); >> >> recirc_metadata_from_flow(&md, &ctx->xin->flow); >> @@ -3584,7 +3589,7 @@ compose_recirculate_action(struct xlate_ctx *ctx) >> * fail all revalidations as zero is not a valid recirculation ID. */ >> } >> >> - nl_msg_put_u32(ctx->xout->odp_actions, OVS_ACTION_ATTR_RECIRC, id); >> + nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_RECIRC, id); >> >> /* Undo changes done by recirculation. */ >> ctx->action_set.size = ctx->recirc_action_offset; >> @@ -3605,7 +3610,7 @@ compose_mpls_push_action(struct xlate_ctx *ctx, struct >> ofpact_push_mpls *mpls) >> bool use_masked = ctx->xbridge->support.masked_set_action; >> >> ctx->xout->slow |= commit_odp_actions(flow, &ctx->base_flow, >> - ctx->xout->odp_actions, >> + ctx->odp_actions, >> ctx->wc, use_masked); >> } else if (n >= FLOW_MAX_MPLS_LABELS) { >> if (ctx->xin->packet != NULL) { >> @@ -3641,7 +3646,7 @@ compose_mpls_pop_action(struct xlate_ctx *ctx, >> ovs_be16 eth_type) >> ctx->xbridge->name, FLOW_MAX_MPLS_LABELS); >> } >> ctx->exit = true; >> - ofpbuf_clear(ctx->xout->odp_actions); >> + ofpbuf_clear(ctx->odp_actions); >> } >> } >> >> @@ -3963,12 +3968,12 @@ xlate_sample_action(struct xlate_ctx *ctx, >> >> use_masked = ctx->xbridge->support.masked_set_action; >> ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow, >> - ctx->xout->odp_actions, >> + ctx->odp_actions, >> ctx->wc, use_masked); >> >> compose_flow_sample_cookie(os->probability, os->collector_set_id, >> os->obs_domain_id, os->obs_point_id, &cookie); >> - compose_sample_action(ctx->xbridge, ctx->xout->odp_actions, >> + compose_sample_action(ctx->xbridge, ctx->odp_actions, >> &ctx->xin->flow, probability, &cookie, >> sizeof cookie.flow_sample, ODPP_NONE, >> false); >> @@ -4533,7 +4538,8 @@ void >> xlate_in_init(struct xlate_in *xin, struct ofproto_dpif *ofproto, >> const struct flow *flow, ofp_port_t in_port, >> struct rule_dpif *rule, uint16_t tcp_flags, >> - const struct dp_packet *packet, struct flow_wildcards *wc) >> + const struct dp_packet *packet, struct flow_wildcards *wc, >> + struct ofpbuf *odp_actions) >> { >> xin->ofproto = ofproto; >> xin->flow = *flow; >> @@ -4550,7 +4556,7 @@ xlate_in_init(struct xlate_in *xin, struct >> ofproto_dpif *ofproto, >> xin->report_hook = NULL; >> xin->resubmit_stats = NULL; >> xin->wc = wc; >> - xin->odp_actions = NULL; >> + xin->odp_actions = odp_actions; >> >> /* Do recirc lookup. */ >> xin->recirc = flow->recirc_id >> @@ -4562,9 +4568,6 @@ void >> xlate_out_uninit(struct xlate_out *xout) >> { >> if (xout) { >> - if (xout->odp_actions == &xout->odp_actions_buf) { >> - ofpbuf_uninit(xout->odp_actions); >> - } >> xlate_out_free_recircs(xout); >> } >> } >> @@ -4628,8 +4631,8 @@ actions_output_to_local_port(const struct xlate_ctx >> *ctx) >> const struct nlattr *a; >> unsigned int left; >> >> - NL_ATTR_FOR_EACH_UNSAFE (a, left, ctx->xout->odp_actions->data, >> - ctx->xout->odp_actions->size) { >> + NL_ATTR_FOR_EACH_UNSAFE (a, left, ctx->odp_actions->data, >> + ctx->odp_actions->size) { >> if (nl_attr_type(a) == OVS_ACTION_ATTR_OUTPUT >> && nl_attr_get_odp_port(a) == local_odp_port) { >> return true; >> @@ -4740,6 +4743,8 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> union mf_subvalue stack_stub[1024 / sizeof(union mf_subvalue)]; >> uint64_t action_set_stub[1024 / 8]; >> struct flow_wildcards scratch_wc; >> + uint64_t actions_stub[256 / 8]; >> + struct ofpbuf scratch_actions = OFPBUF_STUB_INITIALIZER(actions_stub); >> struct xlate_ctx ctx = { >> .xin = xin, >> .xout = xout, >> @@ -4749,6 +4754,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> .stack = OFPBUF_STUB_INITIALIZER(stack_stub), >> .rule = xin->rule, >> .wc = xin->wc ? xin->wc : &scratch_wc, >> + .odp_actions = xin->odp_actions ? xin->odp_actions : >> &scratch_actions, >> >> .recurse = 0, >> .resubmits = 0, >> @@ -4772,6 +4778,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> .action_set = OFPBUF_STUB_INITIALIZER(action_set_stub), >> }; >> memset(&ctx.base_flow.tunnel, 0, sizeof ctx.base_flow.tunnel); >> + ofpbuf_reserve(ctx.odp_actions, NL_A_U32_SIZE); >> >> enum slow_path_reason special; >> const struct ofpact *ofpacts; >> @@ -4804,14 +4811,6 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> * kernel does. If we wish to maintain the original values an action >> * needs to be generated. */ >> >> - xout->odp_actions = xin->odp_actions; >> - if (!xout->odp_actions) { >> - xout->odp_actions = &xout->odp_actions_buf; >> - ofpbuf_use_stub(xout->odp_actions, xout->odp_actions_stub, >> - sizeof xout->odp_actions_stub); >> - } >> - ofpbuf_reserve(xout->odp_actions, NL_A_U32_SIZE); >> - >> if (xin->wc) { >> flow_wildcards_init_catchall(ctx.wc); >> memset(&ctx.wc->masks.in_port, 0xff, sizeof ctx.wc->masks.in_port); >> @@ -4845,7 +4844,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> xin->ofpacts_len > 0 >> ? "actions" >> : "rule"); >> - return; >> + goto exit; >> } >> >> /* Set the bridge for post-recirculation processing if needed. */ >> @@ -4858,7 +4857,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> /* Drop the packet if the bridge cannot be found. */ >> static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); >> VLOG_WARN_RL(&rl, "Recirculation bridge no longer exists."); >> - return; >> + goto exit; >> } >> ctx.xbridge = new_bridge; >> } >> @@ -4904,7 +4903,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> >> VLOG_WARN_RL(&rl, "Recirculation context not found for ID %"PRIx32, >> flow->recirc_id); >> - return; >> + goto exit; >> } >> /* The bridge is now known so obtain its table version. */ >> ctx.tables_version = >> ofproto_dpif_get_tables_version(ctx.xbridge->ofproto); >> @@ -4989,7 +4988,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> if (!xin->recirc) { >> add_sflow_action(&ctx); >> add_ipfix_action(&ctx); >> - sample_actions_len = ctx.xout->odp_actions->size; >> + sample_actions_len = ctx.odp_actions->size; >> } else { >> sample_actions_len = 0; >> } >> @@ -5002,7 +5001,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> if (in_port && (!xport_stp_forward_state(in_port) || >> !xport_rstp_forward_state(in_port))) { >> /* Drop all actions added by do_xlate_actions() above. */ >> - ctx.xout->odp_actions->size = sample_actions_len; >> + ctx.odp_actions->size = sample_actions_len; >> >> /* Undo changes that may have been done for recirculation. */ >> if (exit_recirculates(&ctx)) { >> @@ -5041,14 +5040,14 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> } >> } >> >> - if (nl_attr_oversized(ctx.xout->odp_actions->size)) { >> + if (nl_attr_oversized(ctx.odp_actions->size)) { >> /* These datapath actions are too big for a Netlink attribute, so we >> * can't hand them to the kernel directly. dpif_execute() can execute >> * them one by one with help, so just mark the result as SLOW_ACTION >> to >> * prevent the flow from being installed. */ >> COVERAGE_INC(xlate_actions_oversize); >> ctx.xout->slow |= SLOW_ACTION; >> - } else if (too_many_output_actions(ctx.xout->odp_actions)) { >> + } else if (too_many_output_actions(ctx.odp_actions)) { >> COVERAGE_INC(xlate_actions_too_many_output); >> ctx.xout->slow |= SLOW_ACTION; >> } >> @@ -5094,9 +5093,6 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> } >> } >> >> - ofpbuf_uninit(&ctx.stack); >> - ofpbuf_uninit(&ctx.action_set); >> - >> if (xin->wc) { >> /* Clear the metadata and register wildcard masks, because we won't >> * use non-header fields as part of the cache. */ >> @@ -5121,6 +5117,11 @@ xlate_actions(struct xlate_in *xin, struct xlate_out >> *xout) >> ctx.wc->masks.vlan_tci |= htons(VLAN_CFI); >> } >> } >> + >> +exit: >> + ofpbuf_uninit(&ctx.stack); >> + ofpbuf_uninit(&ctx.action_set); >> + ofpbuf_uninit(&scratch_actions); >> } >> >> /* Sends 'packet' out 'ofport'. >> diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h >> index c5648d6..9c9d2f2 100644 >> --- a/ofproto/ofproto-dpif-xlate.h >> +++ b/ofproto/ofproto-dpif-xlate.h >> @@ -52,10 +52,6 @@ struct xlate_out { >> uint32_t recirc[2]; /* When n_recircs == 1 or 2 */ >> uint32_t *recircs; /* When 'n_recircs' > 2 */ >> }; >> - >> - uint64_t odp_actions_stub[256 / 8]; >> - struct ofpbuf odp_actions_buf; >> - struct ofpbuf *odp_actions; >> }; >> >> /* Helpers to abstract the recirculation union away. */ >> @@ -181,9 +177,8 @@ struct xlate_in { >> * calling xlate_in_init(). */ >> struct xlate_cache *xcache; >> >> - /* Allows callers to optionally supply their own buffer for the >> resulting >> - * odp_actions stored in xlate_out. If NULL, the default buffer will be >> - * used. */ >> + /* If nonnull, flow translation puts the resulting datapath actions in >> this >> + * buffer. If null, flow translation will not produce datapath >> actions. */ >> struct ofpbuf *odp_actions; >> >> /* If nonnull, flow translation populates this with wildcards relevant in >> @@ -239,7 +234,7 @@ void xlate_actions(struct xlate_in *, struct xlate_out >> *); >> void xlate_in_init(struct xlate_in *, struct ofproto_dpif *, >> const struct flow *, ofp_port_t in_port, struct rule_dpif >> *, >> uint16_t tcp_flags, const struct dp_packet *packet, >> - struct flow_wildcards *); >> + struct flow_wildcards *, struct ofpbuf *odp_actions); >> void xlate_out_uninit(struct xlate_out *); >> void xlate_actions_for_side_effects(struct xlate_in *); >> >> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c >> index ab0bf09..078eb90 100644 >> --- a/ofproto/ofproto-dpif.c >> +++ b/ofproto/ofproto-dpif.c >> @@ -3660,15 +3660,17 @@ ofproto_dpif_execute_actions(struct ofproto_dpif >> *ofproto, >> rule_dpif_credit_stats(rule, &stats); >> } >> >> + uint64_t odp_actions_stub[1024 / 8]; >> + struct ofpbuf odp_actions = OFPBUF_STUB_INITIALIZER(odp_actions_stub); >> xlate_in_init(&xin, ofproto, flow, flow->in_port.ofp_port, rule, >> - stats.tcp_flags, packet, NULL); >> + stats.tcp_flags, packet, NULL, &odp_actions); >> xin.ofpacts = ofpacts; >> xin.ofpacts_len = ofpacts_len; >> xin.resubmit_stats = &stats; >> xlate_actions(&xin, &xout); >> >> - execute.actions = xout.odp_actions->data; >> - execute.actions_len = xout.odp_actions->size; >> + execute.actions = odp_actions.data; >> + execute.actions_len = odp_actions.size; >> >> pkt_metadata_from_flow(&packet->md, flow); >> execute.packet = packet; >> @@ -3685,6 +3687,7 @@ ofproto_dpif_execute_actions(struct ofproto_dpif >> *ofproto, >> error = dpif_execute(ofproto->backer->dpif, &execute); >> >> xlate_out_uninit(&xout); >> + ofpbuf_uninit(&odp_actions); >> >> return error; >> } >> @@ -4466,6 +4469,7 @@ struct trace_ctx { >> struct flow flow; >> struct flow_wildcards wc; >> struct ds *result; >> + struct ofpbuf odp_actions; >> }; >> >> static void >> @@ -4532,7 +4536,7 @@ static void >> trace_format_odp(struct ds *result, int level, const char *title, >> struct trace_ctx *trace) >> { >> - struct ofpbuf *odp_actions = trace->xout.odp_actions; >> + struct ofpbuf *odp_actions = &trace->odp_actions; >> >> ds_put_char_multiple(result, '\t', level); >> ds_put_format(result, "%s: ", title); >> @@ -4891,12 +4895,14 @@ ofproto_trace(struct ofproto_dpif *ofproto, struct >> flow *flow, >> ds_put_char(ds, '\n'); >> >> flow_wildcards_init_catchall(&trace.wc); >> + ofpbuf_init(&trace.odp_actions, 0); >> >> trace.result = ds; >> trace.key = flow; /* Original flow key, used for megaflow. */ >> trace.flow = *flow; /* May be modified by actions. */ >> xlate_in_init(&trace.xin, ofproto, flow, flow->in_port.ofp_port, NULL, >> - ntohs(flow->tcp_flags), packet, &trace.wc); >> + ntohs(flow->tcp_flags), packet, &trace.wc, >> + &trace.odp_actions); >> trace.xin.ofpacts = ofpacts; >> trace.xin.ofpacts_len = ofpacts_len; >> trace.xin.resubmit_hook = trace_resubmit; >> @@ -4909,8 +4915,7 @@ ofproto_trace(struct ofproto_dpif *ofproto, struct >> flow *flow, >> trace_format_megaflow(ds, 0, "Megaflow", &trace); >> >> ds_put_cstr(ds, "Datapath actions: "); >> - format_odp_actions(ds, trace.xout.odp_actions->data, >> - trace.xout.odp_actions->size); >> + format_odp_actions(ds, trace.odp_actions.data, trace.odp_actions.size); >> >> if (trace.xout.slow) { >> enum slow_path_reason slow; >> @@ -4930,6 +4935,7 @@ ofproto_trace(struct ofproto_dpif *ofproto, struct >> flow *flow, >> } >> >> xlate_out_uninit(&trace.xout); >> + ofpbuf_uninit(&trace.odp_actions); >> } >> >> /* Store the current ofprotos in 'ofproto_shash'. Returns a sorted list >> -- >> 2.1.3 >> >> _______________________________________________ >> dev mailing list >> dev@openvswitch.org >> http://openvswitch.org/mailman/listinfo/dev >
_______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev