ofproto: Move 'used' from ofproto_dpif into ofproto.
authorBen Pfaff <blp@nicira.com>
Sat, 14 Jan 2012 00:40:59 +0000 (16:40 -0800)
committerBen Pfaff <blp@nicira.com>
Wed, 1 Feb 2012 22:15:15 +0000 (14:15 -0800)
This will allow the upcoming flow table eviction policy code to determine
which flows will expire soon.

Signed-off-by: Ben Pfaff <blp@nicira.com>
NEWS
ofproto/ofproto-dpif.c
ofproto/ofproto-provider.h
ofproto/ofproto.c

diff --git a/NEWS b/NEWS
index 96c86c421e9da6348ecbd220844bb0a0af38e118..415b9f28a2e81323721e5f5557c3cd0597ad82ec 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,9 @@ post-v1.5.0
     - Logging to console and file will have UTC timestamp as a default for all
       the daemons. An example of the default format is 2012-01-27T16:35:17Z.
       ovs-appctl can be used to change the default format as before.
+    - ofproto-provider interface:
+        - "struct rule" has a new member "used" that ofproto implementations
+          should maintain by updating with ofproto_rule_update_used().
 
 
 v1.5.0 - xx xxx xxxx
index a6087bf39ef49fec90d9a9c7e5e72761dfe00382..840e74bd90bd29f7bdadd52acf729663e9fd9e69 100644 (file)
@@ -76,8 +76,6 @@ struct ofproto_dpif;
 struct rule_dpif {
     struct rule up;
 
-    long long int used;         /* Time last used; time created if not used. */
-
     /* These statistics:
      *
      *   - Do include packets and bytes from facets that have been deleted or
@@ -3088,7 +3086,7 @@ rule_expire(struct rule_dpif *rule)
         && now > rule->up.modified + rule->up.hard_timeout * 1000) {
         reason = OFPRR_HARD_TIMEOUT;
     } else if (rule->up.idle_timeout && list_is_empty(&rule->facets)
-               && now > rule->used + rule->up.idle_timeout * 1000) {
+               && now > rule->up.used + rule->up.idle_timeout * 1000) {
         reason = OFPRR_IDLE_TIMEOUT;
     } else {
         return;
@@ -3611,9 +3609,7 @@ facet_update_time(struct facet *facet, long long int used)
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(facet->rule->up.ofproto);
     if (used > facet->used) {
         facet->used = used;
-        if (used > facet->rule->used) {
-            facet->rule->used = used;
-        }
+        ofproto_rule_update_used(&facet->rule->up, used);
         netflow_flow_update_time(ofproto->netflow, &facet->nf_flow, used);
     }
 }
@@ -3668,7 +3664,7 @@ push_resubmit(struct action_xlate_ctx *ctx, struct rule_dpif *rule)
     if (rule) {
         rule->packet_count += push->packets;
         rule->byte_count += push->bytes;
-        rule->used = MAX(push->used, rule->used);
+        ofproto_rule_update_used(&rule->up, push->used);
     }
 }
 
@@ -4034,7 +4030,6 @@ rule_construct(struct rule *rule_)
         return error;
     }
 
-    rule->used = rule->up.created;
     rule->packet_count = 0;
     rule->byte_count = 0;
 
@@ -4118,10 +4113,10 @@ rule_execute(struct rule *rule_, const struct flow *flow,
     size = packet->size;
     if (execute_odp_actions(ofproto, flow, odp_actions->data,
                             odp_actions->size, packet)) {
-        rule->used = time_msec();
+        ofproto_rule_update_used(&rule->up, time_msec());
         rule->packet_count++;
         rule->byte_count += size;
-        flow_push_stats(rule, flow, 1, size, rule->used);
+        flow_push_stats(rule, flow, 1, size, rule->up.used);
     }
     ofpbuf_delete(odp_actions);
 
index 2d647fe3ccc0581a771e36dbe5552c06aad6f7db..9fb5effdea0666e393e3e741080f01a900c5ab86 100644 (file)
@@ -136,8 +136,9 @@ struct rule {
 
     long long int created;       /* Creation time. */
     long long int modified;      /* Time of last modification. */
-    uint16_t idle_timeout;       /* In seconds from time of last use. */
-    uint16_t hard_timeout;       /* In seconds from last modification. */
+    long long int used;          /* Last use; time created if never used. */
+    uint16_t hard_timeout;       /* In seconds from ->modified. */
+    uint16_t idle_timeout;       /* In seconds from ->used. */
     uint8_t table_id;            /* Index in ofproto's 'tables' array. */
     bool send_flow_removed;      /* Send a flow removed message? */
 
@@ -151,6 +152,7 @@ rule_from_cls_rule(const struct cls_rule *cls_rule)
     return cls_rule ? CONTAINER_OF(cls_rule, struct rule, cr) : NULL;
 }
 
+void ofproto_rule_update_used(struct rule *, long long int used);
 void ofproto_rule_expire(struct rule *, uint8_t reason);
 void ofproto_rule_destroy(struct rule *);
 
index 3dab46a4ea3b7e8f1959cadab5b3e0653eb70a35..b27a41c7fa8e9536071190a4751a9395d8271287 100644 (file)
@@ -2580,7 +2580,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn,
     rule->cr = fm->cr;
     rule->pending = NULL;
     rule->flow_cookie = fm->cookie;
-    rule->created = rule->modified = time_msec();
+    rule->created = rule->modified = rule->used = time_msec();
     rule->idle_timeout = fm->idle_timeout;
     rule->hard_timeout = fm->hard_timeout;
     rule->table_id = table - ofproto->tables;
@@ -2785,6 +2785,14 @@ ofproto_rule_send_removed(struct rule *rule, uint8_t reason)
     connmgr_send_flow_removed(rule->ofproto->connmgr, &fr);
 }
 
+void
+ofproto_rule_update_used(struct rule *rule, long long int used)
+{
+    if (used > rule->used) {
+        rule->used = used;
+    }
+}
+
 /* Sends an OpenFlow "flow removed" message with the given 'reason' (either
  * OFPRR_HARD_TIMEOUT or OFPRR_IDLE_TIMEOUT), and then removes 'rule' from its
  * ofproto.