A given rule may only have one pending operation at a time, so when an
operation is pending we must not allow a flow expiration to be started on
that rule.
This doesn't fix a user-visible bug in ofproto-dpif because ofproto-dpif
always completes operations immediately, that is, no operations will be
pending when expiration runs. (Technically there is a bug if the user
runs "ovs-appctl ofproto/clog", but that feature is for debugging only and
there is no reason for a user to ever run it.)
Signed-off-by: Ben Pfaff <blp@nicira.com>
long long int now;
uint8_t reason;
+ if (rule->up.pending) {
+ /* We'll have to expire it later. */
+ return;
+ }
+
/* Has 'rule' expired? */
now = time_msec();
if (rule->up.hard_timeout
* - Call ofproto_rule_expire() for each OpenFlow flow that has reached
* its hard_timeout or idle_timeout, to expire the flow.
*
+ * (But rules that are part of a pending operation, e.g. rules for
+ * which ->pending is true, may not expire.)
+ *
* Returns 0 if successful, otherwise a positive errno value. */
int (*run)(struct ofproto *ofproto);
* OFPRR_HARD_TIMEOUT or OFPRR_IDLE_TIMEOUT), and then removes 'rule' from its
* ofproto.
*
+ * 'rule' must not have a pending operation (that is, 'rule->pending' must be
+ * NULL).
+ *
* ofproto implementation ->run() functions should use this function to expire
* OpenFlow flows. */
void