Add build of ovsext.sln using MSBuild
[cascardo/ovs.git] / ofproto / ofproto-provider.h
index d61fc7c..d490679 100644 (file)
@@ -96,6 +96,7 @@ struct ofproto {
 
     /* Rules indexed on their cookie values, in all flow tables. */
     struct hindex cookies OVS_GUARDED_BY(ofproto_mutex);
+    struct hmap learned_cookies OVS_GUARDED_BY(ofproto_mutex);
 
     /* List of expirable flows, in all flow tables. */
     struct list expirable OVS_GUARDED_BY(ofproto_mutex);
@@ -110,10 +111,6 @@ struct ofproto {
     /* OpenFlow connections. */
     struct connmgr *connmgr;
 
-    /* 'meaningful only within ofproto.c, one of the enum ofproto_state
-     * constants defined there. */
-    int state;
-
     /* Delayed rule executions.
      *
      * We delay calls to ->ofproto_class->rule_execute() past releasing
@@ -199,21 +196,18 @@ enum oftable_flags {
  * Thread-safety
  * =============
  *
- * A cls->rwlock read-lock holder prevents rules from being added or deleted.
- *
- * Adding or removing rules requires holding ofproto_mutex AND the cls->rwlock
- * write-lock.
+ * Adding or removing rules requires holding ofproto_mutex.
  *
- * 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.
+ * 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.
  *
- * 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.
+ * Modifying a rule requires the rule's own mutex.
  *
- * 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 {
@@ -247,8 +241,8 @@ 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;
@@ -292,19 +286,21 @@ struct oftable {
  * 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:
@@ -387,6 +383,7 @@ struct rule {
 };
 
 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 *);
@@ -399,22 +396,32 @@ static inline bool rule_is_hidden(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. */
 struct rule_actions {
-    /* These members are immutable: they do not change during the struct's
-     * lifetime.  */
+    /* Flags.
+     *
+     * 'has_meter' is true if 'ofpacts' contains an OFPACT_METER action.
+     *
+     * 'has_learn_with_delete' is true if 'ofpacts' contains an OFPACT_LEARN
+     * action whose flags include NX_LEARN_F_DELETE_LEARNED. */
+    bool has_meter;
+    bool has_learn_with_delete;
+
+    /* Actions. */
     uint32_t ofpacts_len;         /* Size of 'ofpacts', in bytes. */
-    uint32_t provider_meter_id;   /* Datapath meter_id, or UINT32_MAX. */
     struct ofpact ofpacts[];      /* Sequence of "struct ofpacts". */
 };
 BUILD_ASSERT_DECL(offsetof(struct rule_actions, ofpacts) % OFPACT_ALIGNTO == 0);
 
-const struct rule_actions *rule_actions_create(const struct ofproto *,
-                                               const struct ofpact *, size_t);
+const struct rule_actions *rule_actions_create(const struct ofpact *, size_t);
 void rule_actions_destroy(const struct rule_actions *);
+bool ofproto_rule_has_out_port(const struct rule *, ofp_port_t port)
+    OVS_REQUIRES(ofproto_mutex);
 
 /* A set of rules to which an OpenFlow operation applies. */
 struct rule_collection {
@@ -454,8 +461,6 @@ void ofproto_rule_reduce_timeouts(struct rule *rule, uint16_t idle_timeout,
                                   uint16_t hard_timeout)
     OVS_EXCLUDED(ofproto_mutex);
 
-void ofoperation_complete(struct ofoperation *, enum ofperr);
-
 /* A group within a "struct ofproto".
  *
  * With few exceptions, ofproto implementations may look at these fields but
@@ -712,18 +717,8 @@ struct ofproto_class {
      * Destruction
      * ===========
      *
-     * If 'ofproto' has any pending asynchronous operations, ->destruct()
-     * must complete all of them by calling ofoperation_complete().
-     *
      * ->destruct() must also destroy all remaining rules in the ofproto's
-     * tables, by passing each remaining rule to ofproto_rule_delete(), and
-     * then complete each of those deletions in turn by calling
-     * ofoperation_complete().
-     *
-     * (Thus, there is a multi-step process for any rule currently being
-     * inserted or modified at the beginning of destruction: first
-     * ofoperation_complete() that operation, then ofproto_rule_delete() the
-     * rule, then ofoperation_complete() the deletion operation.)
+     * tables, by passing each remaining rule to ofproto_rule_delete().
      *
      * The client will destroy the flow tables themselves after ->destruct()
      * returns.
@@ -742,9 +737,6 @@ struct ofproto_class {
      *   - 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);
 
@@ -776,81 +768,59 @@ struct ofproto_class {
      * 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.
-     *
-     * 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.
+    /* Helper for the OpenFlow OFPT_TABLE_FEATURES 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.
      *
-     *   - 'name' to a more meaningful name.
+     *     * 'write' and 'apply' both to:
      *
-     *   - 'wildcards' to the set of wildcards actually supported by the table
-     *     (if it doesn't support all OpenFlow wildcards).
+     *       - 'ofpacts': All actions.
      *
-     *   - 'instructions' to set the instructions actually supported by
-     *     the table.
+     *       - 'set_fields': All fields.
      *
-     *   - 'write_actions' to set the write actions actually supported by
-     *     the table (if it doesn't support all OpenFlow actions).
+     *   - 'match', 'mask', and 'wildcard' to all fields.
      *
-     *   - 'apply_actions' to set the apply 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:
      *
-     *   - 'write_setfields' to set the write setfields actually supported by
-     *     the table.
+     *   - 'table_id' to the array index.
      *
-     *   - 'apply_setfields' to set the apply setfields actually supported by
-     *     the table.
+     *   - 'active_count' to the classifier_count() for the table.
      *
-     *   - 'max_entries' to the maximum number of flows actually supported by
-     *     the hardware.
+     *   - 'lookup_count' and 'matched_count' to 0.
+     *
+     * The implementation should update any members in each element for which
+     * it has better values:
+     *
+     *   - 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 ## */
@@ -1089,8 +1059,8 @@ struct ofproto_class {
      * cycle described above under "Life Cycle".
      *
      * After a rule is successfully constructed, it is then inserted.  If
-     * insertion completes successfully, then before it is later destructed, it
-     * is deleted.
+     * insertion is successful, then before it is later destructed, it is
+     * deleted.
      *
      * You can think of a rule as having the following extra steps inserted
      * between "Life Cycle" steps 4 and 5:
@@ -1098,9 +1068,10 @@ struct ofproto_class {
      *   4.1. The client inserts the rule into the flow table, making it
      *        visible in flow table lookups.
      *
-     *   4.2. The client calls "rule_insert".  Immediately or eventually, the
-     *        implementation calls ofoperation_complete() to indicate that the
-     *        insertion completed.  If the operation failed, skip to step 5.
+     *   4.2. The client calls "rule_insert" to insert the flow.  The
+     *        implementation attempts to install the flow in the underlying
+     *        hardware and returns an error code indicate success or failure.
+     *        On failure, go to step 5.
      *
      *   4.3. The rule is now installed in the flow table.  Eventually it will
      *        be deleted.
@@ -1108,60 +1079,9 @@ struct ofproto_class {
      *   4.4. The client removes the rule from the flow table.  It is no longer
      *        visible in flow table lookups.
      *
-     *   4.5. The client calls "rule_delete".  Immediately or eventually, the
-     *        implementation calls ofoperation_complete() to indicate that the
-     *        deletion completed.  Deletion is not allowed to fail, so it must
-     *        be successful.
-     *
-     *
-     * Asynchronous Operation Support
-     * ==============================
-     *
-     * The "insert" and "delete" life-cycle operations on rules can operate
-     * asynchronously, meaning that ->rule_insert() and ->rule_delete() only
-     * need to initiate their respective operations and do not need to wait for
-     * them to complete before they return.  ->rule_modify_actions() also
-     * operates asynchronously.
-     *
-     * An ofproto implementation reports the success or failure of an
-     * asynchronous operation on a rule using the rule's 'pending' member,
-     * which points to a opaque "struct ofoperation" that represents the
-     * ongoing operation.  When the operation completes, the ofproto
-     * implementation calls ofoperation_complete(), passing the ofoperation and
-     * an error indication.
-     *
-     * Only the following contexts may call ofoperation_complete():
-     *
-     *   - The function called to initiate the operation, e.g. ->rule_insert()
-     *     or ->rule_delete().  This is the best choice if the operation
-     *     completes quickly.
-     *
-     *   - The implementation's ->run() function.
-     *
-     *   - The implementation's ->destruct() function.
-     *
-     * The ofproto base code updates the flow table optimistically, assuming
-     * that the operation will probably succeed:
-     *
-     *   - ofproto adds the rule in the flow table before calling
-     *     ->rule_insert().  If adding a rule in the flow table fails, ofproto
-     *     removes the new rule in the call to ofoperation_complete().
-     *
-     *   - ofproto updates the rule's actions and other properties before
-     *     calling ->rule_modify_actions().  Modifying a rule is not allowed to
-     *     fail (but ->rule_premodify_actions() can prevent the modification
-     *     attempt in advance).
-     *
-     *   - ofproto removes the rule before calling ->rule_delete().  Removing a
-     *     rule is not allowed to fail.  It must always succeed.
-     *
-     * The ofproto base code serializes operations: if any operation is in
-     * progress on a given rule, ofproto postpones initiating any new operation
-     * on that rule until the pending operation completes.  Therefore, every
-     * operation must eventually complete through a call to
-     * ofoperation_complete() to avoid delaying new operations indefinitely
-     * (including any OpenFlow request that affects the rule in question, even
-     * just to query its statistics).
+     *   4.5. The client calls "rule_delete".  The implementation uninstalls
+     *        the flow from the underlying hardware.  Deletion is not allowed
+     *        to fail.
      *
      *
      * Construction
@@ -1195,16 +1115,8 @@ struct ofproto_class {
      *
      * Following successful construction, the ofproto base case inserts 'rule'
      * into its flow table, then it calls ->rule_insert().  ->rule_insert()
-     * should set in motion adding the new rule to the datapath flow table.  It
-     * must act as follows:
-     *
-     *   - If it completes insertion, either by succeeding or failing, it must
-     *     call ofoperation_complete()
-     *
-     *   - If insertion is only partially complete, then it must return without
-     *     calling ofoperation_complete().  Later, when the insertion is
-     *     complete, the ->run() or ->destruct() function must call
-     *     ofoperation_complete() to report success or failure.
+     * must add the new rule to the datapath flow table and return only after
+     * this is complete (whether it succeeds or fails).
      *
      * If ->rule_insert() fails, the ofproto base code will remove 'rule' from
      * the flow table, destruct, uninitialize, and deallocate 'rule'.  See
@@ -1215,15 +1127,8 @@ struct ofproto_class {
      * ========
      *
      * The ofproto base code removes 'rule' from its flow table before it calls
-     * ->rule_delete().  ->rule_delete() should set in motion removing 'rule'
-     * from the datapath flow table.  It must act as follows:
-     *
-     *   - If it completes deletion, it must call ofoperation_complete().
-     *
-     *   - If deletion is only partially complete, then it must return without
-     *     calling ofoperation_complete().  Later, when the deletion is
-     *     complete, the ->run() or ->destruct() function must call
-     *     ofoperation_complete().
+     * ->rule_delete().  ->rule_delete() must remove 'rule' from the datapath
+     * flow table and return only after this has completed successfully.
      *
      * Rule deletion must not fail.
      *
@@ -1281,10 +1186,11 @@ struct ofproto_class {
         /* OVS_REQUIRES(ofproto_mutex) */;
 
     /* When ->rule_modify_actions() is called, the caller has already replaced
-     * the OpenFlow actions in 'rule' by a new set.  (The original actions are
-     * in rule->pending->actions.)
+     * the OpenFlow actions in 'rule' by a new set.  (If
+     * ->rule_premodify_actions is nonnull, then it was previously called to
+     * verify that the new set of actions is acceptable.)
      *
-     * ->rule_modify_actions() should set the following in motion:
+     * ->rule_modify_actions() must:
      *
      *   - Update the datapath flow table with the new actions.
      *
@@ -1292,11 +1198,6 @@ struct ofproto_class {
      *     associated with the rule to zero, so that rule_get_stats() will not
      *     longer count those packets or bytes.
      *
-     * If the operation synchronously completes, ->rule_modify_actions() may
-     * call ofoperation_complete() before it returns.  Otherwise, ->run()
-     * should call ofoperation_complete() later, after the operation does
-     * complete.
-     *
      * Rule modification must not fail.
      *
      * ->rule_modify_actions() should not modify any base members of struct
@@ -1426,19 +1327,19 @@ struct ofproto_class {
      * support CFM, as does a null pointer. */
     int (*set_cfm)(struct ofport *ofport, const struct cfm_settings *s);
 
-    /* Checks the status of CFM configured on 'ofport'.  Returns 0 if the
-     * port's CFM status was successfully stored into '*status'.  Returns
-     * negative number if there is no status change since last update.
-     * Returns positive errno otherwise.
-     *
-     * EOPNOTSUPP as a return value indicates that this ofproto_class does not
-     * support CFM, as does a null pointer.
+    /* Checks the status change of CFM on 'ofport'.  Returns true if
+     * there is status change since last call or if CFM is not specified. */
+    bool (*cfm_status_changed)(struct ofport *ofport);
+
+    /* Populates 'smap' with the status of CFM on 'ofport'.  Returns 0 on
+     * success, or a positive errno.  EOPNOTSUPP as a return value indicates
+     * that this ofproto_class does not support CFM, as does a null pointer.
      *
      * The caller must provide and own '*status', and it must free the array
      * returned in 'status->rmps'.  '*status' is indeterminate if the return
      * value is non-zero. */
     int (*get_cfm_status)(const struct ofport *ofport,
-                          struct ofproto_cfm_status *status);
+                          struct cfm_status *status);
 
     /* Configures BFD on 'ofport'.
      *
@@ -1450,12 +1351,13 @@ struct ofproto_class {
      * support BFD, as does a null pointer. */
     int (*set_bfd)(struct ofport *ofport, const struct smap *cfg);
 
+    /* Checks the status change of BFD on 'ofport'.  Returns true if there
+     * is status change since last call or if BFD is not specified. */
+    bool (*bfd_status_changed)(struct ofport *ofport);
+
     /* Populates 'smap' with the status of BFD on 'ofport'.  Returns 0 on
-     * success.  Returns a negative number if there is no status change since
-     * last update.  Returns a positive errno otherwise.
-     *
-     * EOPNOTSUPP as a return value indicates that this ofproto_class does not
-     * support BFD, as does a null pointer. */
+     * success, or a positive errno.  EOPNOTSUPP as a return value indicates
+     * that this ofproto_class does not support BFD, as does a null pointer. */
     int (*get_bfd_status)(struct ofport *ofport, struct smap *smap);
 
     /* Configures spanning tree protocol (STP) on 'ofproto' using the
@@ -1605,6 +1507,31 @@ struct ofproto_class {
     void (*set_mac_table_config)(struct ofproto *ofproto,
                                  unsigned int idle_time, size_t max_entries);
 
+    /* Configures multicast snooping on 'ofport' using the settings
+     * defined in 's'.
+     *
+     * If 's' is nonnull, this function updates multicast snooping
+     * configuration to 's' in 'ofproto'.
+     *
+     * If 's' is NULL, this function disables multicast snooping
+     * on 'ofproto'.
+     *
+     * An implementation that does not support multicast snooping may set
+     * it to NULL or return EOPNOTSUPP. */
+    int (*set_mcast_snooping)(struct ofproto *ofproto,
+                              const struct ofproto_mcast_snooping_settings *s);
+
+    /* Configures multicast snooping port's flood setting on 'ofproto'.
+     *
+     * All multicast traffic is sent to struct port 'aux' in 'ofproto'
+     * if 'flood' is true. Otherwise, struct port 'aux' is an ordinary
+     * switch port.
+     *
+     * An implementation that does not support multicast snooping may set
+     * it to NULL or return EOPNOTSUPP. */
+    int (*set_mcast_snooping_port)(struct ofproto *ofproto_, void *aux,
+                                   bool flood);
+
 /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
  *
  * This is deprecated.  It is only for compatibility with broken device drivers