X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-provider.h;h=9431be875d13e6642d9a97aacae8c6afd6495dc2;hb=dc723c447a797e555d400594133a35b9841eb1de;hp=713af8767cf197052e851a561611c230a812fe7b;hpb=a6b7506dab305d91fc5f2ac6416a714e5fa09dd4;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 713af8767..9431be875 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,17 +39,18 @@ #include "heap.h" #include "hindex.h" #include "list.h" +#include "ofp-actions.h" #include "ofp-errors.h" #include "ofp-util.h" #include "ofproto/ofproto.h" #include "ovs-atomic.h" +#include "ovs-rcu.h" #include "ovs-thread.h" #include "shash.h" #include "simap.h" #include "timeval.h" struct match; -struct ofpact; struct ofputil_flow_mod; struct bfd_cfg; struct meter; @@ -173,6 +174,7 @@ struct ofport { struct netdev *netdev; struct ofputil_phy_port pp; ofp_port_t ofp_port; /* OpenFlow port number. */ + uint64_t change_seq; long long int created; /* Time created, in msec. */ int mtu; }; @@ -204,7 +206,8 @@ void ofproto_port_set_state(struct ofport *, enum ofputil_port_state); */ enum oftable_flags { OFTABLE_HIDDEN = 1 << 0, /* Hide from most OpenFlow operations. */ - OFTABLE_READONLY = 1 << 1 /* Don't allow OpenFlow to change this table. */ + OFTABLE_READONLY = 1 << 1 /* Don't allow OpenFlow controller to change + this table. */ }; /* A flow table within a "struct ofproto". @@ -260,6 +263,9 @@ struct oftable { uint32_t eviction_group_id_basis; struct hmap eviction_groups_by_id; struct heap eviction_groups_by_size; + + /* Table config: contains enum ofproto_table_config; accessed atomically. */ + atomic_uint config; }; /* Assigns TABLE to each oftable, in turn, in OFPROTO. @@ -336,14 +342,16 @@ struct rule { /* Protects members marked OVS_GUARDED. * Readers only need to hold this mutex. - * Writers must hold both this mutex AND ofproto_mutex. */ + * Writers must hold both this mutex AND ofproto_mutex. + * By implication writers can read *without* taking this mutex while they + * hold ofproto_mutex. */ struct ovs_mutex mutex OVS_ACQ_AFTER(ofproto_mutex); /* Number of references. * The classifier owns one reference. * Any thread trying to keep a rule from being freed should hold its own * reference. */ - atomic_uint ref_count; + struct ovs_refcount ref_count; /* Operation now in progress, if nonnull. */ struct ofoperation *pending OVS_GUARDED_BY(ofproto_mutex); @@ -353,10 +361,6 @@ struct rule { ovs_be64 flow_cookie OVS_GUARDED; struct hindex_node cookie_node OVS_GUARDED_BY(ofproto_mutex); - /* Times. */ - long long int created OVS_GUARDED; /* Creation time. */ - long long int modified OVS_GUARDED; /* Time of last modification. */ - long long int used OVS_GUARDED; /* Last use; time created if never used. */ enum ofputil_flow_mod_flags flags OVS_GUARDED; /* Timeouts. */ @@ -373,7 +377,7 @@ struct rule { /* OpenFlow actions. See struct rule_actions for more thread-safety * notes. */ - struct rule_actions *actions OVS_GUARDED; + OVSRCU_TYPE(const struct rule_actions *) actions; /* In owning meter's 'rules' list. An empty list if there is no meter. */ struct list meter_list_node OVS_GUARDED_BY(ofproto_mutex); @@ -390,15 +394,23 @@ struct rule { /* Optimisation for flow expiry. In ofproto's 'expirable' list if this * rule is expirable, otherwise empty. */ struct list expirable OVS_GUARDED_BY(ofproto_mutex); + + /* Times. Last so that they are more likely close to the stats managed + * by the provider. */ + long long int created OVS_GUARDED; /* Creation time. */ + + /* Must hold 'mutex' for both read/write, 'ofproto_mutex' not needed. */ + long long int modified OVS_GUARDED; /* Time of last modification. */ }; void ofproto_rule_ref(struct rule *); void ofproto_rule_unref(struct rule *); -struct rule_actions *rule_get_actions(const struct rule *rule) - OVS_EXCLUDED(rule->mutex); -struct rule_actions *rule_get_actions__(const struct rule *rule) - OVS_REQUIRES(rule->mutex); +static inline const struct rule_actions * +rule_get_actions(const struct rule *rule) +{ + return ovsrcu_get(const struct rule_actions *, &rule->actions); +} /* Returns true if 'rule' is an OpenFlow 1.3 "table-miss" rule, false * otherwise. @@ -411,6 +423,7 @@ rule_is_table_miss(const struct rule *rule) { return rule->cr.priority == 0 && cls_rule_is_catchall(&rule->cr); } +bool rule_is_internal(const struct rule *); /* A set of actions within a "struct rule". * @@ -418,24 +431,22 @@ rule_is_table_miss(const struct rule *rule) * Thread-safety * ============= * - * A struct rule_actions 'actions' may be accessed without a risk of being + * A struct rule_actions may be accessed without a risk of being * freed by code that holds a read-lock or write-lock on 'rule->mutex' (where - * 'rule' is the rule for which 'rule->actions == actions') or that owns a - * reference to 'actions->ref_count' (or both). */ + * 'rule' is the rule for which 'rule->actions == actions') or during the RCU + * active period. */ struct rule_actions { - atomic_uint ref_count; - /* These members are immutable: they do not change during the struct's * lifetime. */ - struct ofpact *ofpacts; /* Sequence of "struct ofpacts". */ - unsigned int ofpacts_len; /* Size of 'ofpacts', in bytes. */ - uint32_t provider_meter_id; /* Datapath meter_id, or UINT32_MAX. */ + uint32_t ofpacts_len; /* Size of 'ofpacts', in bytes. */ + uint32_t provider_meter_id; /* Datapath meter_id, or UINT32_MAX. */ + struct ofpact ofpacts[]; /* Sequence of "struct ofpacts". */ }; +BUILD_ASSERT_DECL(offsetof(struct rule_actions, ofpacts) % OFPACT_ALIGNTO == 0); -struct rule_actions *rule_actions_create(const struct ofproto *, - const struct ofpact *, size_t); -void rule_actions_ref(struct rule_actions *); -void rule_actions_unref(struct rule_actions *); +const struct rule_actions *rule_actions_create(const struct ofproto *, + const struct ofpact *, size_t); +void rule_actions_destroy(const struct rule_actions *); /* A set of rules to which an OpenFlow operation applies. */ struct rule_collection { @@ -452,17 +463,18 @@ void rule_collection_ref(struct rule_collection *) OVS_REQUIRES(ofproto_mutex); void rule_collection_unref(struct rule_collection *); void rule_collection_destroy(struct rule_collection *); -/* Threshold at which to begin flow table eviction. Only affects the - * ofproto-dpif implementation */ -extern unsigned flow_eviction_threshold; +/* Limits the number of flows allowed in the datapath. Only affects the + * ofproto-dpif implementation. */ +extern unsigned ofproto_flow_limit; -/* Number of upcall handler threads. Only affects the ofproto-dpif - * implementation. */ -extern unsigned n_handler_threads; +/* Maximum idle time (in ms) for flows to be cached in the datapath. + * Revalidators may expire flows more quickly than the configured value based + * on system load and other factors. This variable is subject to change. */ +extern unsigned ofproto_max_idle; -/* Determines which model to use for handling misses in the ofproto-dpif - * implementation */ -extern enum ofproto_flow_miss_model flow_miss_model; +/* Number of upcall handler and revalidator threads. Only affects the + * ofproto-dpif implementation. */ +extern size_t n_handlers, n_revalidators; static inline struct rule * rule_from_cls_rule(const struct cls_rule *cls_rule) @@ -783,6 +795,12 @@ struct ofproto_class { void (*get_memory_usage)(const struct ofproto *ofproto, struct simap *usage); + /* Adds some memory usage statistics for the implementation of 'type' + * into 'usage', for use with memory_report(). + * + * This function is optional. */ + void (*type_get_memory_usage)(const char *type, struct simap *usage); + /* Every "struct rule" in 'ofproto' is about to be deleted, one by one. * This function may prepare for that, for example by clearing state in * advance. It should *not* actually delete any "struct rule"s from @@ -820,7 +838,7 @@ struct ofproto_class { * * - 'write_setfields' and 'apply_setfields' to OFPXMT12_MASK. * - * - 'metadata_match' and 'metadata_write' to UINT64_MAX. + * - 'metadata_match' and 'metadata_write' to OVS_BE64_MAX. * * - 'instructions' to OFPIT11_ALL. * @@ -927,8 +945,9 @@ struct ofproto_class { void (*port_reconfigured)(struct ofport *ofport, enum ofputil_port_config old_config); - /* Looks up a port named 'devname' in 'ofproto'. On success, initializes - * '*port' appropriately. + /* Looks up a port named 'devname' in 'ofproto'. On success, returns 0 and + * initializes '*port' appropriately. Otherwise, returns a positive errno + * value. * * The caller owns the data in 'port' and must free it with * ofproto_port_destroy() when it is no longer needed. */ @@ -1270,7 +1289,7 @@ struct ofproto_class { * in '*byte_count'. UINT64_MAX indicates that the packet count or byte * count is unknown. */ void (*rule_get_stats)(struct rule *rule, uint64_t *packet_count, - uint64_t *byte_count) + uint64_t *byte_count, long long int *used) /* OVS_EXCLUDED(ofproto_mutex) */; /* Applies the actions in 'rule' to 'packet'. (This implements sending @@ -1283,8 +1302,8 @@ struct ofproto_class { * information in 'flow' is extracted from 'packet', except for * flow->tunnel and flow->in_port, which are assigned the correct values * for the incoming packet. The register values are zeroed. 'packet''s - * header pointers (e.g. packet->l3) are appropriately initialized. - * packet->l3 is aligned on a 32-bit boundary. + * header pointers and offsets (e.g. packet->l3) are appropriately + * initialized. packet->l3 is aligned on a 32-bit boundary. * * The implementation should add the statistics for 'packet' into 'rule'. * @@ -1442,15 +1461,19 @@ struct ofproto_class { * support CFM, as does a null pointer. */ int (*set_cfm)(struct ofport *ofport, const struct cfm_settings *s); - /* Checks the status of CFM configured on 'ofport'. Returns true if the - * port's CFM status was successfully stored into '*status'. Returns false - * if the port did not have CFM configured, in which case '*status' is - * indeterminate. + /* Checks the status of CFM configured on 'ofport'. Returns 0 if the + * port's CFM status was successfully stored into '*status'. Returns + * negative number if there is no status change since last update. + * Returns positive errno otherwise. + * + * EOPNOTSUPP as a return value indicates that this ofproto_class does not + * support CFM, as does a null pointer. * - * The caller must provide and owns '*status', but it does not own and must - * not modify or free the array returned in 'status->rmps'. */ - bool (*get_cfm_status)(const struct ofport *ofport, - struct ofproto_cfm_status *status); + * The caller must provide and own '*status', and it must free the array + * returned in 'status->rmps'. '*status' is indeterminate if the return + * value is non-zero. */ + int (*get_cfm_status)(const struct ofport *ofport, + struct ofproto_cfm_status *status); /* Configures BFD on 'ofport'. * @@ -1463,8 +1486,11 @@ struct ofproto_class { int (*set_bfd)(struct ofport *ofport, const struct smap *cfg); /* Populates 'smap' with the status of BFD on 'ofport'. Returns 0 on - * success, or a positive errno. EOPNOTSUPP as a return value indicates - * that this ofproto_class does not support BFD, as does a null pointer. */ + * success. Returns a negative number if there is no status change since + * last update. Returns a positive errno otherwise. + * + * EOPNOTSUPP as a return value indicates that this ofproto_class does not + * support BFD, as does a null pointer. */ int (*get_bfd_status)(struct ofport *ofport, struct smap *smap); /* Configures spanning tree protocol (STP) on 'ofproto' using the @@ -1709,6 +1735,8 @@ BUILD_ASSERT_DECL(OFPROTO_POSTPONE < OFPERR_OFS); int ofproto_flow_mod(struct ofproto *, struct ofputil_flow_mod *) OVS_EXCLUDED(ofproto_mutex); +struct rule *ofproto_refresh_rule(struct rule *rule) + OVS_EXCLUDED(ofproto_mutex); void ofproto_add_flow(struct ofproto *, const struct match *, unsigned int priority, const struct ofpact *ofpacts, size_t ofpacts_len)