[ovs-dev] [PATCH 08/11] ofproto-dpif: pass flow pointer as an argument.

Jarno Rajahalme jarno.rajahalme at nsn.com
Fri May 31 11:35:18 UTC 2013


Signed-off-by: Jarno Rajahalme <jarno.rajahalme at 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




More information about the dev mailing list