X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-provider.h;h=43273ec96fbe339460b42e0f0c2ca7d9d156b2e6;hb=b277c7cc6984ef0aa233d5fed48db8a4d6af2210;hp=565cb01c12e5e27b393032e362ef7bae9199badb;hpb=4e022ec09e14ac89add74c1b4b8e3ff3873edbf0;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 565cb01c1..43273ec96 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -19,7 +19,6 @@ /* Definitions for use within ofproto. */ -#include "ofproto/ofproto.h" #include "cfm.h" #include "classifier.h" #include "heap.h" @@ -27,6 +26,8 @@ #include "list.h" #include "ofp-errors.h" #include "ofp-util.h" +#include "ofproto/ofproto.h" +#include "ovs-thread.h" #include "shash.h" #include "simap.h" #include "timeval.h" @@ -35,6 +36,7 @@ struct match; struct ofpact; struct ofputil_flow_mod; struct bfd_cfg; +struct meter; /* An OpenFlow switch. * @@ -63,8 +65,8 @@ struct ofproto { struct shash port_by_name; unsigned long *ofp_port_ids;/* Bitmap of used OpenFlow port numbers. */ struct simap ofp_requests; /* OpenFlow port number requests. */ - ofp_port_t alloc_port_no; /* Last allocated OpenFlow port number. */ - ofp_port_t max_ports; /* Max possible OpenFlow port num, plus one. */ + uint16_t alloc_port_no; /* Last allocated OpenFlow port number. */ + uint16_t max_ports; /* Max possible OpenFlow port num, plus one. */ /* Flow tables. */ struct oftable *tables; @@ -74,7 +76,16 @@ struct ofproto { /* Optimisation for flow expiry. * These flows should all be present in tables. */ - struct list expirable; /* Expirable 'struct rule"s in all tables. */ + struct ovs_mutex expirable_mutex; + struct list expirable OVS_GUARDED; /* Expirable 'struct rule"s in all + tables. */ + + /* Meter table. + * OpenFlow meters start at 1. To avoid confusion we leave the first + * pointer in the array un-used, and index directly with the OpenFlow + * meter_id. */ + struct ofputil_meter_features meter_features; + struct meter **meters; /* 'meter_features.max_meter' + 1 pointers. */ /* OpenFlow connections. */ struct connmgr *connmgr; @@ -103,7 +114,7 @@ struct ofproto { }; void ofproto_init_tables(struct ofproto *, int n_tables); -void ofproto_init_max_ports(struct ofproto *, ofp_port_t max_ports); +void ofproto_init_max_ports(struct ofproto *, uint16_t max_ports); struct ofproto *ofproto_lookup(const char *name); struct ofport *ofproto_get_port(const struct ofproto *, ofp_port_t ofp_port); @@ -211,19 +222,32 @@ struct rule { long long int created; /* Creation time. */ long long int modified; /* Time of last modification. */ long long int used; /* Last use; time created if never used. */ - uint16_t hard_timeout; /* In seconds from ->modified. */ - uint16_t idle_timeout; /* In seconds from ->used. */ uint8_t table_id; /* Index in ofproto's 'tables' array. */ bool send_flow_removed; /* Send a flow removed message? */ + struct ovs_mutex timeout_mutex; + uint16_t hard_timeout OVS_GUARDED; /* In seconds from ->modified. */ + uint16_t idle_timeout OVS_GUARDED; /* In seconds from ->used. */ + /* Eviction groups. */ - bool evictable; /* If false, prevents eviction. */ struct heap_node evg_node; /* In eviction_group's "rules" heap. */ struct eviction_group *eviction_group; /* NULL if not in any group. */ + /* The evict lock is used to prevent rules from being evicted while child + * threads are using them to xlate flows. A read lock means the rule is + * currently being used. A write lock means the rule is in the process of + * being evicted and should be considered gone. A rule will not be evicted + * unless both its own and its classifiers write locks are held. + * Therefore, while holding a classifier readlock, one can be assured that + * even write locked rules are safe. */ + struct ovs_rwlock evict; + struct ofpact *ofpacts; /* Sequence of "struct ofpacts". */ unsigned int ofpacts_len; /* Size of 'ofpacts', in bytes. */ + uint32_t meter_id; /* Non-zero OF meter_id, or zero. */ + struct list meter_list_node; /* In owning meter's 'rules' list. */ + /* Flow monitors. */ enum nx_flow_monitor_flags monitor_flags; uint64_t add_seqno; /* Sequence number when added. */ @@ -238,6 +262,14 @@ struct rule { * ofproto-dpif implementation */ extern unsigned flow_eviction_threshold; +/* Number of upcall handler threads. Only affects the ofproto-dpif + * implementation. */ +extern unsigned n_handler_threads; + +/* Determines which model to use for handling misses in the ofproto-dpif + * implementation */ +extern enum ofproto_flow_miss_model flow_miss_model; + static inline struct rule * rule_from_cls_rule(const struct cls_rule *cls_rule) { @@ -245,13 +277,17 @@ rule_from_cls_rule(const struct cls_rule *cls_rule) } void ofproto_rule_update_used(struct rule *, long long int used); -void ofproto_rule_expire(struct rule *, uint8_t reason); -void ofproto_rule_destroy(struct rule *); +void ofproto_rule_expire(struct rule *rule, uint8_t reason) + OVS_RELEASES(rule->evict); +void ofproto_rule_destroy(struct ofproto *, struct classifier *cls, + struct rule *) OVS_REQ_WRLOCK(cls->rwlock); +void ofproto_rule_reduce_timeouts(struct rule *rule, uint16_t idle_timeout, + uint16_t hard_timeout) + OVS_EXCLUDED(rule->ofproto->expirable_mutex, rule->timeout_mutex); bool ofproto_rule_has_out_port(const struct rule *, ofp_port_t out_port); void ofoperation_complete(struct ofoperation *, enum ofperr); -struct rule *ofoperation_get_victim(struct ofoperation *); bool ofoperation_has_out_port(const struct ofoperation *, ofp_port_t out_port); @@ -853,7 +889,7 @@ struct ofproto_class { * 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 opreation. When the operation completes, the ofproto + * ongoing operation. When the operation completes, the ofproto * implementation calls ofoperation_complete(), passing the ofoperation and * an error indication. * @@ -870,22 +906,22 @@ struct ofproto_class { * The ofproto base code updates the flow table optimistically, assuming * that the operation will probably succeed: * - * - ofproto adds or replaces the rule in the flow table before calling + * - ofproto adds the rule in the flow table before calling * ->rule_construct(). * - * - ofproto updates the rule's actions before calling - * ->rule_modify_actions(). + * - ofproto updates the rule's actions and other properties before + * calling ->rule_modify_actions(). * * - ofproto removes the rule before calling ->rule_destruct(). * * With one exception, when an asynchronous operation completes with an * error, ofoperation_complete() backs out the already applied changes: * - * - If adding or replacing a rule in the flow table fails, ofproto - * removes the new rule or restores the original rule. + * - If adding a rule in the flow table fails, ofproto removes the new + * rule. * - * - If modifying a rule's actions fails, ofproto restores the original - * actions. + * - If modifying a rule fails, ofproto restores the original actions + * (and other properties). * * - Removing a rule is not allowed to fail. It must always succeed. * @@ -901,17 +937,9 @@ struct ofproto_class { * Construction * ============ * - * When ->rule_construct() is called, the caller has already inserted - * 'rule' into 'rule->ofproto''s flow table numbered 'rule->table_id'. - * There are two cases: - * - * - 'rule' is a new rule in its flow table. In this case, - * ofoperation_get_victim(rule) returns NULL. - * - * - '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 (the - * "victim" rule). + * When ->rule_construct() is called, 'rule' is a new rule in its flow + * table. The caller has already inserted 'rule' into 'rule->ofproto''s + * flow table numbered 'rule->table_id'. * * ->rule_construct() should set the following in motion: * @@ -922,16 +950,10 @@ struct ofproto_class { * * - Validate that the datapath can correctly implement 'rule->ofpacts'. * - * - 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. + * - If the rule is valid, add the new rule to the datapath flow table. * * (On failure, the ofproto code will roll back the insertion from the flow - * table, either removing 'rule' or replacing it by the victim rule if - * there is one.) + * table by removing 'rule'.) * * ->rule_construct() must act in one of the following ways: * @@ -1007,6 +1029,10 @@ struct ofproto_class { * * - Update the datapath flow table with the new actions. * + * - Only if 'reset_counters' is true, reset any packet or byte counters + * 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 @@ -1017,7 +1043,7 @@ struct ofproto_class { * * ->rule_modify_actions() should not modify any base members of struct * rule. */ - void (*rule_modify_actions)(struct rule *rule); + void (*rule_modify_actions)(struct rule *rule, bool reset_counters); /* Changes the OpenFlow IP fragment handling policy to 'frag_handling', * which takes one of the following values, with the corresponding @@ -1317,10 +1343,52 @@ struct ofproto_class { * If 'realdev_ofp_port' is zero, then this function deconfigures 'ofport' * as a VLAN splinter port. * - * This function should be NULL if a an implementation does not support - * it. */ + * This function should be NULL if an implementation does not support it. + */ int (*set_realdev)(struct ofport *ofport, ofp_port_t realdev_ofp_port, int vid); + +/* ## ------------------------ ## */ +/* ## OpenFlow meter functions ## */ +/* ## ------------------------ ## */ + + /* These functions should be NULL if an implementation does not support + * them. They must be all null or all non-null.. */ + + /* Initializes 'features' to describe the metering features supported by + * 'ofproto'. */ + void (*meter_get_features)(const struct ofproto *ofproto, + struct ofputil_meter_features *features); + + /* If '*id' is UINT32_MAX, adds a new meter with the given 'config'. On + * success the function must store a provider meter ID other than + * UINT32_MAX in '*id'. All further references to the meter will be made + * with the returned provider meter id rather than the OpenFlow meter id. + * The caller does not try to interpret the provider meter id, giving the + * implementation the freedom to either use the OpenFlow meter_id value + * provided in the meter configuration, or any other value suitable for the + * implementation. + * + * If '*id' is a value other than UINT32_MAX, modifies the existing meter + * with that meter provider ID to have configuration 'config'. On failure, + * the existing meter configuration is left intact. Regardless of success, + * any change to '*id' updates the provider meter id used for this + * meter. */ + enum ofperr (*meter_set)(struct ofproto *ofproto, ofproto_meter_id *id, + const struct ofputil_meter_config *config); + + /* Gets the meter and meter band packet and byte counts for maximum of + * 'stats->n_bands' bands for the meter with provider ID 'id' within + * 'ofproto'. The caller fills in the other stats values. The band stats + * are copied to memory at 'stats->bands' provided by the caller. The + * number of returned band stats is returned in 'stats->n_bands'. */ + enum ofperr (*meter_get)(const struct ofproto *ofproto, + ofproto_meter_id id, + struct ofputil_meter_stats *stats); + + /* Deletes a meter, making the 'ofproto_meter_id' invalid for any + * further calls. */ + void (*meter_del)(struct ofproto *, ofproto_meter_id); }; extern const struct ofproto_class ofproto_dpif_class; @@ -1340,7 +1408,7 @@ int ofproto_class_unregister(const struct ofproto_class *); enum { OFPROTO_POSTPONE = 1 << 16 }; BUILD_ASSERT_DECL(OFPROTO_POSTPONE < OFPERR_OFS); -int ofproto_flow_mod(struct ofproto *, const struct ofputil_flow_mod *); +int ofproto_flow_mod(struct ofproto *, struct ofputil_flow_mod *); void ofproto_add_flow(struct ofproto *, const struct match *, unsigned int priority, const struct ofpact *ofpacts, size_t ofpacts_len);