* Thread-safety
* =============
*
- * A cls->rwlock read-lock holder prevents rules from being added or deleted.
+ * Adding or removing rules requires holding ofproto_mutex.
*
- * Adding or removing rules requires holding ofproto_mutex AND the cls->rwlock
- * write-lock.
+ * Rules in 'cls' are RCU protected. For extended access to a rule, try
+ * incrementing its ref_count with ofproto_rule_try_ref(), or
+ * ofproto_rule_ref(), if the rule is still known to be in 'cls'. A rule
+ * will be freed using ovsrcu_postpone() once its 'ref_count' reaches zero.
*
- * cls->rwlock should be held only briefly. For extended access to a rule,
- * increment its ref_count with ofproto_rule_ref(). A rule will not be freed
- * until its ref_count reaches zero.
+ * Modifying a rule requires the rule's own mutex.
*
- * Modifying a rule requires the rule's own mutex. Holding cls->rwlock (for
- * read or write) does not allow the holder to modify the rule.
- *
- * Freeing a rule requires ofproto_mutex and the cls->rwlock write-lock. After
- * removing the rule from the classifier, release a ref_count from the rule
- * ('cls''s reference to the rule).
+ * Freeing a rule requires ofproto_mutex. After removing the rule from the
+ * classifier, release a ref_count from the rule ('cls''s reference to the
+ * rule).
*
* Refer to the thread-safety notes on struct rule for more information.*/
struct oftable {
struct hmap eviction_groups_by_id;
struct heap eviction_groups_by_size;
- /* Table config: contains enum ofproto_table_config; accessed atomically. */
- atomic_uint config;
+ /* Table configuration. */
+ ATOMIC(enum ofputil_table_miss) miss_config;
atomic_ulong n_matched;
atomic_ulong n_missed;
* Rules
* -----
*
- * A rule 'rule' may be accessed without a risk of being freed by code that
- * holds a read-lock or write-lock on 'cls->rwlock' or that owns a reference to
- * 'rule->ref_count' (or both). Code that needs to hold onto a rule for a
- * while should take 'cls->rwlock', find the rule it needs, increment
- * 'rule->ref_count' with ofproto_rule_ref(), and drop 'cls->rwlock'.
+ * A rule 'rule' may be accessed without a risk of being freed by a thread
+ * until the thread quiesces (i.e., rules are RCU protected and destructed
+ * using ovsrcu_postpone()). Code that needs to hold onto a rule for a
+ * while should increment 'rule->ref_count' either with ofproto_rule_ref()
+ * (if 'ofproto_mutex' is held), or with ofproto_rule_try_ref() (when some
+ * other thread might remove the rule from 'cls'). ofproto_rule_try_ref()
+ * will fail if the rule has already been scheduled for destruction.
*
* 'rule->ref_count' protects 'rule' from being freed. It doesn't protect the
- * rule from being deleted from 'cls' (that's 'cls->rwlock') and it doesn't
+ * rule from being deleted from 'cls' (that's 'ofproto_mutex') and it doesn't
* protect members of 'rule' from modification (that's 'rule->mutex').
*
* 'rule->mutex' protects the members of 'rule' from modification. It doesn't
- * protect the rule from being deleted from 'cls' (that's 'cls->rwlock') and it
- * doesn't prevent the rule from being freed (that's 'rule->ref_count').
+ * protect the rule from being deleted from 'cls' (that's 'ofproto_mutex') and
+ * it doesn't prevent the rule from being freed (that's 'rule->ref_count').
*
* Regarding thread safety, the members of a rule fall into the following
* categories:
};
void ofproto_rule_ref(struct rule *);
+bool ofproto_rule_try_ref(struct rule *);
void ofproto_rule_unref(struct rule *);
static inline const struct rule_actions * rule_get_actions(const struct rule *);
* Thread-safety
* =============
*
- * A struct rule_actions may be accessed without a risk of being
- * freed by code that holds a read-lock or write-lock on 'rule->mutex' (where
- * 'rule' is the rule for which 'rule->actions == actions') or during the RCU
- * active period.
+ * A struct rule_actions may be accessed without a risk of being freed by
+ * code that holds 'rule->mutex' (where 'rule' is the rule for which
+ * 'rule->actions == actions') or during the RCU active period.
*
* All members are immutable: they do not change during the struct's
* lifetime. */
* than to do it one by one. */
void (*flush)(struct ofproto *ofproto);
- /* Helper for the OpenFlow OFPT_FEATURES_REQUEST request.
- *
- * The implementation should store true in '*arp_match_ip' if the switch
- * supports matching IP addresses inside ARP requests and replies, false
- * otherwise.
+ /* Helper for the OpenFlow OFPT_TABLE_FEATURES request.
*
- * The implementation should store in '*actions' a bitmap of the supported
- * OpenFlow actions. Vendor actions are not included in '*actions'. */
- void (*get_features)(struct ofproto *ofproto,
- bool *arp_match_ip,
- enum ofputil_action_bitmap *actions);
-
- /* Helper for the OpenFlow OFPST_TABLE statistics request.
- *
- * The 'ots' array contains 'ofproto->n_tables' elements. Each element is
- * initialized as:
+ * The 'features' array contains 'ofproto->n_tables' elements. Each
+ * element is initialized as:
*
* - 'table_id' to the array index.
*
* - 'name' to "table#" where # is the table ID.
*
- * - 'match' and 'wildcards' to OFPXMT12_MASK.
- *
- * - 'write_actions' and 'apply_actions' to OFPAT12_OUTPUT.
- *
- * - 'write_setfields' and 'apply_setfields' to OFPXMT12_MASK.
- *
* - 'metadata_match' and 'metadata_write' to OVS_BE64_MAX.
*
- * - 'instructions' to OFPIT11_ALL.
- *
- * - 'config' to OFPTC11_TABLE_MISS_MASK.
+ * - 'config' to the table miss configuration.
*
* - 'max_entries' to 1,000,000.
*
- * - 'active_count' to the classifier_count() for the table.
+ * - Both 'nonmiss' and 'miss' to:
*
- * - 'lookup_count' and 'matched_count' to 0.
+ * * 'next' to all 1-bits for all later tables.
*
- * The implementation should update any members in each element for which
- * it has better values:
+ * * 'instructions' to all instructions.
+ *
+ * * 'write' and 'apply' both to:
*
- * - 'name' to a more meaningful name.
+ * - 'ofpacts': All actions.
*
- * - 'wildcards' to the set of wildcards actually supported by the table
- * (if it doesn't support all OpenFlow wildcards).
+ * - 'set_fields': All fields.
*
- * - 'instructions' to set the instructions actually supported by
- * the table.
+ * - 'match', 'mask', and 'wildcard' to all fields.
*
- * - 'write_actions' to set the write actions actually supported by
- * the table (if it doesn't support all OpenFlow actions).
+ * If 'stats' is nonnull, it also contains 'ofproto->n_tables' elements.
+ * Each element is initialized as:
+ *
+ * - 'table_id' to the array index.
*
- * - 'apply_actions' to set the apply actions actually supported by
- * the table (if it doesn't support all OpenFlow actions).
+ * - 'active_count' to the classifier_count() for the table.
*
- * - 'write_setfields' to set the write setfields actually supported by
- * the table.
+ * - 'lookup_count' and 'matched_count' to 0.
*
- * - 'apply_setfields' to set the apply setfields actually supported by
- * the table.
+ * The implementation should update any members in each element for which
+ * it has better values:
*
- * - 'max_entries' to the maximum number of flows actually supported by
- * the hardware.
+ * - Any member of 'features' to better describe the implementation's
+ * capabilities.
*
* - 'lookup_count' to the number of packets looked up in this flow table
* so far.
*
* - 'matched_count' to the number of packets looked up in this flow
* table so far that matched one of the flow entries.
- *
- * All of the members of struct ofp12_table_stats are in network byte
- * order.
*/
- void (*get_tables)(struct ofproto *ofproto, struct ofp12_table_stats *ots);
+ void (*query_tables)(struct ofproto *ofproto,
+ struct ofputil_table_features *features,
+ struct ofputil_table_stats *stats);
/* ## ---------------- ## */
/* ## ofport Functions ## */