netflow: Fold netflow_expire() into netflow_flow_clear().
[cascardo/ovs.git] / ofproto / ofproto-dpif-xlate.c
index da538b7..b4a1ed4 100644 (file)
@@ -267,7 +267,8 @@ struct xc_entry {
         } bond;
         struct {
             struct ofproto_dpif *ofproto;
-            struct rule_dpif *rule;
+            struct ofputil_flow_mod *fm;
+            struct ofpbuf *ofpacts;
         } learn;
         struct {
             struct ofproto_dpif *ofproto;
@@ -1553,7 +1554,7 @@ xlate_normal(struct xlate_ctx *ctx)
 
         /* Save enough info to update mac learning table later. */
         entry = xlate_cache_add_entry(ctx->xin->xcache, XC_NORMAL);
-        entry->u.normal.ofproto = ctx->xin->ofproto;
+        entry->u.normal.ofproto = ctx->xbridge->ofproto;
         entry->u.normal.flow = xmemdup(flow, sizeof *flow);
         entry->u.normal.vlan = vlan;
     }
@@ -2634,35 +2635,38 @@ xlate_bundle_action(struct xlate_ctx *ctx,
 }
 
 static void
-xlate_learn_action(struct xlate_ctx *ctx,
-                   const struct ofpact_learn *learn)
+xlate_learn_action__(struct xlate_ctx *ctx, const struct ofpact_learn *learn,
+                     struct ofputil_flow_mod *fm, struct ofpbuf *ofpacts)
 {
-    uint64_t ofpacts_stub[1024 / 8];
-    struct ofputil_flow_mod fm;
-    struct ofpbuf ofpacts;
+    learn_execute(learn, &ctx->xin->flow, fm, ofpacts);
+    if (ctx->xin->may_learn) {
+        ofproto_dpif_flow_mod(ctx->xbridge->ofproto, fm);
+    }
+}
 
+static void
+xlate_learn_action(struct xlate_ctx *ctx, const struct ofpact_learn *learn)
+{
     ctx->xout->has_learn = true;
-
     learn_mask(learn, &ctx->xout->wc);
 
-    if (!ctx->xin->may_learn) {
-        return;
-    }
-
-    ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
-    learn_execute(learn, &ctx->xin->flow, &fm, &ofpacts);
-    ofproto_dpif_flow_mod(ctx->xbridge->ofproto, &fm);
-    ofpbuf_uninit(&ofpacts);
-
     if (ctx->xin->xcache) {
         struct xc_entry *entry;
 
         entry = xlate_cache_add_entry(ctx->xin->xcache, XC_LEARN);
-        entry->u.learn.ofproto = ctx->xin->ofproto;
-        /* Lookup the learned rule, taking a reference on it.  The reference
-         * is released when this cache entry is deleted. */
-        rule_dpif_lookup(ctx->xbridge->ofproto, &ctx->xin->flow, NULL,
-                         &entry->u.learn.rule, true);
+        entry->u.learn.ofproto = ctx->xbridge->ofproto;
+        entry->u.learn.fm = xmalloc(sizeof *entry->u.learn.fm);
+        entry->u.learn.ofpacts = ofpbuf_new(64);
+        xlate_learn_action__(ctx, learn, entry->u.learn.fm,
+                             entry->u.learn.ofpacts);
+    } else if (ctx->xin->may_learn) {
+        uint64_t ofpacts_stub[1024 / 8];
+        struct ofputil_flow_mod fm;
+        struct ofpbuf ofpacts;
+
+        ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
+        xlate_learn_action__(ctx, learn, &fm, &ofpacts);
+        ofpbuf_uninit(&ofpacts);
     }
 }
 
@@ -3417,9 +3421,6 @@ xlate_actions__(struct xlate_in *xin, struct xlate_out *xout)
     }
 
     if (ctx.xbridge->netflow) {
-        const struct ofpact *ofpacts = actions->ofpacts;
-        size_t ofpacts_len = actions->ofpacts_len;
-
         /* Only update netflow if we don't have controller flow.  We don't
          * report NetFlow expiration messages for such facets because they
          * are just part of the control logic for the network, not real
@@ -3582,12 +3583,8 @@ xlate_push_stats(struct xlate_cache *xcache, bool may_learn,
             break;
         case XC_LEARN:
             if (may_learn) {
-                struct rule_dpif *rule = entry->u.learn.rule;
-
-                /* Reset the modified time for a rule that is equivalent to
-                 * the currently cached rule.  If the rule is not the exact
-                 * rule we have cached, update the reference that we have. */
-                entry->u.learn.rule = ofproto_dpif_refresh_rule(rule);
+                ofproto_dpif_flow_mod(entry->u.learn.ofproto,
+                                      entry->u.learn.fm);
             }
             break;
         case XC_NORMAL:
@@ -3621,7 +3618,6 @@ xlate_dev_unref(struct xc_entry *entry)
 static void
 xlate_cache_clear_netflow(struct netflow *netflow, struct flow *flow)
 {
-    netflow_expire(netflow, flow);
     netflow_flow_clear(netflow, flow);
     netflow_unref(netflow);
     free(flow);
@@ -3656,8 +3652,8 @@ xlate_cache_clear(struct xlate_cache *xcache)
             mbridge_unref(entry->u.mirror.mbridge);
             break;
         case XC_LEARN:
-            /* 'u.learn.rule' is the learned rule. */
-            rule_dpif_unref(entry->u.learn.rule);
+            free(entry->u.learn.fm);
+            ofpbuf_delete(entry->u.learn.ofpacts);
             break;
         case XC_NORMAL:
             free(entry->u.normal.flow);