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

Reply via email to