Signed-off-by: Jarno Rajahalme <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev