struct oftable *tables;
int n_tables;
- struct hindex cookies; /* Rules indexed on their cookie values. */
+ /* Rules indexed on their cookie values, in all flow tables. */
+ struct hindex cookies OVS_GUARDED_BY(ofproto_mutex);
/* List of expirable flows, in all flow tables. */
struct list expirable OVS_GUARDED_BY(ofproto_mutex);
ovs_be64 flow_cookie; /* Controller-issued identifier. Guarded by
rwlock. */
- struct hindex_node cookie_node; /* In owning ofproto's 'cookies' index. */
+ struct hindex_node cookie_node OVS_GUARDED_BY(ofproto_mutex);
long long int created; /* Creation time. */
long long int modified; /* Time of last modification. */
static void
cookies_insert(struct ofproto *ofproto, struct rule *rule)
+ OVS_REQUIRES(ofproto_mutex)
{
hindex_insert(&ofproto->cookies, &rule->cookie_node,
hash_cookie(rule->flow_cookie));
static void
cookies_remove(struct ofproto *ofproto, struct rule *rule)
+ OVS_REQUIRES(ofproto_mutex)
{
hindex_remove(&ofproto->cookies, &rule->cookie_node);
}
ovs_be64 new_cookie)
{
if (new_cookie != rule->flow_cookie) {
+ ovs_mutex_lock(&ofproto_mutex);
cookies_remove(ofproto, rule);
ovs_rwlock_wrlock(&rule->rwlock);
ovs_rwlock_unlock(&rule->rwlock);
cookies_insert(ofproto, rule);
+ ovs_mutex_unlock(&ofproto_mutex);
}
}
if (criteria->cookie_mask == htonll(UINT64_MAX)) {
struct rule *rule;
+ ovs_mutex_lock(&ofproto_mutex);
HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node,
hash_cookie(criteria->cookie),
&ofproto->cookies) {
}
}
}
+ ovs_mutex_unlock(&ofproto_mutex);
} else {
FOR_EACH_MATCHING_TABLE (table, criteria->table_id, ofproto) {
struct cls_cursor cursor;
if (criteria->cookie_mask == htonll(UINT64_MAX)) {
struct rule *rule;
+ ovs_mutex_lock(&ofproto_mutex);
HINDEX_FOR_EACH_WITH_HASH (rule, cookie_node,
hash_cookie(criteria->cookie),
&ofproto->cookies) {
}
}
}
+ ovs_mutex_unlock(&ofproto_mutex);
} else {
FOR_EACH_MATCHING_TABLE (table, criteria->table_id, ofproto) {
struct rule *rule;
OVS_REQ_WRLOCK(cls->rwlock) OVS_RELEASES(rule->rwlock)
{
classifier_remove(cls, &rule->cr);
+
+ ovs_mutex_lock(&ofproto_mutex);
cookies_remove(ofproto, rule);
+ ovs_mutex_unlock(&ofproto_mutex);
+
eviction_group_remove_rule(rule);
ovs_mutex_lock(&ofproto_mutex);
if (!list_is_empty(&rule->expirable)) {
list_insert(&ofproto->expirable, &rule->expirable);
ovs_mutex_unlock(&ofproto_mutex);
}
+
+ ovs_mutex_lock(&ofproto_mutex);
cookies_insert(ofproto, rule);
+ ovs_mutex_unlock(&ofproto_mutex);
if (rule->actions->meter_id) {
struct meter *meter = ofproto->meters[rule->actions->meter_id];