struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
atomic_store_relaxed(&ofproto->tables_version, version);
+ ofproto->backer->need_revalidate = REV_FLOW_TABLE;
}
-
static struct ofport *
port_alloc(void)
{
return rule;
}
-static void
-complete_operation(struct rule_dpif *rule)
- OVS_REQUIRES(ofproto_mutex)
-{
- struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->up.ofproto);
-
- ofproto->backer->need_revalidate = REV_FLOW_TABLE;
-}
-
static struct rule_dpif *rule_dpif_cast(const struct rule *rule)
{
return rule ? CONTAINER_OF(rule, struct rule_dpif, up) : NULL;
ovs_mutex_unlock(&rule->stats_mutex);
ovs_mutex_unlock(&old_rule->stats_mutex);
}
-
- complete_operation(rule);
-}
-
-static void
-rule_delete(struct rule *rule_)
- OVS_REQUIRES(ofproto_mutex)
-{
- struct rule_dpif *rule = rule_dpif_cast(rule_);
- complete_operation(rule);
}
static void
rule_alloc,
rule_construct,
rule_insert,
- rule_delete,
+ NULL, /* rule_delete */
rule_destruct,
rule_dealloc,
rule_get_stats,
struct ofputil_table_stats *stats);
/* Sets the current tables version the provider should use for classifier
- * lookups. */
+ * lookups. This must be called with a new version number after each set
+ * of flow table changes has been completed, so that datapath revalidation
+ * can be triggered. */
void (*set_tables_version)(struct ofproto *ofproto, cls_version_t version);
+
/* ## ---------------- ## */
/* ## ofport Functions ## */
/* ## ---------------- ## */
* ========
*
* The ofproto base code removes 'rule' from its flow table before it calls
- * ->rule_delete(). ->rule_delete() must remove 'rule' from the datapath
- * flow table and return only after this has completed successfully.
+ * ->rule_delete() (if non-null). ->rule_delete() must remove 'rule' from
+ * the datapath flow table and return only after this has completed
+ * successfully.
*
* Rule deletion must not fail.
*
OVS_NOT_REACHED();
}
ofproto_rule_remove__(rule->ofproto, rule);
- ofproto->ofproto_class->rule_delete(rule);
+ if (ofproto->ofproto_class->rule_delete) {
+ ofproto->ofproto_class->rule_delete(rule);
+ }
ofproto_rule_unref(rule);
}
ovs_mutex_unlock(&ofproto_mutex);
if (!classifier_remove(&table->cls, &rule->cr)) {
OVS_NOT_REACHED();
}
- ofproto->ofproto_class->rule_delete(rule);
+ if (ofproto->ofproto_class->rule_delete) {
+ ofproto->ofproto_class->rule_delete(rule);
+ }
ofproto_rule_unref(rule);
}