{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
struct shash_node *node, *next;
- odp_port_t max_ports;
+ uint32_t max_ports;
int error;
error = open_dpif_backer(ofproto->up.type, &ofproto->backer);
}
max_ports = dpif_get_max_ports(ofproto->backer->dpif);
- ofproto_init_max_ports(ofproto_, u16_to_ofp(MIN(odp_to_u32(max_ports),
- ofp_to_u16(OFPP_MAX))));
+ ofproto_init_max_ports(ofproto_, MIN(max_ports, ofp_to_u16(OFPP_MAX)));
ofproto->netflow = NULL;
ofproto->sflow = NULL;
ovs_rwlock_wrlock(&table->cls.rwlock);
cls_cursor_init(&cursor, &table->cls, NULL);
CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, up.cr, &cursor) {
- ofproto_rule_destroy(&ofproto->up, &table->cls, &rule->up);
+ ofproto_rule_delete(&ofproto->up, &table->cls, &rule->up);
}
ovs_rwlock_unlock(&table->cls.rwlock);
}
+ complete_operations(ofproto);
ovs_mutex_lock(&ofproto->flow_mod_mutex);
LIST_FOR_EACH_SAFE (fm, next_fm, list_node, &ofproto->flow_mods) {
if (ofproto->sflow) {
dpif_sflow_run(ofproto->sflow);
}
+ if (ofproto->ipfix) {
+ dpif_ipfix_run(ofproto->ipfix);
+ }
HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
port_run(ofport);
if (ofproto->sflow) {
dpif_sflow_wait(ofproto->sflow);
}
+ if (ofproto->ipfix) {
+ dpif_ipfix_wait(ofproto->ipfix);
+ }
HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
port_wait(ofport);
}
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
struct dpif_ipfix *di = ofproto->ipfix;
+ bool has_options = bridge_exporter_options || flow_exporters_options;
- if (bridge_exporter_options || flow_exporters_options) {
- if (!di) {
- di = ofproto->ipfix = dpif_ipfix_create();
- }
+ if (has_options && !di) {
+ di = ofproto->ipfix = dpif_ipfix_create();
+ }
+
+ if (di) {
+ /* Call set_options in any case to cleanly flush the flow
+ * caches in the last exporters that are to be destroyed. */
dpif_ipfix_set_options(
di, bridge_exporter_options, flow_exporters_options,
n_flow_exporters_options);
- } else {
- if (di) {
+
+ if (!has_options) {
dpif_ipfix_unref(di);
ofproto->ipfix = NULL;
}
}
+
return 0;
}
facet->byte_count += miss->stats.n_bytes;
facet->prev_byte_count += miss->stats.n_bytes;
- subfacet = subfacet_create(facet, miss);
want_path = facet->xout.slow ? SF_SLOW_PATH : SF_FAST_PATH;
/* Don't install the flow if it's the result of the "userspace"
return;
}
- if (!ovs_rwlock_trywrlock(&rule->up.evict)) {
- COVERAGE_INC(ofproto_dpif_expired);
-
- /* Get rid of the rule. */
- ofproto_rule_expire(&rule->up, reason);
- }
+ COVERAGE_INC(ofproto_dpif_expired);
+ ofproto_rule_expire(&rule->up, reason);
}
\f
/* Facets. */
rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto,
const struct flow *flow, struct flow_wildcards *wc,
uint8_t table_id, struct rule_dpif **rule)
- OVS_ACQ_RDLOCK((*rule)->up.evict)
+ OVS_TRY_RDLOCK(true, (*rule)->up.evict)
{
struct cls_rule *cls_rule;
struct classifier *cls;
void
rule_release(struct rule_dpif *rule)
+ OVS_NO_THREAD_SAFETY_ANALYSIS
{
if (rule) {
ovs_rwlock_unlock(&rule->up.evict);
rule->packet_count = 0;
rule->byte_count = 0;
ovs_mutex_unlock(&rule->stats_mutex);
- complete_operation(rule);
return 0;
}
static void
-rule_destruct(struct rule *rule_)
+rule_insert(struct rule *rule_)
{
struct rule_dpif *rule = rule_dpif_cast(rule_);
complete_operation(rule);
+}
+
+static void
+rule_delete(struct rule *rule_)
+{
+ struct rule_dpif *rule = rule_dpif_cast(rule_);
+ complete_operation(rule);
+}
+
+static void
+rule_destruct(struct rule *rule_)
+{
+ struct rule_dpif *rule = rule_dpif_cast(rule_);
ovs_mutex_destroy(&rule->stats_mutex);
}
}
static void
-rule_modify_actions(struct rule *rule_)
+rule_modify_actions(struct rule *rule_, bool reset_counters)
{
struct rule_dpif *rule = rule_dpif_cast(rule_);
+ if (reset_counters) {
+ ovs_mutex_lock(&rule->stats_mutex);
+ rule->packet_count = 0;
+ rule->byte_count = 0;
+ ovs_mutex_unlock(&rule->stats_mutex);
+ }
+
complete_operation(rule);
}
\f
NULL, /* rule_choose_table */
rule_alloc,
rule_construct,
+ rule_insert,
+ rule_delete,
rule_destruct,
rule_dealloc,
rule_get_stats,