/* Global lock that protects all flow table operations. */
struct ovs_mutex ofproto_mutex = OVS_MUTEX_INITIALIZER;
-unsigned flow_eviction_threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT;
-unsigned n_handler_threads;
+unsigned ofproto_flow_limit = OFPROTO_FLOW_LIMIT_DEFAULT;
enum ofproto_flow_miss_model flow_miss_model = OFPROTO_HANDLE_MISS_AUTO;
+size_t n_handlers, n_revalidators;
+
/* Map from datapath name to struct ofproto, for use by unixctl commands. */
static struct hmap all_ofprotos = HMAP_INITIALIZER(&all_ofprotos);
/* Sets the number of flows at which eviction from the kernel flow table
* will occur. */
void
-ofproto_set_flow_eviction_threshold(unsigned threshold)
+ofproto_set_flow_limit(unsigned limit)
{
- flow_eviction_threshold = MAX(OFPROTO_FLOW_EVICTION_THRESHOLD_MIN,
- threshold);
+ ofproto_flow_limit = limit;
}
/* Sets the path for handling flow misses. */
}
}
-/* Sets number of upcall handler threads. The default is
- * (number of online cores - 2). */
void
-ofproto_set_n_handler_threads(unsigned limit)
+ofproto_set_threads(size_t n_handlers_, size_t n_revalidators_)
{
- if (limit) {
- n_handler_threads = limit;
- } else {
- int n_proc = count_cpu_cores();
- n_handler_threads = n_proc > 2 ? n_proc - 2 : 1;
+ int threads = MAX(count_cpu_cores(), 2);
+
+ n_revalidators = n_revalidators_;
+ n_handlers = n_handlers_;
+
+ if (!n_revalidators) {
+ n_revalidators = n_handlers
+ ? MAX(threads - (int) n_handlers, 1)
+ : threads / 4 + 1;
+ }
+
+ if (!n_handlers) {
+ n_handlers = MAX(threads - (int) n_revalidators, 1);
}
}
break;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
if (time_msec() >= p->next_op_report) {
op->actions->ofpacts_len, out_port);
}
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
static void
* actions, so that when the operation commits we report the change. */
switch (op->type) {
case OFOPERATION_ADD:
- NOT_REACHED();
+ OVS_NOT_REACHED();
case OFOPERATION_MODIFY:
case OFOPERATION_REPLACE:
break;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
}
fu.ofpacts = actions ? actions->ofpacts : NULL;
}
}
+static enum ofperr
+table_mod(struct ofproto *ofproto, const struct ofputil_table_mod *tm)
+{
+ /* XXX Reject all configurations because none are currently supported */
+ return OFPERR_OFPTMFC_BAD_CONFIG;
+
+ if (tm->table_id == OFPTT_ALL) {
+ int i;
+ for (i = 0; i < ofproto->n_tables; i++) {
+ atomic_store(&ofproto->tables[i].config,
+ (unsigned int)tm->config);
+ }
+ } else if (!check_table_id(ofproto, tm->table_id)) {
+ return OFPERR_OFPTMFC_BAD_TABLE;
+ } else {
+ atomic_store(&ofproto->tables[tm->table_id].config,
+ (unsigned int)tm->config);
+ }
+
+ return 0;
+}
+
static enum ofperr
handle_table_mod(struct ofconn *ofconn, const struct ofp_header *oh)
{
+ struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
struct ofputil_table_mod tm;
enum ofperr error;
return error;
}
- /* XXX Actual table mod support is not implemented yet. */
- return 0;
+ return table_mod(ofproto, &tm);
}
static enum ofperr
break;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
ofmonitor_report(ofproto->connmgr, rule, event_type,
break;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
ofoperation_destroy(op);
memset(table, 0, sizeof *table);
classifier_init(&table->cls, flow_segment_u32s);
table->max_flows = UINT_MAX;
+ atomic_init(&table->config, (unsigned int)OFPTC11_TABLE_MISS_CONTROLLER);
}
/* Destroys 'table', including its classifier and eviction groups.