ofproto: Properly initialize table_id when creating rules.
[openvswitch] / ofproto / private.h
index e74d4ad57226e9c32ca9a787a94462d2d295cee3..7a41a10a315f71cac6f537c519b4c4067edb7bac 100644 (file)
@@ -49,8 +49,9 @@ struct ofproto {
     struct hmap ports;          /* Contains "struct ofport"s. */
     struct shash port_by_name;
 
-    /* Flow table. */
-    struct classifier cls;      /* Contains "struct rule"s. */
+    /* Flow tables. */
+    struct classifier *tables;  /* Each classifier contains "struct rule"s. */
+    int n_tables;
 
     /* OpenFlow connections. */
     struct connmgr *connmgr;
@@ -84,6 +85,7 @@ struct rule {
     long long int created;       /* Creation time. */
     uint16_t idle_timeout;       /* In seconds from time of last use. */
     uint16_t hard_timeout;       /* In seconds from time of creation. */
+    uint8_t table_id;            /* Index in ofproto's 'tables' array. */
     bool send_flow_removed;      /* Send a flow removed message? */
 
     union ofp_action *actions;   /* OpenFlow actions. */
@@ -96,7 +98,6 @@ rule_from_cls_rule(const struct cls_rule *cls_rule)
     return cls_rule ? CONTAINER_OF(cls_rule, struct rule, cr) : NULL;
 }
 
-struct rule *ofproto_rule_lookup(struct ofproto *, const struct flow *);
 void ofproto_rule_expire(struct rule *, uint8_t reason);
 void ofproto_rule_destroy(struct rule *);
 
@@ -236,12 +237,17 @@ struct ofproto_class {
 
     /* Life-cycle functions for an "ofproto" (see "Life Cycle" above).
      *
-     * ->construct() should not modify any base members of the ofproto, even
-     * though it may be tempting in a few cases.  In particular, the client
-     * will initialize the ofproto's 'ports' member after construction is
-     * complete.  An ofproto's flow table should be initially empty, so
-     * ->construct() should delete flows from the underlying datapath, if
-     * necessary, rather than populating the ofproto's 'cls'.
+     * ->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.
      *
      * 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
@@ -285,6 +291,61 @@ 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: the bit with value (1 << n) should be set to 1 if the
+     * implementation supports the action with value 'n', and to 0 otherwise.
+     * For example, if the implementation supports the OFPAT_OUTPUT and
+     * OFPAT_ENQUEUE actions, but no others, it would set '*actions' to (1 <<
+     * OFPAT_OUTPUT) | (1 << OFPAT_ENQUEUE).  Vendor actions are not included
+     * in '*actions'. */
+    void (*get_features)(struct ofproto *ofproto,
+                         bool *arp_match_ip, uint32_t *actions);
+
+    /* Helper for the OpenFlow OFPST_TABLE statistics request.
+     *
+     * The 'ots' 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.
+     *
+     *   - 'wildcards' to OFPFW_ALL.
+     *
+     *   - 'max_entries' to 1,000,000.
+     *
+     *   - 'active_count' to the classifier_count() for the table.
+     *
+     *   - 'lookup_count' and 'matched_count' to 0.
+     *
+     * The implementation should update any members in each element for which
+     * it has better values:
+     *
+     *   - 'name' to a more meaningful name.
+     *
+     *   - 'wildcards' to the set of wildcards actually supported by the table
+     *     (if it doesn't support all OpenFlow wildcards).
+     *
+     *   - 'max_entries' to the maximum number of flows actually supported by
+     *     the hardware.
+     *
+     *   - '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.
+     *
+     * Keep in mind that all of the members of struct ofp_table_stats are in
+     * network byte order.
+     */
+    void (*get_tables)(struct ofproto *ofproto, struct ofp_table_stats *ots);
+
 /* ## ---------------- ## */
 /* ## ofport Functions ## */
 /* ## ---------------- ## */
@@ -445,6 +506,25 @@ struct ofproto_class {
 /* ## OpenFlow Rule Functions ## */
 /* ## ----------------------- ## */
 
+    /* Chooses an appropriate table for 'cls_rule' within 'ofproto'.  On
+     * success, stores the table ID into '*table_idp' and returns 0.  On
+     * failure, returns an OpenFlow error code (as returned by ofp_mkerr()).
+     *
+     * The choice of table should be a function of 'cls_rule' and 'ofproto''s
+     * datapath capabilities.  It should not depend on the flows already in
+     * 'ofproto''s flow tables.  Failure implies that an OpenFlow rule with
+     * 'cls_rule' as its matching condition can never be inserted into
+     * 'ofproto', even starting from an empty flow table.
+     *
+     * 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. */
+    int (*rule_choose_table)(const struct ofproto *ofproto,
+                             const struct cls_rule *cls_rule,
+                             uint8_t *table_idp);
+
     /* Life-cycle functions for a "struct rule" (see "Life Cycle" above).
      *
      * ->rule_construct() should first check whether the rule is acceptable:
@@ -592,25 +672,22 @@ struct ofproto_class {
 
     /* Configures connectivity fault management on 'ofport'.
      *
-     * If 'cfm' is nonnull, takes basic configuration from the configuration
-     * members in 'cfm', and the set of remote maintenance points from the
-     * 'n_remote_mps' elements in 'remote_mps'.  Ignores the statistics members
-     * of 'cfm'.
+     * If 'cfm_settings' is nonnull, configures CFM according to its members.
      *
-     * If 'cfm' is null, removes any connectivity fault management
+     * If 'cfm_settings' is null, removes any connectivity fault management
      * configuration from 'ofport'.
      *
      * EOPNOTSUPP as a return value indicates that this ofproto_class does not
      * support CFM, as does a null pointer. */
-    int (*set_cfm)(struct ofport *ofport, const struct cfm *cfm,
-                   const uint16_t *remote_mps, size_t n_remote_mps);
+    int (*set_cfm)(struct ofport *ofport, const struct cfm_settings *s);
 
-    /* Stores the connectivity fault management object associated with 'ofport'
-     * in '*cfmp'.  Stores a null pointer in '*cfmp' if CFM is not configured
-     * on 'ofport'.  The caller must not modify or destroy the returned object.
+    /* Checks the fault status of CFM configured on 'ofport'.  Returns 1 if CFM
+     * is faulted (generally indicating a connectivity problem), 0 if CFM is
+     * not faulted, or -1 if CFM is not enabled on 'port'
      *
-     * This function may be NULL if this ofproto_class does not support CFM. */
-    int (*get_cfm)(struct ofport *ofport, const struct cfm **cfmp);
+     * This function may be a null pointer if the ofproto implementation does
+     * not support CFM. */
+    int (*get_cfm_fault)(const struct ofport *ofport);
 
     /* If 's' is nonnull, this function registers a "bundle" associated with
      * client data pointer 'aux' in 'ofproto'.  A bundle is the same concept as