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. */
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
* 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
* 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);
* 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);
/* 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;