I'm a little confused about the motivation for this change. IIRC the idea of having recirculation fields in the xlate_ctx structure was to avoid having to pass around extra function parameters, like the ones this patch adds. I'm not necessarily opposed to that. But I think it is worth adding some context to the discussion.
On Thu, Mar 19, 2015 at 06:03:25PM -0700, Jarno Rajahalme wrote: > Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> > --- > ofproto/ofproto-dpif-xlate.c | 66 > +++++++++++++++++++++++++----------------- > ofproto/ofproto-dpif-xlate.h | 6 ---- > 2 files changed, 39 insertions(+), 33 deletions(-) > > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c > index 0e28c77..ece9670 100644 > --- a/ofproto/ofproto-dpif-xlate.c > +++ b/ofproto/ofproto-dpif-xlate.c > @@ -208,14 +208,13 @@ struct xlate_ctx { > uint16_t user_cookie_offset;/* Used for user_action_cookie fixup. */ > bool exit; /* No further actions should be processed. */ > > - bool use_recirc; /* Should generate recirc? */ > - struct xlate_recirc recirc; /* Information used for generating > - * recirculation actions */ > - > /* True if a packet was but is no longer MPLS (due to an MPLS pop > action). > * This is a trigger for recirculation in cases where translating an > action > * or looking up a flow requires access to the fields of the packet after > - * the MPLS label stack that was originally present. */ > + * the MPLS label stack that was originally present. > + * > + * XXX: output to a table and patch port do not currently recirculate > even > + * if this is true. */ > bool was_mpls; > > /* OpenFlow 1.1+ action set. > @@ -353,7 +352,16 @@ static bool input_vid_is_valid(uint16_t vid, struct > xbundle *, bool warn); > static uint16_t input_vid_to_vlan(const struct xbundle *, uint16_t vid); > static void output_normal(struct xlate_ctx *, const struct xbundle *, > uint16_t vlan); > -static void compose_output_action(struct xlate_ctx *, ofp_port_t ofp_port); > + > +/* Optional bond recirculation parameter to compose_output_action(). */ > +struct xlate_bond_recirc { > + uint32_t recirc_id; /* !0 Use recirculation instead of output. */ > + uint8_t hash_alg; /* !0 Compute hash for recirc before. */ > + uint32_t hash_basis; /* Compute hash for recirc before. */ > +}; > + > +static void compose_output_action(struct xlate_ctx *, ofp_port_t ofp_port, > + const struct xlate_bond_recirc *xr); > > static struct xbridge *xbridge_lookup(struct xlate_cfg *, > const struct ofproto_dpif *); > @@ -1670,28 +1678,28 @@ output_normal(struct xlate_ctx *ctx, const struct > xbundle *out_xbundle, > uint16_t vid; > ovs_be16 tci, old_tci; > struct xport *xport; > + struct xlate_bond_recirc xr; > + bool use_recirc = false; > > vid = output_vlan_to_vid(out_xbundle, vlan); > if (list_is_empty(&out_xbundle->xports)) { > /* Partially configured bundle with no slaves. Drop the packet. */ > return; > } else if (!out_xbundle->bond) { > - ctx->use_recirc = false; > xport = CONTAINER_OF(list_front(&out_xbundle->xports), struct xport, > bundle_node); > } else { > struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp); > struct flow_wildcards *wc = &ctx->xout->wc; > - struct xlate_recirc *xr = &ctx->recirc; > struct ofport_dpif *ofport; > > if (ctx->xbridge->enable_recirc) { > - ctx->use_recirc = bond_may_recirc( > - out_xbundle->bond, &xr->recirc_id, &xr->hash_basis); > + use_recirc = bond_may_recirc( > + out_xbundle->bond, &xr.recirc_id, &xr.hash_basis); > > - if (ctx->use_recirc) { > + if (use_recirc) { > /* Only TCP mode uses recirculation. */ > - xr->hash_alg = OVS_HASH_ALG_L4; > + xr.hash_alg = OVS_HASH_ALG_L4; > bond_update_post_recirc_rules(out_xbundle->bond, false); > > /* Recirculation does not require unmasking hash fields. */ > @@ -1708,9 +1716,9 @@ output_normal(struct xlate_ctx *ctx, const struct > xbundle *out_xbundle, > return; > } > > - /* If ctx->xout->use_recirc is set, the main thread will handle stats > + /* If use_recirc is set, the main thread will handle stats > * accounting for this bond. */ > - if (!ctx->use_recirc) { > + if (!use_recirc) { > if (ctx->xin->resubmit_stats) { > bond_account(out_xbundle->bond, &ctx->xin->flow, vid, > ctx->xin->resubmit_stats->n_bytes); > @@ -1738,7 +1746,7 @@ output_normal(struct xlate_ctx *ctx, const struct > xbundle *out_xbundle, > } > *flow_tci = tci; > > - compose_output_action(ctx, xport->ofp_port); > + compose_output_action(ctx, xport->ofp_port, use_recirc ? &xr : NULL); > *flow_tci = old_tci; > } > > @@ -2673,7 +2681,7 @@ build_tunnel_send(const struct xlate_ctx *ctx, const > struct xport *xport, > > static void > compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, > - bool check_stp) > + const struct xlate_bond_recirc *xr, bool check_stp) > { > const struct xport *xport = get_ofp_port(ctx->xbridge, ofp_port); > struct flow_wildcards *wc = &ctx->xout->wc; > @@ -2731,6 +2739,7 @@ compose_output_action__(struct xlate_ctx *ctx, > ofp_port_t ofp_port, > if (xport->peer) { > const struct xport *peer = xport->peer; > struct flow old_flow = ctx->xin->flow; > + bool old_was_mpls = ctx->was_mpls; > enum slow_path_reason special; > uint8_t table_id = > rule_dpif_lookup_get_init_table_id(&ctx->xin->flow); > struct ofpbuf old_stack = ctx->stack; > @@ -2781,6 +2790,10 @@ compose_output_action__(struct xlate_ctx *ctx, > ofp_port_t ofp_port, > ofpbuf_uninit(&ctx->stack); > ctx->stack = old_stack; > > + /* The peer bridge popping MPLS should have no effect on the original > + * bridge. */ > + ctx->was_mpls = old_was_mpls; > + > /* The fact that the peer bridge exits (for any reason) does not mean > * that the original bridge should exit. Specifically, if the peer > * bridge recirculates (which typically modifies the packet), the > @@ -2873,9 +2886,8 @@ compose_output_action__(struct xlate_ctx *ctx, > ofp_port_t ofp_port, > wc, > > ctx->xbridge->masked_set_action); > > - if (ctx->use_recirc) { > + if (xr) { > struct ovs_action_hash *act_hash; > - struct xlate_recirc *xr = &ctx->recirc; > > /* Hash action. */ > act_hash = nl_msg_put_unspec_uninit(ctx->xout->odp_actions, > @@ -2931,9 +2943,10 @@ compose_output_action__(struct xlate_ctx *ctx, > ofp_port_t ofp_port, > } > > static void > -compose_output_action(struct xlate_ctx *ctx, ofp_port_t ofp_port) > +compose_output_action(struct xlate_ctx *ctx, ofp_port_t ofp_port, > + const struct xlate_bond_recirc *xr) > { > - compose_output_action__(ctx, ofp_port, true); > + compose_output_action__(ctx, ofp_port, xr, true); > } > > static void > @@ -3223,9 +3236,9 @@ flood_packets(struct xlate_ctx *ctx, bool all) > } > > if (all) { > - compose_output_action__(ctx, xport->ofp_port, false); > + compose_output_action__(ctx, xport->ofp_port, NULL, false); > } else if (!(xport->config & OFPUTIL_PC_NO_FLOOD)) { > - compose_output_action(ctx, xport->ofp_port); > + compose_output_action(ctx, xport->ofp_port, NULL); > } > } > > @@ -3492,7 +3505,7 @@ xlate_output_action(struct xlate_ctx *ctx, > > switch (port) { > case OFPP_IN_PORT: > - compose_output_action(ctx, ctx->xin->flow.in_port.ofp_port); > + compose_output_action(ctx, ctx->xin->flow.in_port.ofp_port, NULL); > break; > case OFPP_TABLE: > xlate_table_action(ctx, ctx->xin->flow.in_port.ofp_port, > @@ -3519,7 +3532,7 @@ xlate_output_action(struct xlate_ctx *ctx, > case OFPP_LOCAL: > default: > if (port != ctx->xin->flow.in_port.ofp_port) { > - compose_output_action(ctx, port); > + compose_output_action(ctx, port, NULL); > } else { > xlate_report(ctx, "skipping output to input port"); > } > @@ -3578,7 +3591,7 @@ xlate_enqueue_action(struct xlate_ctx *ctx, > /* Add datapath actions. */ > flow_priority = ctx->xin->flow.skb_priority; > ctx->xin->flow.skb_priority = priority; > - compose_output_action(ctx, ofp_port); > + compose_output_action(ctx, ofp_port, NULL); > ctx->xin->flow.skb_priority = flow_priority; > > /* Update NetFlow output port. */ > @@ -4494,7 +4507,6 @@ xlate_actions(struct xlate_in *xin, struct xlate_out > *xout) > ctx.table_id = 0; > ctx.rule_cookie = OVS_BE64_MAX; > ctx.exit = false; > - ctx.use_recirc = false; > ctx.was_mpls = false; > > if (!xin->ofpacts && !ctx.rule) { > @@ -4596,7 +4608,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out > *xout) > if (ctx.xbridge->has_in_band > && in_band_must_output_to_local_port(flow) > && !actions_output_to_local_port(&ctx)) { > - compose_output_action(&ctx, OFPP_LOCAL); > + compose_output_action(&ctx, OFPP_LOCAL, NULL); > } > > fix_sflow_action(&ctx); > diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h > index a53fa8e..3e596fb 100644 > --- a/ofproto/ofproto-dpif-xlate.h > +++ b/ofproto/ofproto-dpif-xlate.h > @@ -36,12 +36,6 @@ struct mac_learning; > struct mcast_snooping; > struct xlate_cache; > > -struct xlate_recirc { > - uint32_t recirc_id; /* !0 Use recirculation instead of output. */ > - uint8_t hash_alg; /* !0 Compute hash for recirc before. */ > - uint32_t hash_basis; /* Compute hash for recirc before. */ > -}; > - > struct xlate_out { > /* Wildcards relevant in translation. Any fields that were used to > * calculate the action must be set for caching and kernel > -- > 1.7.10.4 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev