From cdf5d3a51e9ccd33ef77b5dcd9b03671f3352650 Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Wed, 19 Jun 2013 18:51:28 -0700 Subject: [PATCH] ofproto-dpif: Handle dest mirrors in compose_output_action(). Before this patch, the mirroring code would retroactively insert actions for destination mirrors after actions were translated. This relied on converting datapath output actions into ofports which doesn't work for tunnels and patch ports. This patch refactors the code to handle destination mirrors at output. Signed-off-by: Ethan Jackson Acked-by: Ben Pfaff --- ofproto/ofproto-dpif-xlate.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 0e7b9a076..0203b98ff 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -181,15 +181,16 @@ add_mirror_actions(struct xlate_ctx *ctx, const struct flow *orig_flow) struct ofbundle *in_bundle; uint16_t vlan; uint16_t vid; - const struct nlattr *a; - size_t left; + + mirrors = ctx->xout->mirrors; + ctx->xout->mirrors = 0; in_bundle = lookup_input_bundle(ctx->ofproto, orig_flow->in_port.ofp_port, ctx->xin->packet != NULL, NULL); if (!in_bundle) { return; } - mirrors = in_bundle->src_mirrors; + mirrors |= in_bundle->src_mirrors; /* Drop frames on bundles reserved for mirroring. */ if (in_bundle->mirror_out) { @@ -209,23 +210,6 @@ add_mirror_actions(struct xlate_ctx *ctx, const struct flow *orig_flow) } vlan = input_vid_to_vlan(in_bundle, vid); - /* Look at the output ports to check for destination selections. */ - - NL_ATTR_FOR_EACH (a, left, ctx->xout->odp_actions.data, - ctx->xout->odp_actions.size) { - enum ovs_action_attr type = nl_attr_type(a); - struct ofport_dpif *ofport; - - if (type != OVS_ACTION_ATTR_OUTPUT) { - continue; - } - - ofport = get_odp_port(ofproto, nl_attr_get_odp_port(a)); - if (ofport && ofport->bundle) { - mirrors |= ofport->bundle->dst_mirrors; - } - } - if (!mirrors) { return; } @@ -854,6 +838,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, return; } + if (ctx->ofproto->has_mirrors && ofport->bundle) { + ctx->xout->mirrors |= ofport->bundle->dst_mirrors; + } + if (ofport->peer) { struct ofport_dpif *peer = ofport->peer; struct flow old_flow = ctx->xin->flow; @@ -877,7 +865,9 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, * 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; + mirror_mask_t old_mirrors = ctx->xout->mirrors; xlate_table_action(ctx, flow->in_port.ofp_port, 0, true); + ctx->xout->mirrors = old_mirrors; ctx->base_flow = old_base_flow; ctx->xout->odp_actions.size = old_size; } -- 2.45.2