When a wildcarded flow is expired we remove all of the subrules to
collect their stats before sending a flow expiration message. However,
we were only removing exact match flows after the expiration message
is composed. This uninstalls it first.
CC: David Erickson <derickso@stanford.edu>
}
COVERAGE_INC(ofproto_expired);
}
COVERAGE_INC(ofproto_expired);
+
+ /* Update stats. This code will be a no-op if the rule expired
+ * due to an idle timeout. */
if (rule->cr.wc.wildcards) {
if (rule->cr.wc.wildcards) {
- /* Update stats. (This code will be a no-op if the rule expired
- * due to an idle timeout, because in that case the rule has no
- * subrules left.) */
struct rule *subrule, *next;
LIST_FOR_EACH_SAFE (subrule, next, struct rule, list, &rule->list) {
rule_remove(p, subrule);
}
struct rule *subrule, *next;
LIST_FOR_EACH_SAFE (subrule, next, struct rule, list, &rule->list) {
rule_remove(p, subrule);
}
+ } else {
+ rule_uninstall(p, rule);
}
send_flow_exp(p, rule, now,
}
send_flow_exp(p, rule, now,