Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- ofproto/ofproto-dpif-xlate.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 0e28c77..9dfe77d 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -208,6 +208,8 @@ struct xlate_ctx { uint16_t user_cookie_offset;/* Used for user_action_cookie fixup. */ bool exit; /* No further actions should be processed. */ + /* These are used only for carrying bond-related parameters to + * compose_output_action__() */ bool use_recirc; /* Should generate recirc? */ struct xlate_recirc recirc; /* Information used for generating * recirculation actions */ @@ -215,7 +217,10 @@ struct xlate_ctx { /* 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. @@ -1670,13 +1675,13 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, uint16_t vid; ovs_be16 tci, old_tci; struct xport *xport; + 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 { @@ -1686,10 +1691,10 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, struct ofport_dpif *ofport; if (ctx->xbridge->enable_recirc) { - ctx->use_recirc = bond_may_recirc( + 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; bond_update_post_recirc_rules(out_xbundle->bond, false); @@ -1708,9 +1713,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 +1743,9 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, } *flow_tci = tci; + ctx->use_recirc = use_recirc; compose_output_action(ctx, xport->ofp_port); + ctx->use_recirc = false; /* Restore to default value. */ *flow_tci = old_tci; } @@ -2731,6 +2738,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 +2789,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 -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev