aboutsummaryrefslogtreecommitdiff
path: root/ofproto/ofproto-dpif.c
diff options
context:
space:
mode:
Diffstat (limited to 'ofproto/ofproto-dpif.c')
-rw-r--r--ofproto/ofproto-dpif.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 7f566f80..a7107457 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -210,11 +210,17 @@ struct action_xlate_ctx {
* revalidating without a packet to refer to. */
const struct ofpbuf *packet;
- /* Should OFPP_NORMAL MAC learning and NXAST_LEARN actions execute? We
- * want to execute them if we are actually processing a packet, or if we
- * are accounting for packets that the datapath has processed, but not if
- * we are just revalidating. */
- bool may_learn;
+ /* Should OFPP_NORMAL update the MAC learning table? We want to update it
+ * if we are actually processing a packet, or if we are accounting for
+ * packets that the datapath has processed, but not if we are just
+ * revalidating. */
+ bool may_learn_macs;
+
+ /* Should "learn" actions update the flow table? We want to update it if
+ * we are actually processing a packet, or in most cases if we are
+ * accounting for packets that the datapath has processed, but not if we
+ * are just revalidating. */
+ bool may_flow_mod;
/* Cookie of the currently matching rule, or 0. */
ovs_be64 cookie;
@@ -336,7 +342,8 @@ static void facet_update_time(struct ofproto_dpif *, struct facet *,
long long int used);
static void facet_reset_counters(struct facet *);
static void facet_push_stats(struct facet *);
-static void facet_account(struct ofproto_dpif *, struct facet *);
+static void facet_account(struct ofproto_dpif *, struct facet *,
+ bool may_flow_mod);
static bool facet_is_controller_flow(struct facet *);
@@ -2946,7 +2953,7 @@ update_stats(struct ofproto_dpif *p)
subfacet->dp_byte_count = stats->n_bytes;
subfacet_update_time(p, subfacet, stats->used);
- facet_account(p, facet);
+ facet_account(p, facet, true);
facet_push_stats(facet);
} else {
if (!VLOG_DROP_WARN(&rl)) {
@@ -3198,7 +3205,8 @@ facet_remove(struct ofproto_dpif *ofproto, struct facet *facet)
}
static void
-facet_account(struct ofproto_dpif *ofproto, struct facet *facet)
+facet_account(struct ofproto_dpif *ofproto, struct facet *facet,
+ bool may_flow_mod)
{
uint64_t n_bytes;
struct subfacet *subfacet;
@@ -3221,7 +3229,8 @@ facet_account(struct ofproto_dpif *ofproto, struct facet *facet)
action_xlate_ctx_init(&ctx, ofproto, &facet->flow,
facet->flow.vlan_tci,
facet->rule->up.flow_cookie, NULL);
- ctx.may_learn = true;
+ ctx.may_learn_macs = true;
+ ctx.may_flow_mod = may_flow_mod;
ofpbuf_delete(xlate_actions(&ctx, facet->rule->up.actions,
facet->rule->up.n_actions));
}
@@ -3294,7 +3303,7 @@ facet_flush_stats(struct ofproto_dpif *ofproto, struct facet *facet)
}
facet_push_stats(facet);
- facet_account(ofproto, facet);
+ facet_account(ofproto, facet, false);
if (ofproto->netflow && !facet_is_controller_flow(facet)) {
struct ofexpired expired;
@@ -4741,7 +4750,7 @@ do_xlate_actions(const union ofp_action *in, size_t n_in,
case OFPUTIL_NXAST_LEARN:
ctx->has_learn = true;
- if (ctx->may_learn) {
+ if (ctx->may_flow_mod) {
xlate_learn_action(ctx, (const struct nx_action_learn *) ia);
}
break;
@@ -4773,7 +4782,8 @@ action_xlate_ctx_init(struct action_xlate_ctx *ctx,
ctx->base_flow.vlan_tci = initial_tci;
ctx->cookie = cookie;
ctx->packet = packet;
- ctx->may_learn = packet != NULL;
+ ctx->may_learn_macs = packet != NULL;
+ ctx->may_flow_mod = packet != NULL;
ctx->resubmit_hook = NULL;
}
@@ -5380,7 +5390,7 @@ xlate_normal(struct action_xlate_ctx *ctx)
}
/* Learn source MAC. */
- if (ctx->may_learn) {
+ if (ctx->may_learn_macs) {
update_learning_table(ctx->ofproto, &ctx->flow, vlan, in_bundle);
}