X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto-provider.h;h=f596abcba1643d539009c15bcca85c1b59cbabb3;hb=e9141eec249f97e547c6e47205b61ee98d9b52e9;hp=62fb035346bd3ddbc85abf31576f373e8977bce8;hpb=5bee6e2638989aff14429c5a85fa7cef196f2106;p=openvswitch diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 62fb0353..f596abcb 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -20,11 +20,14 @@ /* 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 @@ -38,6 +41,11 @@ struct ofproto { /* Settings. */ uint64_t fallback_dpid; /* Datapath ID if no better choice found. */ uint64_t datapath_id; /* Datapath ID. */ + 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. */ @@ -58,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 @@ -75,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". @@ -91,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? */ @@ -252,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 @@ -276,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); @@ -591,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); @@ -669,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: * @@ -689,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: * @@ -704,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() @@ -856,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 @@ -911,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; @@ -918,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 *);