ovs-appctl: Print command arguments for "help".
[openvswitch] / ofproto / ofproto-provider.h
index be1e4de6cbc12f66d2415055756d641338a38eb3..f596abcba1643d539009c15bcca85c1b59cbabb3 100644 (file)
 /* Definitions for use within ofproto. */
 
 #include "ofproto/ofproto.h"
+#include "cfm.h"
 #include "classifier.h"
 #include "list.h"
 #include "shash.h"
 #include "timeval.h"
 
+struct ofputil_flow_mod;
+
 /* An OpenFlow switch.
  *
  * With few exceptions, ofproto implementations may look at these fields but
@@ -41,6 +44,8 @@ struct ofproto {
     unsigned flow_eviction_threshold; /* Threshold at which to begin flow
                                        * table eviction. Only affects the
                                        * ofproto-dpif implementation */
+    bool forward_bpdu;          /* Option to allow forwarding of BPDU frames
+                                 * when NORMAL action is invoked. */
     char *mfr_desc;             /* Manufacturer. */
     char *hw_desc;              /* Hardware. */
     char *sw_desc;              /* Software version. */
@@ -61,12 +66,22 @@ struct ofproto {
     /* Flow table operation tracking. */
     int state;                  /* Internal state. */
     struct list pending;        /* List of "struct ofopgroup"s. */
+    unsigned int n_pending;     /* list_size(&pending). */
     struct hmap deletions;      /* All OFOPERATION_DELETE "ofoperation"s. */
 };
 
 struct ofproto *ofproto_lookup(const char *name);
 struct ofport *ofproto_get_port(const struct ofproto *, uint16_t ofp_port);
 
+/* Assigns CLS to each classifier table, in turn, in OFPROTO.
+ *
+ * All parameters are evaluated multiple times. */
+#define OFPROTO_FOR_EACH_TABLE(CLS, OFPROTO)                \
+    for ((CLS) = (OFPROTO)->tables;                         \
+         (CLS) < &(OFPROTO)->tables[(OFPROTO)->n_tables];   \
+         (CLS)++)
+
+
 /* An OpenFlow port within a "struct ofproto".
  *
  * With few exceptions, ofproto implementations may look at these fields but
@@ -78,6 +93,7 @@ struct ofport {
     struct ofp_phy_port opp;
     uint16_t ofp_port;          /* OpenFlow port number. */
     unsigned int change_seq;
+    int mtu;
 };
 
 /* An OpenFlow flow within a "struct ofproto".
@@ -94,8 +110,9 @@ struct rule {
     ovs_be64 flow_cookie;        /* Controller-issued identifier. */
 
     long long int created;       /* Creation time. */
+    long long int modified;      /* Time of last modification. */
     uint16_t idle_timeout;       /* In seconds from time of last use. */
-    uint16_t hard_timeout;       /* In seconds from time of creation. */
+    uint16_t hard_timeout;       /* In seconds from last modification. */
     uint8_t table_id;            /* Index in ofproto's 'tables' array. */
     bool send_flow_removed;      /* Send a flow removed message? */
 
