static void reinit_ports(struct ofproto *);
/* rule. */
+static void ofproto_rule_destroy(struct rule *);
static void ofproto_rule_destroy__(struct rule *);
static void ofproto_rule_send_removed(struct rule *, uint8_t reason);
static bool rule_is_modifiable(const struct rule *);
}
/* Sets number of upcall handler threads. The default is
- * (number of online cores - 1). */
+ * (number of online cores - 2). */
void
ofproto_set_n_handler_threads(unsigned limit)
{
if (limit) {
n_handler_threads = limit;
} else {
- n_handler_threads = MAX(1, sysconf(_SC_NPROCESSORS_ONLN) - 1);
+ int n_proc = sysconf(_SC_NPROCESSORS_ONLN);
+ n_handler_threads = n_proc > 2 ? n_proc - 2 : 1;
}
}
struct oftable *table = &p->tables[i];
struct eviction_group *evg;
struct cls_cursor cursor;
- struct cls_rule cr;
struct rule *rule;
if (!table->eviction_fields) {
}
ovs_rwlock_rdlock(&table->cls.rwlock);
- cls_cursor_init(&cursor, &table->cls, &cr);
+ cls_cursor_init(&cursor, &table->cls, NULL);
CLS_CURSOR_FOR_EACH (rule, cr, &cursor) {
if (!rule->eviction_group
&& (rule->idle_timeout || rule->hard_timeout)) {
}
\f
static void
-ofproto_rule_destroy__(struct rule *rule)
+ofproto_rule_destroy(struct rule *rule)
{
if (rule) {
rule->ofproto->ofproto_class->rule_destruct(rule);
- cls_rule_destroy(&rule->cr);
- free(rule->ofpacts);
- ovs_mutex_destroy(&rule->timeout_mutex);
- ovs_rwlock_destroy(&rule->rwlock);
- rule->ofproto->ofproto_class->rule_dealloc(rule);
+ ofproto_rule_destroy__(rule);
}
}
+static void
+ofproto_rule_destroy__(struct rule *rule)
+{
+ cls_rule_destroy(&rule->cr);
+ free(rule->ofpacts);
+ ovs_mutex_destroy(&rule->timeout_mutex);
+ ovs_rwlock_destroy(&rule->rwlock);
+ rule->ofproto->ofproto_class->rule_dealloc(rule);
+}
+
/* This function allows an ofproto implementation to destroy any rules that
* remain when its ->destruct() function is called.. This function implements
* steps 4.4 and 4.5 in the section titled "Rule Life Cycle" in
goto exit;
}
if (rule->flow_cookie == cookie /* Hash collisions possible. */
- && ofproto_rule_has_out_port(rule, out_port)) {
+ && ofproto_rule_has_out_port(rule, out_port)
+ && ofproto_rule_has_out_group(rule, out_group)) {
list_push_back(rules, &rule->ofproto_node);
}
}
goto exit;
}
if (rule->flow_cookie == cookie /* Hash collisions possible. */
- && ofproto_rule_has_out_port(rule, out_port)) {
+ && ofproto_rule_has_out_port(rule, out_port)
+ && ofproto_rule_has_out_group(rule, out_group)) {
list_push_back(rules, &rule->ofproto_node);
}
}
} else {
ovs_rwlock_wrlock(&rule->rwlock);
oftable_remove_rule(rule);
- ofproto_rule_destroy__(rule);
+ ofproto_rule_destroy(rule);
}
break;
case OFOPERATION_DELETE:
ovs_assert(!op->error);
- ofproto_rule_destroy__(rule);
+ ofproto_rule_destroy(rule);
op->rule = NULL;
break;