[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