From 308881afb61e292c629b36a357cfc37153884000 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 19 Aug 2011 10:33:09 -0700 Subject: [PATCH] ofproto: Reinterpret meaning of OpenFlow hard timeouts with OFPFC_MODIFY. I finally found a good use for hard timeouts in OpenFlow, but they require a slight reinterpretation of the meaning of hard timeouts. Until now, a hard timeout meant that a flow would be removed the specified number of seconds after a flow was created. Intervening modifications with OFPFC_MODIFY(_STRICT) had no effect on the hard timeout; the flow would still be deleted the specified number of seconds after its original creation. This commit changes the effect of OFPFC_MODIFY(_STRICT). Now, modifying a flow resets its hard timeout counter. A flow will time out the specified number of seconds after creation or after the last time it is modified, whichever comes later. --- ofproto/ofproto-dpif.c | 2 +- ofproto/ofproto-provider.h | 3 ++- ofproto/ofproto.c | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 7174748b..93920452 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -2009,7 +2009,7 @@ rule_expire(struct rule_dpif *rule) /* Has 'rule' expired? */ now = time_msec(); if (rule->up.hard_timeout - && now > rule->up.created + rule->up.hard_timeout * 1000) { + && 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) { diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 6e29ed9b..b1c69722 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -107,8 +107,9 @@ struct rule { ovs_be64 flow_cookie; /* Controller-issued identifier. */ 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 time of creation. */ + uint16_t hard_timeout; /* In seconds from last modification. */ uint8_t table_id; /* Index in ofproto's 'tables' array. */ bool send_flow_removed; /* Send a flow removed message? */ diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 33cd85e5..b96fa6e6 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -2252,7 +2252,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, rule->cr = fm->cr; rule->pending = NULL; rule->flow_cookie = fm->cookie; - rule->created = time_msec(); + rule->created = rule->modified = time_msec(); rule->idle_timeout = fm->idle_timeout; rule->hard_timeout = fm->hard_timeout; rule->table_id = table - ofproto->tables; @@ -2315,6 +2315,8 @@ modify_flows__(struct ofproto *ofproto, struct ofconn *ofconn, rule->actions = ofputil_actions_clone(fm->actions, fm->n_actions); rule->n_actions = fm->n_actions; rule->ofproto->ofproto_class->rule_modify_actions(rule); + } else { + rule->modified = time_msec(); } rule->flow_cookie = fm->cookie; } @@ -2944,7 +2946,9 @@ ofoperation_complete(struct ofoperation *op, int error) break; case OFOPERATION_MODIFY: - if (error) { + if (!error) { + rule->modified = time_msec(); + } else { free(rule->actions); rule->actions = op->actions; rule->n_actions = op->n_actions; -- 2.30.2