/* 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
char *sw_desc; /* Software version. */
char *serial_desc; /* Serial number. */
char *dp_desc; /* Datapath description. */
+ enum ofp_config_flags frag_handling; /* One of OFPC_*. */
/* Datapath. */
struct hmap ports; /* Contains "struct ofport"s. */
/* 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. */
};
(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
struct ofp_phy_port opp;
uint16_t ofp_port; /* OpenFlow port number. */
unsigned int change_seq;
+ int mtu;
};
+void ofproto_port_set_state(struct ofport *, ovs_be32 state);
+
/* An OpenFlow flow within a "struct ofproto".
*
* With few exceptions, ofproto implementations may look at these fields but
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? */
*
* - '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:
*
* - 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:
*
* * 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()
* rule. */
void (*rule_modify_actions)(struct rule *rule);
- /* These functions implement the OpenFlow IP fragment handling policy. By
- * default ('drop_frags' == false), an OpenFlow switch should treat IP
- * fragments the same way as other packets (although TCP and UDP port
- * numbers cannot be determined). With 'drop_frags' == true, the switch
- * should drop all IP fragments without passing them through the flow
- * table. */
- bool (*get_drop_frags)(struct ofproto *ofproto);
- void (*set_drop_frags)(struct ofproto *ofproto, bool drop_frags);
+ /* Changes the OpenFlow IP fragment handling policy to 'frag_handling',
+ * which takes one of the following values, with the corresponding
+ * meanings:
+ *
+ * - OFPC_FRAG_NORMAL: The switch should treat IP fragments the same way
+ * as other packets, omitting TCP and UDP port numbers (always setting
+ * them to 0).
+ *
+ * - OFPC_FRAG_DROP: The switch should drop all IP fragments without
+ * passing them through the flow table.
+ *
+ * - OFPC_FRAG_REASM: The switch should reassemble IP fragments before
+ * passing packets through the flow table.
+ *
+ * - OFPC_FRAG_NX_MATCH (a Nicira extension): Similar to OFPC_FRAG_NORMAL,
+ * except that TCP and UDP port numbers should be included in fragments
+ * with offset 0.
+ *
+ * Implementations are not required to support every mode.
+ * OFPC_FRAG_NORMAL is the default mode when an ofproto is created.
+ *
+ * At the time of the call to ->set_frag_handling(), the current mode is
+ * available in 'ofproto->frag_handling'. ->set_frag_handling() returns
+ * true if the requested mode was set, false if it is not supported.
+ *
+ * Upon successful return, the caller changes 'ofproto->frag_handling' to
+ * reflect the new mode.
+ */
+ bool (*set_frag_handling)(struct ofproto *ofproto,
+ enum ofp_config_flags frag_handling);
/* Implements the OpenFlow OFPT_PACKET_OUT command. The datapath should
* execute the 'n_actions' in the 'actions' array on 'packet'.
* 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);
+
+ /* Configures spanning tree protocol (STP) on 'ofproto' using the
+ * settings defined in 's'.
+ *
+ * If 's' is nonnull, configures STP according to its members.
+ *
+ * If 's' is null, removes any STP configuration from 'ofproto'.
+ *
+ * EOPNOTSUPP as a return value indicates that this ofproto_class does not
+ * support STP, as does a null pointer. */
+ int (*set_stp)(struct ofproto *ofproto,
+ const struct ofproto_stp_settings *s);
+
+ /* Retrieves state of spanning tree protocol (STP) on 'ofproto'.
+ *
+ * Stores STP state for 'ofproto' in 's'. If the 'enabled' member
+ * is false, the other member values are not meaningful.
+ *
+ * EOPNOTSUPP as a return value indicates that this ofproto_class does not
+ * support STP, as does a null pointer. */
+ int (*get_stp_status)(struct ofproto *ofproto,
+ struct ofproto_stp_status *s);
+
+ /* Configures spanning tree protocol (STP) on 'ofport' using the
+ * settings defined in 's'.
+ *
+ * If 's' is nonnull, configures STP according to its members. The
+ * caller is responsible for assigning STP port numbers (using the
+ * 'port_num' member in the range of 1 through 255, inclusive) and
+ * ensuring there are no duplicates.
+ *
+ * If 's' is null, removes any STP configuration from 'ofport'.
+ *
+ * EOPNOTSUPP as a return value indicates that this ofproto_class does not
+ * support STP, as does a null pointer. */
+ int (*set_stp_port)(struct ofport *ofport,
+ const struct ofproto_port_stp_settings *s);
+
+ /* Retrieves spanning tree protocol (STP) port status of 'ofport'.
+ *
+ * Stores STP state for 'ofport' in 's'. If the 'enabled' member is
+ * false, the other member values are not meaningful.
+ *
+ * EOPNOTSUPP as a return value indicates that this ofproto_class does not
+ * support STP, as does a null pointer. */
+ int (*get_stp_port_status)(struct ofport *ofport,
+ struct ofproto_port_stp_status *s);
+
/* 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
/* 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);
+ bool (*is_mirror_output_bundle)(const struct ofproto *ofproto, void *aux);
/* When the configuration option of forward_bpdu changes, this function
* will be invoked. */
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 *);