/*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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_*. */
+ enum ofputil_frag_handling frag_handling;
/* Datapath. */
struct hmap ports; /* Contains "struct ofport"s. */
long long int eviction_group_timer; /* For rate limited reheapification. */
struct oftable *tables;
int n_tables;
+ cls_version_t tables_version; /* Controls which rules are visible to
+ * table lookups. */
/* Rules indexed on their cookie values, in all flow tables. */
struct hindex cookies OVS_GUARDED_BY(ofproto_mutex);
/* Maximum number of flows or UINT_MAX if there is no limit besides any
* limit imposed by resource limitations. */
unsigned int max_flows;
+ /* Current number of flows, not counting temporary duplicates nor deferred
+ * deletions. */
+ unsigned int n_flows;
/* These members determine the handling of an attempt to add a flow that
* would cause the table to have more than 'max_flows' flows.
struct hmap eviction_groups_by_id;
struct heap eviction_groups_by_size;
- /* Table configuration. */
+ /* Flow table miss handling configuration. */
ATOMIC(enum ofputil_table_miss) miss_config;
+ /* Eviction is enabled if either the client (vswitchd) enables it or an
+ * OpenFlow controller enables it; thus, a nonzero value indicates that
+ * eviction is enabled. */
+#define EVICTION_CLIENT (1 << 0) /* Set to 1 if client enables eviction. */
+#define EVICTION_OPENFLOW (1 << 1) /* Set to 1 if OpenFlow enables eviction. */
+ unsigned int eviction;
+
+ /* If true, vacancy events are enabled; otherwise they are disabled. */
+ bool vacancy_enabled;
+
+ /* Non-zero values for vacancy_up and vacancy_down indicates that vacancy
+ * is enabled by table-mod, else these values are set to zero when
+ * vacancy is disabled */
+ uint8_t vacancy_down; /* Vacancy threshold when space decreases (%). */
+ uint8_t vacancy_up; /* Vacancy threshold when space increases (%). */
+
atomic_ulong n_matched;
atomic_ulong n_missed;
};
struct ofproto *const ofproto; /* The ofproto that contains this rule. */
const struct cls_rule cr; /* In owning ofproto's classifier. */
const uint8_t table_id; /* Index in ofproto's 'tables' array. */
+ bool removed; /* Rule has been removed from the ofproto
+ * data structures. */
/* Protects members marked OVS_GUARDED.
* Readers only need to hold this mutex.
uint16_t idle_timeout OVS_GUARDED; /* In seconds from ->used. */
/* Eviction precedence. */
- uint16_t importance OVS_GUARDED;
+ const uint16_t importance;
+
+ /* Removal reason for sending flow removed message.
+ * Used only if 'flags' has OFPUTIL_FF_SEND_FLOW_REM set and if the
+ * value is not OVS_OFPRR_NONE. */
+ uint8_t removed_reason;
/* Eviction groups (see comment on struct eviction_group for explanation) .
*
/* OpenFlow actions. See struct rule_actions for more thread-safety
* notes. */
- OVSRCU_TYPE(const struct rule_actions *) actions;
+ const struct rule_actions * const actions;
/* In owning meter's 'rules' list. An empty list if there is no meter. */
struct ovs_list meter_list_node OVS_GUARDED_BY(ofproto_mutex);
* code that holds 'rule->mutex' (where 'rule' is the rule for which
* 'rule->actions == actions') or during the RCU active period.
*
- * All members are immutable: they do not change during the struct's
+ * All members are immutable: they do not change during the rule's
* lifetime. */
struct rule_actions {
/* Flags.
* ofproto-dpif implementation. */
extern size_t n_handlers, n_revalidators;
-/* Number of rx queues to be created for each dpdk interface. */
-extern size_t n_dpdk_rxqs;
-
/* Cpu mask for pmd threads. */
extern char *pmd_cpu_mask;
struct ovs_list buckets; /* Contains "struct ofputil_bucket"s. */
const uint32_t n_buckets;
+
+ const struct ofputil_group_props props;
};
bool ofproto_group_lookup(const struct ofproto *ofproto, uint32_t group_id,
void ofproto_group_ref(struct ofgroup *);
void ofproto_group_unref(struct ofgroup *);
+void ofproto_group_delete_all(struct ofproto *);
+
/* ofproto class structure, to be defined by each ofproto implementation.
*
*
* not yet been uninitialized, so the "destruct" function may refer to it. The
* "destruct" function is not allowed to fail.
*
- * Each "dealloc" function frees raw memory that was allocated by the the
+ * Each "dealloc" function frees raw memory that was allocated by the
* "alloc" function. The memory's base and derived members might not have ever
* been initialized (but if "construct" returned successfully, then it has been
* "destruct"ed already). The "dealloc" function is not allowed to fail.
* ===========
*
* ->destruct() must also destroy all remaining rules in the ofproto's
- * tables, by passing each remaining rule to ofproto_rule_delete().
+ * tables, by passing each remaining rule to ofproto_rule_delete(), then
+ * destroy all remaining groups by calling ofproto_group_delete_all().
*
* The client will destroy the flow tables themselves after ->destruct()
* returns.
*
* - 'table_id' to the array index.
*
- * - 'active_count' to the classifier_count() for the table.
+ * - 'active_count' to the 'n_flows' of struct ofproto for the table.
*
* - 'lookup_count' and 'matched_count' to 0.
*
struct ofputil_table_features *features,
struct ofputil_table_stats *stats);
+ /* Sets the current tables version the provider should use for classifier
+ * lookups. */
+ void (*set_tables_version)(struct ofproto *ofproto, cls_version_t version);
/* ## ---------------- ## */
/* ## ofport Functions ## */
/* ## ---------------- ## */
* initialization, and construct and destruct ofports to reflect all of
* the changes.
*
+ * - On graceful shutdown, the base ofproto code will destruct all
+ * the ports.
+ *
* ->port_construct() returns 0 if successful, otherwise a positive errno
* value.
+ *
+ *
+ * ->port_destruct()
+ * =================
+ *
+ * ->port_destruct() takes a 'del' parameter. If the provider implements
+ * the datapath itself (e.g. dpif-netdev, it can ignore 'del'. On the
+ * other hand, if the provider is an interface to an external datapath
+ * (e.g. to a kernel module that implement the datapath) then 'del' should
+ * influence destruction behavior in the following way:
+ *
+ * - If 'del' is true, it should remove the port from the underlying
+ * implementation. This is the common case.
+ *
+ * - If 'del' is false, it should leave the port in the underlying
+ * implementation. This is used when Open vSwitch is performing a
+ * graceful shutdown and ensures that, across Open vSwitch restarts,
+ * the underlying ports are not removed and recreated. That makes an
+ * important difference for, e.g., "internal" ports that have
+ * configured IP addresses; without this distinction, the IP address
+ * and other configured state for the port is lost.
*/
struct ofport *(*port_alloc)(void);
int (*port_construct)(struct ofport *ofport);
- void (*port_destruct)(struct ofport *ofport);
+ void (*port_destruct)(struct ofport *ofport, bool del);
void (*port_dealloc)(struct ofport *ofport);
/* Called after 'ofport->netdev' is replaced by a new netdev object. If
* OpenFlow error code), the ofproto base code will uninitialize and
* deallocate 'rule'. See "Rule Life Cycle" above for more details.
*
- * ->rule_construct() may also:
+ * ->rule_construct() must also:
*
* - Validate that the datapath supports the matching rule in 'rule->cr'
* datapath. For example, if the rule's table does not support
*
* - Validate that the datapath can correctly implement 'rule->ofpacts'.
*
- * Some implementations might need to defer these tasks to ->rule_insert(),
- * which is also acceptable.
+ * After a successful construction the rest of the rule life cycle calls
+ * may not fail, so ->rule_construct() must also make sure that the rule
+ * can be inserted in to the datapath.
*
*
* Insertion
* Following successful construction, the ofproto base case inserts 'rule'
* into its flow table, then it calls ->rule_insert(). ->rule_insert()
* must add the new rule to the datapath flow table and return only after
- * this is complete (whether it succeeds or fails).
- *
- * If ->rule_insert() fails, the ofproto base code will remove 'rule' from
- * the flow table, destruct, uninitialize, and deallocate 'rule'. See
- * "Rule Life Cycle" above for more details.
+ * this is complete. The 'new_rule' may be a duplicate of an 'old_rule'.
+ * In this case the 'old_rule' is non-null, and the implementation should
+ * forward rule statistics from the 'old_rule' to the 'new_rule' if
+ * 'forward_stats' is 'true'. This may not fail.
*
*
* Deletion
struct rule *(*rule_alloc)(void);
enum ofperr (*rule_construct)(struct rule *rule)
/* OVS_REQUIRES(ofproto_mutex) */;
- enum ofperr (*rule_insert)(struct rule *rule)
+ void (*rule_insert)(struct rule *rule, struct rule *old_rule,
+ bool forward_stats)
/* OVS_REQUIRES(ofproto_mutex) */;
void (*rule_delete)(struct rule *rule) /* OVS_REQUIRES(ofproto_mutex) */;
void (*rule_destruct)(struct rule *rule);
enum ofperr (*rule_execute)(struct rule *rule, const struct flow *flow,
struct dp_packet *packet);
- /* If the datapath can properly implement changing 'rule''s actions to the
- * 'ofpacts_len' bytes in 'ofpacts', returns 0. Otherwise, returns an enum
- * ofperr indicating why the new actions wouldn't work.
- *
- * May be a null pointer if any set of actions is acceptable. */
- enum ofperr (*rule_premodify_actions)(const struct rule *rule,
- const struct ofpact *ofpacts,
- size_t ofpacts_len)
- /* OVS_REQUIRES(ofproto_mutex) */;
-
- /* When ->rule_modify_actions() is called, the caller has already replaced
- * the OpenFlow actions in 'rule' by a new set. (If
- * ->rule_premodify_actions is nonnull, then it was previously called to
- * verify that the new set of actions is acceptable.)
- *
- * ->rule_modify_actions() must:
- *
- * - 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.
- *
- * Rule modification must not fail.
- *
- * ->rule_modify_actions() should not modify any base members of struct
- * rule. */
- void (*rule_modify_actions)(struct rule *rule, bool reset_counters)
- /* OVS_REQUIRES(ofproto_mutex) */;
-
/* 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).
+ * - OFPUTIL_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
+ * - OFPUTIL_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
+ * - OFPUTIL_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.
+ * - OFPUTIL_FRAG_NX_MATCH (a Nicira extension): Similar to
+ * OFPUTIL_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.
+ * OFPUTIL_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
* reflect the new mode.
*/
bool (*set_frag_handling)(struct ofproto *ofproto,
- enum ofp_config_flags frag_handling);
+ enum ofputil_frag_handling frag_handling);
/* Implements the OpenFlow OFPT_PACKET_OUT command. The datapath should
* execute the 'ofpacts_len' bytes of "struct ofpacts" in 'ofpacts'.
int ofproto_class_register(const struct ofproto_class *);
int ofproto_class_unregister(const struct ofproto_class *);
-int ofproto_flow_mod(struct ofproto *, struct ofputil_flow_mod *)
+/* flow_mod with execution context. */
+struct ofproto_flow_mod {
+ struct ofputil_flow_mod fm;
+
+ cls_version_t version; /* Version in which changes take
+ * effect. */
+ struct rule_collection old_rules; /* Affected rules. */
+ struct rule_collection new_rules; /* Replacement rules. */
+};
+
+/* port_mod with execution context. */
+struct ofproto_port_mod {
+ struct ofputil_port_mod pm;
+ struct ofport *port; /* Affected port. */
+};
+
+enum ofperr ofproto_flow_mod(struct ofproto *, struct ofproto_flow_mod *)
OVS_EXCLUDED(ofproto_mutex);
void ofproto_add_flow(struct ofproto *, const struct match *, int priority,
const struct ofpact *ofpacts, size_t ofpacts_len)
OVS_EXCLUDED(ofproto_mutex);
void ofproto_flush_flows(struct ofproto *);
+enum ofperr ofproto_check_ofpacts(struct ofproto *,
+ const struct ofpact ofpacts[],
+ size_t ofpacts_len);
\f
static inline const struct rule_actions *
rule_get_actions(const struct rule *rule)
{
- return ovsrcu_get(const struct rule_actions *, &rule->actions);
+ return rule->actions;
}
/* Returns true if 'rule' is an OpenFlow 1.3 "table-miss" rule, false