Signed-off-by: Jarno Rajahalme <jarno.rajaha...@nsn.com> --- ofproto/ofproto-dpif.c | 276 +++++++++++++++++++++--------------------------- 1 file changed, 118 insertions(+), 158 deletions(-)
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 96f6452..d3434c3 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -241,10 +241,6 @@ struct xlate_out { struct xlate_in { struct ofproto_dpif *ofproto; - /* Flow to which the OpenFlow actions apply. xlate_actions() will modify - * this flow when actions change header fields. */ - struct flow *flow; - /* Storage for flow initialized by xlate_in_init */ struct flow flow_storage; @@ -341,12 +337,14 @@ static void xlate_in_init(struct xlate_in *, struct ofproto_dpif *, static void xlate_out_uninit(struct xlate_out *); -static void xlate_actions(struct xlate_in *, struct xlate_out *); +static void xlate_actions(struct xlate_in *, struct flow *, + struct xlate_out *); -static void xlate_actions_for_side_effects(struct xlate_in *); +static void xlate_actions_for_side_effects(struct xlate_in *, struct flow *); -static void xlate_table_action(struct xlate_ctx *, uint16_t in_port, - uint8_t table_id, bool may_packet_in); +static void xlate_table_action(struct xlate_ctx *, struct flow *flow, + uint16_t in_port, uint8_t table_id, + bool may_packet_in); static size_t put_userspace_action(const struct ofproto_dpif *, struct ofpbuf *odp_actions, @@ -3707,7 +3705,8 @@ handle_flow_miss_without_facet(struct flow_miss *miss, xlate_in_init(&xin, miss->ofproto, &miss->flow, &miss->initial_vals, rule, stats.tcp_flags, packet); xin.resubmit_stats = &stats; - xlate_actions(&xin, &op->xout); + /* Note: Could use &miss->flow */ + xlate_actions(&xin, &xin.flow_storage, &op->xout); if (op->xout.odp_actions.size) { struct dpif_execute *execute = &op->dpif_op.u.execute; @@ -3757,7 +3756,7 @@ handle_flow_miss_with_facet(struct flow_miss *miss, struct facet *facet, xlate_in_init(&xin, ofproto, &facet->flow, &facet->initial_vals, facet->rule, 0, packet); - xlate_actions_for_side_effects(&xin); + xlate_actions_for_side_effects(&xin, &xin.flow_storage); } dpif_flow_stats_extract(&facet->flow, packet, now, &stats); @@ -4658,7 +4657,7 @@ facet_create(const struct flow_miss *miss, uint32_t hash) xlate_in_init(&xin, ofproto, &facet->flow, &facet->initial_vals, facet->rule, 0, NULL); xin.may_learn = true; - xlate_actions(&xin, &facet->xout); + xlate_actions(&xin, &xin.flow_storage, &facet->xout); facet->nf_flow.output_iface = facet->xout.nf_output_iface; return facet; @@ -4942,7 +4941,7 @@ facet_check_consistency(struct facet *facet) /* Check the datapath actions for consistency. */ xlate_in_init(&xin, ofproto, &facet->flow, &facet->initial_vals, rule, 0, NULL); - xlate_actions(&xin, &xout); + xlate_actions(&xin, &xin.flow_storage, &xout); ok = ofpbuf_equal(&facet->xout.odp_actions, &xout.odp_actions) && facet->xout.slow == xout.slow; @@ -5024,7 +5023,7 @@ facet_revalidate(struct facet *facet) * around to properly compose it. */ xlate_in_init(&xin, ofproto, &facet->flow, &facet->initial_vals, new_rule, 0, NULL); - xlate_actions(&xin, &xout); + xlate_actions(&xin, &xin.flow_storage, &xout); /* A facet's slow path reason should only change under dramatic * circumstances. Rather than try to update everything, it's simpler to @@ -5126,7 +5125,7 @@ facet_push_stats(struct facet *facet, bool may_learn) facet->rule, stats.tcp_flags, NULL); xin.resubmit_stats = &stats; xin.may_learn = may_learn; - xlate_actions_for_side_effects(&xin); + xlate_actions_for_side_effects(&xin, &facet->flow); } } @@ -5590,7 +5589,7 @@ rule_dpif_execute(struct rule_dpif *rule, const struct flow *flow, xlate_in_init(&xin, ofproto, flow, &initial_vals, rule, stats.tcp_flags, packet); xin.resubmit_stats = &stats; - xlate_actions(&xin, &xout); + xlate_actions(&xin, &xin.flow_storage, &xout); execute_odp_actions(ofproto, flow, xout.odp_actions.data, xout.odp_actions.size, packet); @@ -5649,7 +5648,7 @@ send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet) xin.ofpacts_len = sizeof output; xin.ofpacts = &output.ofpact; xin.resubmit_stats = &stats; - xlate_actions(&xin, &xout); + xlate_actions(&xin, &xin.flow_storage, &xout); error = dpif_execute(ofproto->backer->dpif, key.data, key.size, @@ -5672,8 +5671,8 @@ send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet) static bool may_receive(const struct ofport_dpif *, struct flow *); static void do_xlate_actions(const struct ofpact *, size_t ofpacts_len, - struct xlate_ctx *); -static void xlate_normal(struct xlate_ctx *); + struct xlate_ctx *, struct flow *); +static void xlate_normal(struct xlate_ctx *, struct flow *); /* Composes an ODP action for a "slow path" action for 'flow' within 'ofproto'. * The action will state 'slow' as the reason that the action is in the slow @@ -5849,10 +5848,8 @@ compose_ipfix_action(const struct ofproto_dpif *ofproto, * actions. At this point we do not have all information required to * build it. So try to build sample action as complete as possible. */ static void -add_sflow_action(struct xlate_ctx *ctx) +add_sflow_action(struct xlate_ctx *ctx, struct flow *flow) { - struct flow *flow = ctx->xin->flow; - ctx->user_cookie_offset = compose_sflow_action(ctx->ofproto, &ctx->xout->odp_actions, flow, OVSP_NONE); @@ -5863,12 +5860,9 @@ add_sflow_action(struct xlate_ctx *ctx) /* SAMPLE action for IPFIX must be 1st or 2nd action in any given list * of actions, eventually after the SAMPLE action for sFlow. */ static void -add_ipfix_action(struct xlate_ctx *ctx) +add_ipfix_action(struct xlate_ctx *ctx, struct flow *flow) { - struct flow *flow = ctx->xin->flow; - - compose_ipfix_action(ctx->ofproto, &ctx->xout->odp_actions, - flow); + compose_ipfix_action(ctx->ofproto, &ctx->xout->odp_actions, flow); } /* Fix SAMPLE action according to data collected while composing ODP actions. @@ -5893,10 +5887,9 @@ fix_sflow_action(struct xlate_ctx *ctx) } static void -compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, - bool check_stp) +compose_output_action__(struct xlate_ctx *ctx, struct flow *flow, + uint16_t ofp_port, bool check_stp) { - struct flow *flow = ctx->xin->flow; const struct ofport_dpif *ofport = get_ofp_port(ctx->ofproto, ofp_port); ovs_be16 flow_vlan_tci; uint32_t flow_skb_mark; @@ -5951,19 +5944,17 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, if (special) { ctx->xout->slow = special; } else if (!in_port || may_receive(in_port, &new_flow)) { - ctx->xin->flow = &new_flow; if (!in_port || stp_forward_in_state(in_port->stp_state)) { - xlate_table_action(ctx, new_flow.in_port, 0, true); + xlate_table_action(ctx, &new_flow, new_flow.in_port, 0, true); } else { /* Forwarding is disabled by STP. Let OFPP_NORMAL and the * 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; - xlate_table_action(ctx, new_flow.in_port, 0, true); + xlate_table_action(ctx, &new_flow, new_flow.in_port, 0, true); ctx->base_flow = old_base_flow; ctx->xout->odp_actions.size = old_size; } - ctx->xin->flow = flow; /* Restore flow pointer */ } ctx->ofproto = ofproto_dpif_cast(ofport->up.ofproto); @@ -6036,9 +6027,10 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, } static void -compose_output_action(struct xlate_ctx *ctx, uint16_t ofp_port) +compose_output_action(struct xlate_ctx *ctx, struct flow *flow, + uint16_t ofp_port) { - compose_output_action__(ctx, ofp_port, true); + compose_output_action__(ctx, flow, ofp_port, true); } static void @@ -6061,11 +6053,9 @@ tag_the_flow(struct xlate_ctx *ctx, struct flow *flow, struct rule_dpif *rule) /* Common rule processing in one place to avoid duplicating code. */ static struct rule_dpif * -ctx_rule_hooks(struct xlate_ctx *ctx, struct rule_dpif *rule, - bool may_packet_in) +ctx_rule_hooks(struct xlate_ctx *ctx, struct flow *flow, + struct rule_dpif *rule, bool may_packet_in) { - struct flow *flow = ctx->xin->flow; - if (ctx->xin->resubmit_hook) { ctx->xin->resubmit_hook(ctx, rule); } @@ -6086,11 +6076,9 @@ ctx_rule_hooks(struct xlate_ctx *ctx, struct rule_dpif *rule, } static void -xlate_table_action(struct xlate_ctx *ctx, +xlate_table_action(struct xlate_ctx *ctx, struct flow *flow, uint16_t in_port, uint8_t table_id, bool may_packet_in) { - struct flow *flow = ctx->xin->flow; - if (ctx->recurse < MAX_RESUBMIT_RECURSION) { struct rule_dpif *rule; uint16_t old_in_port = flow->in_port; @@ -6108,14 +6096,15 @@ xlate_table_action(struct xlate_ctx *ctx, * OFPP_IN_PORT will have surprising behavior. */ flow->in_port = old_in_port; - rule = ctx_rule_hooks(ctx, rule, may_packet_in); + rule = ctx_rule_hooks(ctx, flow, rule, may_packet_in); if (rule) { struct rule_dpif *old_rule = ctx->rule; ctx->recurse++; ctx->rule = rule; - do_xlate_actions(rule->up.ofpacts, rule->up.ofpacts_len, ctx); + do_xlate_actions(rule->up.ofpacts, rule->up.ofpacts_len, ctx, + flow); ctx->rule = old_rule; ctx->recurse--; } @@ -6131,10 +6120,9 @@ xlate_table_action(struct xlate_ctx *ctx, } static void -xlate_ofpact_resubmit(struct xlate_ctx *ctx, +xlate_ofpact_resubmit(struct xlate_ctx *ctx, struct flow *flow, const struct ofpact_resubmit *resubmit) { - struct flow *flow = ctx->xin->flow; uint16_t in_port; uint8_t table_id; @@ -6148,13 +6136,12 @@ xlate_ofpact_resubmit(struct xlate_ctx *ctx, table_id = ctx->table_id; } - xlate_table_action(ctx, in_port, table_id, false); + xlate_table_action(ctx, flow, in_port, table_id, false); } static void -flood_packets(struct xlate_ctx *ctx, bool all) +flood_packets(struct xlate_ctx *ctx, struct flow *flow, bool all) { - struct flow *flow = ctx->xin->flow; struct ofport_dpif *ofport; HMAP_FOR_EACH (ofport, up.hmap_node, &ctx->ofproto->up.ports) { @@ -6165,9 +6152,9 @@ flood_packets(struct xlate_ctx *ctx, bool all) } if (all) { - compose_output_action__(ctx, ofp_port, false); + compose_output_action__(ctx, flow, ofp_port, false); } else if (!(ofport->up.pp.config & OFPUTIL_PC_NO_FLOOD)) { - compose_output_action(ctx, ofp_port); + compose_output_action(ctx, flow, ofp_port); } } @@ -6175,11 +6162,10 @@ flood_packets(struct xlate_ctx *ctx, bool all) } static void -execute_controller_action(struct xlate_ctx *ctx, int len, +execute_controller_action(struct xlate_ctx *ctx, struct flow *flow, int len, enum ofp_packet_in_reason reason, uint16_t controller_id) { - struct flow *flow = ctx->xin->flow; struct ofputil_packet_in pin; struct ofpbuf *packet; @@ -6336,39 +6322,38 @@ compose_dec_mpls_ttl_action(struct flow *flow) } static void -xlate_output_action(struct xlate_ctx *ctx, +xlate_output_action(struct xlate_ctx *ctx, struct flow *flow, uint16_t port, uint16_t max_len, bool may_packet_in) { - struct flow *flow = ctx->xin->flow; uint16_t prev_nf_output_iface = ctx->xout->nf_output_iface; ctx->xout->nf_output_iface = NF_OUT_DROP; switch (port) { case OFPP_IN_PORT: - compose_output_action(ctx, flow->in_port); + compose_output_action(ctx, flow, flow->in_port); break; case OFPP_TABLE: - xlate_table_action(ctx, flow->in_port, 0, may_packet_in); + xlate_table_action(ctx, flow, flow->in_port, 0, may_packet_in); break; case OFPP_NORMAL: - xlate_normal(ctx); + xlate_normal(ctx, flow); break; case OFPP_FLOOD: - flood_packets(ctx, false); + flood_packets(ctx, flow, false); break; case OFPP_ALL: - flood_packets(ctx, true); + flood_packets(ctx, flow, true); break; case OFPP_CONTROLLER: - execute_controller_action(ctx, max_len, OFPR_ACTION, 0); + execute_controller_action(ctx, flow, max_len, OFPR_ACTION, 0); break; case OFPP_NONE: break; case OFPP_LOCAL: default: if (port != flow->in_port) { - compose_output_action(ctx, port); + compose_output_action(ctx, flow, port); } else { xlate_report(ctx, "skipping output to input port"); } @@ -6386,23 +6371,19 @@ xlate_output_action(struct xlate_ctx *ctx, } static void -xlate_output_reg_action(struct xlate_ctx *ctx, +xlate_output_reg_action(struct xlate_ctx *ctx, struct flow *flow, const struct ofpact_output_reg *or) { - struct flow *flow = ctx->xin->flow; - uint64_t port = mf_get_subfield(&or->src, flow); if (port <= UINT16_MAX) { - xlate_output_action(ctx, port, or->max_len, false); + xlate_output_action(ctx, flow, port, or->max_len, false); } } static void -xlate_enqueue_action(struct xlate_ctx *ctx, +xlate_enqueue_action(struct xlate_ctx *ctx, struct flow *flow, const struct ofpact_enqueue *enqueue) { - struct flow *flow = ctx->xin->flow; - uint16_t ofp_port = enqueue->port; uint32_t queue_id = enqueue->queue; uint32_t flow_priority, priority; @@ -6413,7 +6394,7 @@ xlate_enqueue_action(struct xlate_ctx *ctx, queue_id, &priority); if (error) { /* Fall back to ordinary output action. */ - xlate_output_action(ctx, enqueue->port, 0, false); + xlate_output_action(ctx, flow, enqueue->port, 0, false); return; } @@ -6427,7 +6408,7 @@ xlate_enqueue_action(struct xlate_ctx *ctx, /* Add datapath actions. */ flow_priority = flow->skb_priority; flow->skb_priority = priority; - compose_output_action(ctx, ofp_port); + compose_output_action(ctx, flow, ofp_port); flow->skb_priority = flow_priority; /* Update NetFlow output port. */ @@ -6439,10 +6420,9 @@ xlate_enqueue_action(struct xlate_ctx *ctx, } static void -xlate_set_queue_action(struct xlate_ctx *ctx, uint32_t queue_id) +xlate_set_queue_action(struct xlate_ctx *ctx, struct flow *flow, + uint32_t queue_id) { - struct flow *flow = ctx->xin->flow; - uint32_t skb_priority; if (!dpif_queue_to_priority(ctx->ofproto->backer->dpif, @@ -6477,27 +6457,23 @@ slave_enabled_cb(uint16_t ofp_port, void *ofproto_) } static void -xlate_bundle_action(struct xlate_ctx *ctx, +xlate_bundle_action(struct xlate_ctx *ctx, struct flow *flow, const struct ofpact_bundle *bundle) { - struct flow *flow = ctx->xin->flow; - uint16_t port; port = bundle_execute(bundle, flow, slave_enabled_cb, ctx->ofproto); if (bundle->dst.field) { nxm_reg_load(&bundle->dst, port, flow); } else { - xlate_output_action(ctx, port, 0, false); + xlate_output_action(ctx, flow, port, 0, false); } } static void -xlate_learn_action(struct xlate_ctx *ctx, +xlate_learn_action(struct xlate_ctx *ctx, struct flow *flow, const struct ofpact_learn *learn) { - struct flow *flow = ctx->xin->flow; - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); struct ofputil_flow_mod fm; uint64_t ofpacts_stub[1024 / 8]; @@ -6539,11 +6515,9 @@ xlate_fin_timeout(struct xlate_ctx *ctx, } static void -xlate_sample_action(struct xlate_ctx *ctx, +xlate_sample_action(struct xlate_ctx *ctx, struct flow *flow, const struct ofpact_sample *os) { - struct flow *flow = ctx->xin->flow; - union user_action_cookie cookie; /* Scale the probability from 16-bit to 32-bit while representing * the same percentage. */ @@ -6580,10 +6554,8 @@ may_receive(const struct ofport_dpif *port, struct flow *flow) } static bool -tunnel_ecn_ok(struct xlate_ctx *ctx) +tunnel_ecn_ok(struct xlate_ctx *ctx, struct flow *flow) { - struct flow *flow = ctx->xin->flow; - if (is_ip_any(&ctx->base_flow) && (flow->tunnel.ip_tos & IP_ECN_MASK) == IP_ECN_CE) { if ((ctx->base_flow.nw_tos & IP_ECN_MASK) == IP_ECN_NOT_ECT) { @@ -6601,9 +6573,8 @@ tunnel_ecn_ok(struct xlate_ctx *ctx) static void do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, - struct xlate_ctx *ctx) + struct xlate_ctx *ctx, struct flow *flow) { - struct flow *flow = ctx->xin->flow; bool was_evictable = true; const struct ofpact *a; @@ -6624,19 +6595,19 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, switch (a->type) { case OFPACT_OUTPUT: - xlate_output_action(ctx, ofpact_get_OUTPUT(a)->port, + xlate_output_action(ctx, flow, ofpact_get_OUTPUT(a)->port, ofpact_get_OUTPUT(a)->max_len, true); break; case OFPACT_CONTROLLER: controller = ofpact_get_CONTROLLER(a); - execute_controller_action(ctx, controller->max_len, + execute_controller_action(ctx, flow, controller->max_len, controller->reason, controller->controller_id); break; case OFPACT_ENQUEUE: - xlate_enqueue_action(ctx, ofpact_get_ENQUEUE(a)); + xlate_enqueue_action(ctx, flow, ofpact_get_ENQUEUE(a)); break; case OFPACT_SET_VLAN_VID: @@ -6705,7 +6676,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_RESUBMIT: - xlate_ofpact_resubmit(ctx, ofpact_get_RESUBMIT(a)); + xlate_ofpact_resubmit(ctx, flow, ofpact_get_RESUBMIT(a)); break; case OFPACT_SET_TUNNEL: @@ -6713,7 +6684,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; case OFPACT_SET_QUEUE: - xlate_set_queue_action(ctx, ofpact_get_SET_QUEUE(a)->queue_id); + xlate_set_queue_action(ctx, flow, + ofpact_get_SET_QUEUE(a)->queue_id); break; case OFPACT_POP_QUEUE: @@ -6755,8 +6727,8 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_DEC_MPLS_TTL: if (compose_dec_mpls_ttl_action(flow)) { - execute_controller_action(ctx, UINT16_MAX, OFPR_INVALID_TTL, - 0); + execute_controller_action(ctx, flow, UINT16_MAX, + OFPR_INVALID_TTL, 0); goto out; } break; @@ -6767,7 +6739,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, size_t i; for (i = 0; i < ids->n_controllers; i++) { - execute_controller_action(ctx, UINT16_MAX, + execute_controller_action(ctx, flow, UINT16_MAX, OFPR_INVALID_TTL, ids->cnt_ids[i]); } @@ -6785,17 +6757,17 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, case OFPACT_BUNDLE: ctx->ofproto->has_bundle_action = true; - xlate_bundle_action(ctx, ofpact_get_BUNDLE(a)); + xlate_bundle_action(ctx, flow, ofpact_get_BUNDLE(a)); break; case OFPACT_OUTPUT_REG: - xlate_output_reg_action(ctx, ofpact_get_OUTPUT_REG(a)); + xlate_output_reg_action(ctx, flow, ofpact_get_OUTPUT_REG(a)); break; case OFPACT_LEARN: ctx->xout->has_learn = true; if (ctx->xin->may_learn) { - xlate_learn_action(ctx, ofpact_get_LEARN(a)); + xlate_learn_action(ctx, flow, ofpact_get_LEARN(a)); } break; @@ -6836,7 +6808,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, tag_the_flow(ctx, flow, rule); - rule = ctx_rule_hooks(ctx, rule, true); + rule = ctx_rule_hooks(ctx, flow, rule, true); if (rule) { if (ctx->rule) { @@ -6855,7 +6827,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, } case OFPACT_SAMPLE: - xlate_sample_action(ctx, ofpact_get_SAMPLE(a)); + xlate_sample_action(ctx, flow, ofpact_get_SAMPLE(a)); break; } } @@ -6874,7 +6846,6 @@ xlate_in_init(struct xlate_in *xin, struct ofproto_dpif *ofproto, const struct ofpbuf *packet) { xin->ofproto = ofproto; - xin->flow = &xin->flow_storage; xin->flow_storage = *flow; xin->packet = packet; xin->may_learn = packet != NULL; @@ -6901,10 +6872,10 @@ xlate_out_uninit(struct xlate_out *xout) } } -/* Translates the 'ofpacts_len' bytes of "struct ofpacts" starting at 'ofpacts' - * into datapath actions in 'odp_actions', using 'ctx'. */ +/* Translates the 'ofpacts' in either 'xin' or 'xin->rule' into datapath + * actions in 'ctx->xout', using 'flow'. */ static void -xlate_actions(struct xlate_in *xin, struct xlate_out *xout) +xlate_actions(struct xlate_in *xin, struct flow *flow, struct xlate_out *xout) { /* Normally false. Set to true if we ever hit MAX_RESUBMIT_RECURSION, so * that in the future we always keep a copy of the original flow for @@ -6947,10 +6918,10 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) ctx.ofproto = xin->ofproto; ctx.rule = xin->rule; - ctx.base_flow = *ctx.xin->flow; + ctx.base_flow = *flow; ctx.base_flow.vlan_tci = xin->initial_vals.vlan_tci; memset(&ctx.base_flow.tunnel, 0, sizeof ctx.base_flow.tunnel); - ctx.orig_tunnel_ip_dst = ctx.xin->flow->tunnel.ip_dst; + ctx.orig_tunnel_ip_dst = flow->tunnel.ip_dst; ctx.xout->tags = 0; ctx.xout->slow = 0; @@ -6966,7 +6937,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) ctx.recurse = 0; ctx.max_resubmit_trigger = false; - ctx.orig_skb_priority = ctx.xin->flow->skb_priority; + ctx.orig_skb_priority = flow->skb_priority; ctx.table_id = 0; ctx.exit = false; @@ -6985,15 +6956,15 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) if (ctx.ofproto->has_mirrors || hit_resubmit_limit) { /* Do this conditionally because the copy is expensive enough that it * shows up in profiles. */ - orig_flow = *ctx.xin->flow; + orig_flow = *flow; } - if (ctx.xin->flow->nw_frag & FLOW_NW_FRAG_ANY) { + if (flow->nw_frag & FLOW_NW_FRAG_ANY) { switch (ctx.ofproto->up.frag_handling) { case OFPC_FRAG_NORMAL: /* We must pretend that transport ports are unavailable. */ - ctx.xin->flow->tp_src = ctx.base_flow.tp_src = htons(0); - ctx.xin->flow->tp_dst = ctx.base_flow.tp_dst = htons(0); + flow->tp_src = ctx.base_flow.tp_src = htons(0); + flow->tp_dst = ctx.base_flow.tp_dst = htons(0); break; case OFPC_FRAG_DROP: @@ -7011,8 +6982,8 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) } } - in_port = get_ofp_port(ctx.ofproto, ctx.xin->flow->in_port); - special = process_special(ctx.ofproto, ctx.xin->flow, in_port, + in_port = get_ofp_port(ctx.ofproto, flow->in_port); + special = process_special(ctx.ofproto, flow, in_port, ctx.xin->packet); if (special) { ctx.xout->slow = special; @@ -7024,14 +6995,14 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) initial_vals.vlan_tci = ctx.base_flow.vlan_tci; - add_sflow_action(&ctx); - add_ipfix_action(&ctx); + add_sflow_action(&ctx, flow); + add_ipfix_action(&ctx, flow); sample_actions_len = ctx.xout->odp_actions.size; - if (tunnel_ecn_ok(&ctx) - && (!in_port || may_receive(in_port, ctx.xin->flow))) { + if (tunnel_ecn_ok(&ctx, flow) + && (!in_port || may_receive(in_port, flow))) { - do_xlate_actions(ofpacts, ofpacts_len, &ctx); + do_xlate_actions(ofpacts, ofpacts_len, &ctx, flow); /* We've let OFPP_NORMAL and the learning action look at the * packet, so drop it now if forwarding is disabled. */ @@ -7057,11 +7028,11 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) } local_odp_port = ofp_port_to_odp_port(ctx.ofproto, OFPP_LOCAL); - if (!connmgr_must_output_local(ctx.ofproto->up.connmgr, ctx.xin->flow, + if (!connmgr_must_output_local(ctx.ofproto->up.connmgr, flow, local_odp_port, ctx.xout->odp_actions.data, ctx.xout->odp_actions.size)) { - compose_output_action(&ctx, OFPP_LOCAL); + compose_output_action(&ctx, flow, OFPP_LOCAL); } if (ctx.ofproto->has_mirrors) { add_mirror_actions(&ctx, &orig_flow); @@ -7072,14 +7043,15 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) ofpbuf_uninit(&ctx.stack); } -/* Translates the 'ofpacts_len' bytes of "struct ofpact"s starting at 'ofpacts' - * into datapath actions, using 'ctx', and discards the datapath actions. */ +/* Translates the 'ofpacts' in either 'xin' or 'xin->rule' into datapath + * actions using 'flow', discarding the results, but "keeping" the + * side effects, such as any special processing and controller actions. */ static void -xlate_actions_for_side_effects(struct xlate_in *xin) +xlate_actions_for_side_effects(struct xlate_in *xin, struct flow *flow) { struct xlate_out xout; - xlate_actions(xin, &xout); + xlate_actions(xin, flow, &xout); xlate_out_uninit(&xout); } @@ -7205,10 +7177,9 @@ output_vlan_to_vid(const struct ofbundle *out_bundle, uint16_t vlan) } static void -output_normal(struct xlate_ctx *ctx, const struct ofbundle *out_bundle, - uint16_t vlan) +output_normal(struct xlate_ctx *ctx, struct flow *flow, + const struct ofbundle *out_bundle, uint16_t vlan) { - struct flow *flow = ctx->xin->flow; struct ofport_dpif *port; uint16_t vid; ovs_be16 tci, old_tci; @@ -7235,7 +7206,7 @@ output_normal(struct xlate_ctx *ctx, const struct ofbundle *out_bundle, } flow->vlan_tci = tci; - compose_output_action(ctx, port->up.ofp_port); + compose_output_action(ctx, flow, port->up.ofp_port); flow->vlan_tci = old_tci; } @@ -7274,9 +7245,8 @@ vlan_is_mirrored(const struct ofmirror *m, int vlan) } static void -add_mirror_actions(struct xlate_ctx *ctx, struct flow *orig_flow) +add_mirror_actions(struct xlate_ctx *ctx, struct flow *flow) { - struct flow * flow = ctx->xin->flow; struct ofproto_dpif *ofproto = ctx->ofproto; mirror_mask_t mirrors; struct ofbundle *in_bundle; @@ -7285,7 +7255,7 @@ add_mirror_actions(struct xlate_ctx *ctx, struct flow *orig_flow) const struct nlattr *a; size_t left; - in_bundle = lookup_input_bundle(ctx->ofproto, orig_flow->in_port, + in_bundle = lookup_input_bundle(ctx->ofproto, flow->in_port, ctx->xin->packet != NULL, NULL); if (!in_bundle) { return; @@ -7304,7 +7274,7 @@ add_mirror_actions(struct xlate_ctx *ctx, struct flow *orig_flow) } /* Check VLAN. */ - vid = vlan_tci_to_vid(orig_flow->vlan_tci); + vid = vlan_tci_to_vid(flow->vlan_tci); if (!input_vid_is_valid(vid, in_bundle, ctx->xin->packet != NULL)) { return; } @@ -7331,9 +7301,6 @@ add_mirror_actions(struct xlate_ctx *ctx, struct flow *orig_flow) return; } - /* Point to the original flow before adding the mirror actions. */ - ctx->xin->flow = orig_flow; - while (mirrors) { struct ofmirror *m; @@ -7347,22 +7314,19 @@ add_mirror_actions(struct xlate_ctx *ctx, struct flow *orig_flow) mirrors &= ~m->dup_mirrors; ctx->xout->mirrors |= m->dup_mirrors; if (m->out) { - output_normal(ctx, m->out, vlan); + output_normal(ctx, flow, m->out, vlan); } else if (vlan != m->out_vlan - && !eth_addr_is_reserved(orig_flow->dl_dst)) { + && !eth_addr_is_reserved(flow->dl_dst)) { struct ofbundle *bundle; HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) { if (ofbundle_includes_vlan(bundle, m->out_vlan) && !bundle->mirror_out) { - output_normal(ctx, bundle, m->out_vlan); + output_normal(ctx, flow, bundle, m->out_vlan); } } } } - - /* Restore current flow pointer */ - ctx->xin->flow = flow; } static void @@ -7506,11 +7470,9 @@ lookup_input_bundle(const struct ofproto_dpif *ofproto, uint16_t in_port, * so in one special case. */ static bool -is_admissible(struct xlate_ctx *ctx, struct ofport_dpif *in_port, - uint16_t vlan) +is_admissible(struct xlate_ctx *ctx, struct flow *flow, + struct ofport_dpif *in_port, uint16_t vlan) { - struct flow *flow = ctx->xin->flow; - struct ofproto_dpif *ofproto = ctx->ofproto; struct ofbundle *in_bundle = in_port->bundle; @@ -7550,10 +7512,8 @@ is_admissible(struct xlate_ctx *ctx, struct ofport_dpif *in_port, } static void -xlate_normal(struct xlate_ctx *ctx) +xlate_normal(struct xlate_ctx *ctx, struct flow *flow) { - struct flow *flow = ctx->xin->flow; - struct ofport_dpif *in_port; struct ofbundle *in_bundle; struct mac_entry *mac; @@ -7603,7 +7563,7 @@ xlate_normal(struct xlate_ctx *ctx) vlan = input_vid_to_vlan(in_bundle, vid); /* Check other admissibility requirements. */ - if (in_port && !is_admissible(ctx, in_port, vlan)) { + if (in_port && !is_admissible(ctx, flow, in_port, vlan)) { return; } @@ -7618,7 +7578,7 @@ xlate_normal(struct xlate_ctx *ctx) if (mac) { if (mac->port.p != in_bundle) { xlate_report(ctx, "forwarding to learned port"); - output_normal(ctx, mac->port.p, vlan); + output_normal(ctx, flow, mac->port.p, vlan); } else { xlate_report(ctx, "learned port is input port, dropping"); } @@ -7631,7 +7591,7 @@ xlate_normal(struct xlate_ctx *ctx) && ofbundle_includes_vlan(bundle, vlan) && bundle->floodable && !bundle->mirror_out) { - output_normal(ctx, bundle, vlan); + output_normal(ctx, flow, bundle, vlan); } } ctx->xout->nf_output_iface = NF_OUT_FLOOD; @@ -7791,7 +7751,7 @@ packet_out(struct ofproto *ofproto_, struct ofpbuf *packet, xin.ofpacts_len = ofpacts_len; xin.ofpacts = ofpacts; - xlate_actions(&xin, &xout); + xlate_actions(&xin, &xin.flow_storage, &xout); dpif_execute(ofproto->backer->dpif, key.data, key.size, xout.odp_actions.data, xout.odp_actions.size, packet); xlate_out_uninit(&xout); @@ -7959,11 +7919,11 @@ trace_format_flow(struct ds *result, int level, const char *title, { ds_put_char_multiple(result, '\t', level); ds_put_format(result, "%s: ", title); - if (flow_equal(trace->xin.flow, &trace->flow)) { + if (flow_equal(&trace->xin.flow_storage, &trace->flow)) { ds_put_cstr(result, "unchanged"); } else { - flow_format(result, trace->xin.flow); - trace->flow = *trace->xin.flow; + flow_format(result, &trace->xin.flow_storage); + trace->flow = trace->xin.flow_storage; } ds_put_char(result, '\n'); } @@ -8174,7 +8134,7 @@ ofproto_trace(struct ofproto_dpif *ofproto, const struct flow *flow, packet); trace.xin.resubmit_hook = trace_resubmit; trace.xin.report_hook = trace_report; - xlate_actions(&trace.xin, &trace.xout); + xlate_actions(&trace.xin, &trace.xin.flow_storage, &trace.xout); ds_put_char(ds, '\n'); trace_format_flow(ds, 0, "Final flow", &trace); -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev