X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-provider.h;h=23d9180c9d38f039aa529a5132b2e4cfa86f45dd;hb=380f49c4a1ffaf5efa136985cff92de52bc8b582;hp=15dc34721810f3a5e75c51a6f583a7670e79b231;hpb=1c0333b6baf58cb382d78b53305bfb06149793e2;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h index 15dc34721..23d9180c9 100644 --- a/ofproto/ofproto-provider.h +++ b/ofproto/ofproto-provider.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,11 +27,13 @@ #include "ofp-errors.h" #include "ofp-util.h" #include "shash.h" +#include "simap.h" #include "timeval.h" +struct match; struct ofpact; struct ofputil_flow_mod; -struct simap; +struct bfd_cfg; /* An OpenFlow switch. * @@ -46,26 +48,31 @@ 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. */ - char *serial_desc; /* Serial number. */ - char *dp_desc; /* Datapath description. */ + char *mfr_desc; /* Manufacturer (NULL for default)b. */ + char *hw_desc; /* Hardware (NULL for default). */ + char *sw_desc; /* Software version (NULL for default). */ + char *serial_desc; /* Serial number (NULL for default). */ + char *dp_desc; /* Datapath description (NULL for default). */ enum ofp_config_flags frag_handling; /* One of OFPC_*. */ /* Datapath. */ struct hmap ports; /* Contains "struct ofport"s. */ struct shash port_by_name; + unsigned long *ofp_port_ids;/* Bitmap of used OpenFlow port numbers. */ + struct simap ofp_requests; /* OpenFlow port number requests. */ + 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; int n_tables; + /* Optimisation for flow expiry. + * These flows should all be present in tables. */ + struct list expirable; /* Expirable 'struct rule"s in all tables. */ + /* OpenFlow connections. */ struct connmgr *connmgr; @@ -93,6 +100,7 @@ struct ofproto { }; void ofproto_init_tables(struct ofproto *, int n_tables); +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 *, uint16_t ofp_port); @@ -108,11 +116,35 @@ struct ofport { struct ofputil_phy_port pp; uint16_t ofp_port; /* OpenFlow port number. */ unsigned int change_seq; + long long int created; /* Time created, in msec. */ int mtu; }; void ofproto_port_set_state(struct ofport *, enum ofputil_port_state); +/* OpenFlow table flags: + * + * - "Hidden" tables are not included in OpenFlow operations that operate on + * "all tables". For example, a request for flow stats on all tables will + * omit flows in hidden tables, table stats requests will omit the table + * entirely, and the switch features reply will not count the hidden table. + * + * However, operations that specifically name the particular table still + * operate on it. For example, flow_mods and flow stats requests on a + * hidden table work. + * + * To avoid gaps in table IDs (which have unclear validity in OpenFlow), + * hidden tables must be the highest-numbered tables that a provider + * implements. + * + * - "Read-only" tables can't be changed through OpenFlow operations. (At + * the moment all flow table operations go effectively through OpenFlow, so + * this means that read-only tables can't be changed at all after the + * read-only flag is set.) + * + * The generic ofproto layer never sets these flags. An ofproto provider can + * set them if it is appropriate. + */ enum oftable_flags { OFTABLE_HIDDEN = 1 << 0, /* Hide from most OpenFlow operations. */ OFTABLE_READONLY = 1 << 1 /* Don't allow OpenFlow to change this table. */ @@ -192,8 +224,16 @@ struct rule { enum nx_flow_monitor_flags monitor_flags; uint64_t add_seqno; /* Sequence number when added. */ uint64_t modify_seqno; /* Sequence number when changed. */ + + /* Optimisation for flow expiry. */ + struct list expirable; /* In ofproto's 'expirable' list if this rule + * is expirable, otherwise empty. */ }; +/* Threshold at which to begin flow table eviction. Only affects the + * ofproto-dpif implementation */ +extern unsigned flow_eviction_threshold; + static inline struct rule * rule_from_cls_rule(const struct cls_rule *cls_rule) { @@ -317,6 +357,16 @@ struct ofproto_class { /* ## Factory Functions ## */ /* ## ----------------- ## */ + /* Initializes provider. The caller may pass in 'iface_hints', + * which contains an shash of "struct iface_hint" elements indexed + * by the interface's name. The provider may use these hints to + * describe the startup configuration in order to reinitialize its + * state. The caller owns the provided data, so a provider must + * make copies of anything required. An ofproto provider must + * remove any existing state that is not described by the hint, and + * may choose to remove it all. */ + void (*init)(const struct shash *iface_hints); + /* Enumerates the types of all support ofproto types into 'types'. The * caller has already initialized 'types' and other ofproto classes might * already have added names to it. */ @@ -343,6 +393,48 @@ struct ofproto_class { */ int (*del)(const char *type, const char *name); + /* Returns the type to pass to netdev_open() when a datapath of type + * 'datapath_type' has a port of type 'port_type', for a few special + * cases when a netdev type differs from a port type. For example, + * when using the userspace datapath, a port of type "internal" + * needs to be opened as "tap". + * + * Returns either 'type' itself or a string literal, which must not + * be freed. */ + const char *(*port_open_type)(const char *datapath_type, + const char *port_type); + +/* ## ------------------------ ## */ +/* ## Top-Level type Functions ## */ +/* ## ------------------------ ## */ + + /* Performs any periodic activity required on ofprotos of type + * 'type'. + * + * An ofproto provider may implement it or not, depending on whether + * it needs type-level maintenance. + * + * Returns 0 if successful, otherwise a positive errno value. */ + int (*type_run)(const char *type); + + /* Performs periodic activity required on ofprotos of type 'type' + * that needs to be done with the least possible latency. + * + * This is run multiple times per main loop. An ofproto provider may + * implement it or not, according to whether it provides a performance + * boost for that ofproto implementation. + * + * Returns 0 if successful, otherwise a positive errno value. */ + int (*type_run_fast)(const char *type); + + /* Causes the poll loop to wake up when a type 'type''s 'run' + * function needs to be called, e.g. by calling the timer or fd + * waiting functions in poll-loop.h. + * + * An ofproto provider may implement it or not, depending on whether + * it needs type-level maintenance. */ + void (*type_wait)(const char *type); + /* ## --------------------------- ## */ /* ## Top-Level ofproto Functions ## */ /* ## --------------------------- ## */ @@ -365,6 +457,11 @@ struct ofproto_class { * ->construct() should delete flows from the underlying datapath, if * necessary, rather than populating the tables. * + * If the ofproto knows the maximum port number that the datapath can have, + * then it can call ofproto_init_max_ports(). If it does so, then the + * client will ensure that the actions it allows to be used through + * OpenFlow do not refer to ports above that maximum number. + * * 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 * attempt to "construct" the same datapath as part of another ofproto is @@ -456,7 +553,17 @@ struct ofproto_class { * * - 'name' to "table#" where # is the table ID. * - * - 'wildcards' to OFPFW10_ALL. + * - 'match' and 'wildcards' to OFPXMT12_MASK. + * + * - 'write_actions' and 'apply_actions' to OFPAT12_OUTPUT. + * + * - 'write_setfields' and 'apply_setfields' to OFPXMT12_MASK. + * + * - 'metadata_match' and 'metadata_write' to UINT64_MAX. + * + * - 'instructions' to OFPIT11_ALL. + * + * - 'config' to OFPTC11_TABLE_MISS_MASK. * * - 'max_entries' to 1,000,000. * @@ -472,6 +579,21 @@ struct ofproto_class { * - 'wildcards' to the set of wildcards actually supported by the table * (if it doesn't support all OpenFlow wildcards). * + * - 'instructions' to set the instructions actually supported by + * the table. + * + * - 'write_actions' to set the write actions actually supported by + * the table (if it doesn't support all OpenFlow actions). + * + * - 'apply_actions' to set the apply actions actually supported by + * the table (if it doesn't support all OpenFlow actions). + * + * - 'write_setfields' to set the write setfields actually supported by + * the table. + * + * - 'apply_setfields' to set the apply setfields actually supported by + * the table. + * * - 'max_entries' to the maximum number of flows actually supported by * the hardware. * @@ -481,10 +603,10 @@ struct ofproto_class { * - '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 ofp10_table_stats are in - * network byte order. + * All of the members of struct ofp12_table_stats are in network byte + * order. */ - void (*get_tables)(struct ofproto *ofproto, struct ofp10_table_stats *ots); + void (*get_tables)(struct ofproto *ofproto, struct ofp12_table_stats *ots); /* ## ---------------- ## */ /* ## ofport Functions ## */ @@ -493,6 +615,8 @@ struct ofproto_class { /* Life-cycle functions for a "struct ofport" (see "Life Cycle" above). * * ->port_construct() should not modify any base members of the ofport. + * An ofproto implementation should use the 'ofp_port' member of + * "struct ofport" as the OpenFlow port number. * * ofports are managed by the base ofproto code. The ofproto * implementation should only create and destroy them in response to calls @@ -551,14 +675,14 @@ struct ofproto_class { const char *devname, struct ofproto_port *port); /* Attempts to add 'netdev' as a port on 'ofproto'. Returns 0 if - * successful, otherwise a positive errno value. If successful, sets - * '*ofp_portp' to the new port's port number. + * successful, otherwise a positive errno value. The caller should + * inform the implementation of the OpenFlow port through the + * ->port_construct() method. * * It doesn't matter whether the new port will be returned by a later call * to ->port_poll(); the implementation may do whatever is more * convenient. */ - int (*port_add)(struct ofproto *ofproto, struct netdev *netdev, - uint16_t *ofp_portp); + int (*port_add)(struct ofproto *ofproto, struct netdev *netdev); /* Deletes port number 'ofp_port' from the datapath for 'ofproto'. Returns * 0 if successful, otherwise a positive errno value. @@ -576,11 +700,9 @@ struct ofproto_class { * * The client might not be entirely in control of the ports within an * ofproto. Some hardware implementations, for example, might have a fixed - * set of ports in a datapath, and the Linux datapath allows the system - * administrator to externally add and remove ports with ovs-dpctl. For - * this reason, the client needs a way to iterate through all the ports - * that are actually in a datapath. These functions provide that - * functionality. + * set of ports in a datapath. For this reason, the client needs a way to + * iterate through all the ports that are actually in a datapath. These + * functions provide that functionality. * * The 'state' pointer provides the implementation a place to * keep track of its position. Its format is opaque to the caller. @@ -694,24 +816,22 @@ struct ofproto_class { /* ## OpenFlow Rule Functions ## */ /* ## ----------------------- ## */ - - - /* Chooses an appropriate table for 'cls_rule' within 'ofproto'. On + /* Chooses an appropriate table for 'match' within 'ofproto'. On * success, stores the table ID into '*table_idp' and returns 0. On * failure, returns an OpenFlow error code. * - * The choice of table should be a function of 'cls_rule' and 'ofproto''s + * The choice of table should be a function of 'match' 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. + * 'match' 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). * * If this function is NULL then table 0 is always chosen. */ enum ofperr (*rule_choose_table)(const struct ofproto *ofproto, - const struct cls_rule *cls_rule, + const struct match *match, uint8_t *table_idp); /* Life-cycle functions for a "struct rule" (see "Life Cycle" above). @@ -796,11 +916,7 @@ struct ofproto_class { * registers, then it is an error if 'rule->cr' does not wildcard all * registers. * - * - Validate that 'rule->ofpacts' is a sequence of well-formed actions - * that the datapath can correctly implement. If your ofproto - * implementation only implements a subset of the actions that Open - * vSwitch understands, then you should implement your own action - * validation. + * - 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. @@ -866,7 +982,7 @@ struct ofproto_class { * * 'flow' reflects the flow information for 'packet'. All of the * information in 'flow' is extracted from 'packet', except for - * flow->tun_id and flow->in_port, which are assigned the correct values + * 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. * @@ -882,8 +998,8 @@ struct ofproto_class { * * ->rule_modify_actions() should set the following in motion: * - * - Validate that the actions now in 'rule' are well-formed OpenFlow - * actions that the datapath can correctly implement. + * - Validate that the datapath can correctly implement the actions now + * in 'rule'. * * - Update the datapath flow table with the new actions. * @@ -936,27 +1052,28 @@ struct ofproto_class { * The caller retains ownership of 'packet' and of 'ofpacts', so * ->packet_out() should not modify or free them. * - * This function must validate that it can implement 'ofpacts'. If not, - * then it should return an OpenFlow error code. + * This function must validate that it can correctly implement 'ofpacts'. + * If not, then it should return an OpenFlow error code. * * 'flow' reflects the flow information for 'packet'. All of the * information in 'flow' is extracted from 'packet', except for - * flow->in_port (see below). flow->tun_id and its register values are + * flow->in_port (see below). flow->tunnel and its register values are * zeroed. * * flow->in_port comes from the OpenFlow OFPT_PACKET_OUT message. The * implementation should reject invalid flow->in_port values by returning - * OFPERR_NXBRC_BAD_IN_PORT. For consistency, the implementation should - * consider valid for flow->in_port any value that could possibly be seen - * in a packet that it passes to connmgr_send_packet_in(). Ideally, even - * an implementation that never generates packet-ins (e.g. due to hardware - * limitations) should still allow flow->in_port values for every possible - * physical port and OFPP_LOCAL. The only virtual ports (those above - * OFPP_MAX) that the caller will ever pass in as flow->in_port, other than - * OFPP_LOCAL, are OFPP_NONE and OFPP_CONTROLLER. The implementation - * should allow both of these, treating each of them as packets generated - * by the controller as opposed to packets originating from some switch - * port. + * OFPERR_OFPBRC_BAD_PORT. (If the implementation called + * ofproto_init_max_ports(), then the client will reject these ports + * itself.) For consistency, the implementation should consider valid for + * flow->in_port any value that could possibly be seen in a packet that it + * passes to connmgr_send_packet_in(). Ideally, even an implementation + * that never generates packet-ins (e.g. due to hardware limitations) + * should still allow flow->in_port values for every possible physical port + * and OFPP_LOCAL. The only virtual ports (those above OFPP_MAX) that the + * caller will ever pass in as flow->in_port, other than OFPP_LOCAL, are + * OFPP_NONE and OFPP_CONTROLLER. The implementation should allow both of + * these, treating each of them as packets generated by the controller as + * opposed to packets originating from some switch port. * * (Ordinarily the only effect of flow->in_port is on output actions that * involve the input port, such as actions that output to OFPP_IN_PORT, @@ -995,6 +1112,20 @@ struct ofproto_class { int (*set_sflow)(struct ofproto *ofproto, const struct ofproto_sflow_options *sflow_options); + /* Configures IPFIX on 'ofproto' according to the options in + * 'bridge_exporter_options' and the 'flow_exporters_options' + * array, or turns off IPFIX if 'bridge_exporter_options' and + * 'flow_exporters_options' is NULL. + * + * EOPNOTSUPP as a return value indicates that 'ofproto' does not support + * IPFIX, as does a null pointer. */ + int (*set_ipfix)( + struct ofproto *ofproto, + const struct ofproto_ipfix_bridge_exporter_options + *bridge_exporter_options, + const struct ofproto_ipfix_flow_exporter_options + *flow_exporters_options, size_t n_flow_exporters_options); + /* Configures connectivity fault management on 'ofport'. * * If 'cfm_settings' is nonnull, configures CFM according to its members. @@ -1006,44 +1137,30 @@ struct ofproto_class { * support CFM, as does a null pointer. */ int (*set_cfm)(struct ofport *ofport, const struct cfm_settings *s); - /* Checks the fault status of CFM configured on 'ofport'. Returns a - * bitmask of 'cfm_fault_reason's to indicate a CFM fault (generally - * indicating a connectivity problem). Returns zero if CFM is not faulted, - * and -1 if CFM is not enabled on 'port'. + /* 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. * - * This function may be a null pointer if the ofproto implementation does - * not support CFM. */ - int (*get_cfm_fault)(const struct ofport *ofport); + * 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); - /* Check the operational status reported by the remote CFM endpoint of - * 'ofp_port' Returns 1 if operationally up, 0 if operationally down, and - * -1 if CFM is not enabled on 'ofp_port' or does not support operational - * status. + /* Configures BFD on 'ofport'. * - * This function may be a null pointer if the ofproto implementation does - * not support CFM. */ - int (*get_cfm_opup)(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'. + * If 'cfg' is NULL, or 'cfg' does not contain the key value pair + * "enable=true", removes BFD from 'ofport'. Otherwise, configures BFD + * according to 'cfg'. * - * 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); + * EOPNOTSUPP as a return value indicates that this ofproto_class does not + * support BFD, as does a null pointer. */ + int (*set_bfd)(struct ofport *ofport, const struct smap *cfg); - /* Checks the health of CFM configured on 'ofport'. Returns an integer - * to indicate the health percentage of the 'ofport' which is an average of - * the health of all the remote_mps. Returns an integer between 0 and 100 - * where 0 means that the 'ofport' is very unhealthy and 100 means the - * 'ofport' is perfectly healthy. Returns -1 if CFM is not enabled on - * 'port' or if the number of remote_mpids is > 1. - * - * This function may be a null pointer if the ofproto implementation does - * not support CFM. */ - int (*get_cfm_health)(const struct ofport *ofport); + /* 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. */ + int (*get_bfd_status)(struct ofport *ofport, struct smap *smap); /* Configures spanning tree protocol (STP) on 'ofproto' using the * settings defined in 's'. @@ -1173,9 +1290,14 @@ struct ofproto_class { * will be invoked. */ void (*forward_bpdu_changed)(struct ofproto *ofproto); - /* Sets the MAC aging timeout for the OFPP_NORMAL action to 'idle_time', - * in seconds. */ - void (*set_mac_idle_time)(struct ofproto *ofproto, unsigned int idle_time); + /* Sets the MAC aging timeout for the OFPP_NORMAL action to 'idle_time', in + * seconds, and the maximum number of MAC table entries to + * 'max_entries'. + * + * An implementation that doesn't support configuring these features may + * set this function to NULL or implement it as a no-op. */ + void (*set_mac_table_config)(struct ofproto *ofproto, + unsigned int idle_time, size_t max_entries); /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.) * @@ -1215,9 +1337,11 @@ enum { OFPROTO_POSTPONE = 1 << 16 }; BUILD_ASSERT_DECL(OFPROTO_POSTPONE < OFPERR_OFS); int ofproto_flow_mod(struct ofproto *, const struct ofputil_flow_mod *); -void ofproto_add_flow(struct ofproto *, const struct cls_rule *, +void ofproto_add_flow(struct ofproto *, const struct match *, + unsigned int priority, const struct ofpact *ofpacts, size_t ofpacts_len); -bool ofproto_delete_flow(struct ofproto *, const struct cls_rule *); +bool ofproto_delete_flow(struct ofproto *, + const struct match *, unsigned int priority); void ofproto_flush_flows(struct ofproto *); #endif /* ofproto/ofproto-provider.h */