@@ -255,17 +272,20 @@ struct ofproto_class {
      * Construction
      * ============
      *
-     * ->construct() should not modify most base members of the ofproto.  In
-     * particular, the client will initialize the ofproto's 'ports' member
-     * after construction is complete.
-     *
-     * ->construct() should initialize the base 'n_tables' member to the number
-     * of flow tables supported by the datapath (between 1 and 255, inclusive),
-     * initialize the base 'tables' member with space for one classifier per
-     * table, and initialize each classifier with classifier_init.  Each flow
-     * table should be initially empty, so ->construct() should delete flows
-     * from the underlying datapath, if necessary, rather than populating the
-     * tables.
+     * ->construct() should not modify any base members of the ofproto.  The
+     * client will initialize the ofproto's 'ports' and 'tables' members after
+     * construction is complete.
+     *
+     * When ->construct() is called, the client does not yet know how many flow
+     * tables the datapath supports, so ofproto->n_tables will be 0 and
+     * ofproto->tables will be NULL.  ->construct() should store the number of
+     * flow tables supported by the datapath (between 1 and 255, inclusive)
+     * into '*n_tables'.  After a successful return, the client will initialize
+     * the base 'n_tables' member to '*n_tables' and allocate and initialize
+     * the base 'tables' member as the specified number of empty flow tables.
+     * Each flow table will be initially empty, so ->construct() should delete
+     * flows from the underlying datapath, if necessary, rather than populating
+     * the tables.
      *
      * Only one ofproto instance needs to be supported for any given datapath.
      * If a datapath is already open as part of one "ofproto", then another
@@ -279,15 +299,16 @@ struct ofproto_class {
      * Destruction
      * ===========
      *
-     * ->destruct() must do at least the following:
-     *
-     *   - If 'ofproto' has any pending asynchronous operations, ->destruct()
-     *     must complete all of them by calling ofoperation_complete().
+     * If 'ofproto' has any pending asynchronous operations, ->destruct()
+     * must complete all of them by calling ofoperation_complete().
      *
-     *   - If 'ofproto' has any rules left in any of its flow tables, ->
+     * ->destruct() must also destroy all remaining rules in the ofproto's
+     * tables, by passing each remaining rule to ofproto_rule_destroy().  The
+     * client will destroy the flow tables themselves after ->destruct()
+     * returns.
      */
     struct ofproto *(*alloc)(void);
-    int (*construct)(struct ofproto *ofproto);
+    int (*construct)(struct ofproto *ofproto, int *n_tables);
     void (*destruct)(struct ofproto *ofproto);
     void (*dealloc)(struct ofproto *ofproto);
 
@@ -594,8 +615,7 @@ struct ofproto_class {
      * If multiple tables are candidates for inserting the flow, the function
      * should choose one arbitrarily (but deterministically).
      *
-     * This function will never be called for an ofproto that has only one
-     * table, so it may be NULL in that case. */
+     * If this function is NULL then table 0 is always chosen. */
     int (*rule_choose_table)(const struct ofproto *ofproto,
                              const struct cls_rule *cls_rule,
                              uint8_t *table_idp);
@@ -672,7 +692,8 @@ struct ofproto_class {
      *
      *   - 'rule' is replacing an existing rule in its flow table that had the
      *     same matching criteria and priority.  In this case,
-     *     ofoperation_get_victim(rule) returns the rule being replaced.
+     *     ofoperation_get_victim(rule) returns the rule being replaced (the
+     *     "victim" rule).
      *
      * ->rule_construct() should set the following in motion:
      *
@@ -692,9 +713,13 @@ struct ofproto_class {
      *   - If the rule is valid, update the datapath flow table, adding the new
      *     rule or replacing the existing one.
      *
+     *   - If 'rule' is replacing an existing rule, uninitialize any derived
+     *     state for the victim rule, as in step 5 in the "Life Cycle"
+     *     described above.
+     *
      * (On failure, the ofproto code will roll back the insertion from the flow
-     * table, either removing 'rule' or replacing it by the flow that was
-     * originally in its place.)
+     * table, either removing 'rule' or replacing it by the victim rule if
+     * there is one.)
      *
      * ->rule_construct() must act in one of the following ways:
      *
@@ -707,8 +732,8 @@ struct ofproto_class {
      *       * Return an OpenFlow error code (as returned by ofp_mkerr()).  (Do
      *         not call ofoperation_complete() in this case.)
      *
-     *     In the former case, ->rule_destruct() will be called; in the latter
-     *     case, it will not.  ->rule_dealloc() will be called in either case.
+     *     Either way, ->rule_destruct() will not be called for 'rule', but
+     *     ->rule_dealloc() will be.
      *
      *   - If the operation is only partially complete, then it must return 0.
      *     Later, when the operation is complete, the ->run() or ->destruct()
@@ -859,6 +884,16 @@ struct ofproto_class {
      * not support CFM. */
     int (*get_cfm_fault)(const struct ofport *ofport);
 
+    /* Gets the MPIDs of the remote maintenance points broadcasting to
+     * 'ofport'.  Populates 'rmps' with a provider owned array of MPIDs, and
+     * 'n_rmps' with the number of MPIDs in 'rmps'. Returns a number less than
+     * 0 if CFM is not enabled of 'ofport'.
+     *
+     * This function may be a null pointer if the ofproto implementation does
+     * not support CFM. */
+    int (*get_cfm_remote_mpids)(const struct ofport *ofport,
+                                const uint64_t **rmps, size_t *n_rmps);
+
     /* If 's' is nonnull, this function registers a "bundle" associated with
      * client data pointer 'aux' in 'ofproto'.  A bundle is the same concept as
      * a Port in OVSDB, that is, it consists of one or more "slave" devices
@@ -914,6 +949,10 @@ struct ofproto_class {
     /* Returns true if 'aux' is a registered bundle that is currently in use as
      * the output for a mirror. */
     bool (*is_mirror_output_bundle)(struct ofproto *ofproto, void *aux);
+
+    /* When the configuration option of forward_bpdu changes, this function
+     * will be invoked. */
+    void (*forward_bpdu_changed)(struct ofproto *ofproto);
 };
 
 extern const struct ofproto_class ofproto_dpif_class;
@@ -921,6 +960,18 @@ extern const struct ofproto_class ofproto_dpif_class;
 int ofproto_class_register(const struct ofproto_class *);
 int ofproto_class_unregister(const struct ofproto_class *);
 
+/* ofproto_flow_mod() returns this value if the flow_mod could not be processed
+ * because it overlaps with an ongoing flow table operation that has not yet
+ * completed.  The caller should retry the operation later.
+ *
+ * ofproto.c also uses this value internally for additional (similar) purposes.
+ *
+ * This particular value is a good choice because it is negative (so it won't
+ * collide with any errno value or any value returned by ofp_mkerr()) and large
+ * (so it won't accidentally collide with EOF or a negative errno value). */
+enum { OFPROTO_POSTPONE = -100000 };
+
+int ofproto_flow_mod(struct ofproto *, const struct ofputil_flow_mod *);
 void ofproto_add_flow(struct ofproto *, const struct cls_rule *,
                       const union ofp_action *, size_t n_actions);
 bool ofproto_delete_flow(struct ofproto *, const struct cls_rule *);