struct ovs_mutex ofproto_mutex = OVS_MUTEX_INITIALIZER;
unsigned flow_eviction_threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT;
-unsigned n_handler_threads;
enum ofproto_flow_miss_model flow_miss_model = OFPROTO_HANDLE_MISS_AUTO;
+size_t n_handlers;
+
/* Map from datapath name to struct ofproto, for use by unixctl commands. */
static struct hmap all_ofprotos = HMAP_INITIALIZER(&all_ofprotos);
/* 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_)
{
- 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, 1);
+ n_handlers = n_handlers_ ? n_handlers_ : threads;
}
void
return error;
}
-int
-ofproto_type_run_fast(const char *datapath_type)
-{
- const struct ofproto_class *class;
- int error;
-
- datapath_type = ofproto_normalize_type(datapath_type);
- class = ofproto_class_find__(datapath_type);
-
- error = class->type_run_fast ? class->type_run_fast(datapath_type) : 0;
- if (error && error != EAGAIN) {
- VLOG_ERR_RL(&rl, "%s: type_run_fast failed (%s)",
- datapath_type, ovs_strerror(error));
- }
- return error;
-}
-
void
ofproto_type_wait(const char *datapath_type)
{
break;
default:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
if (time_msec() >= p->next_op_report) {
return error;
}
-/* Performs periodic activity required by 'ofproto' that needs to be done
- * with the least possible latency.
- *
- * It makes sense to call this function a couple of times per poll loop, to
- * provide a significant performance boost on some benchmarks with the
- * ofproto-dpif implementation. */
-int
-ofproto_run_fast(struct ofproto *p)
-{
- int error;
-
- error = p->ofproto_class->run_fast ? p->ofproto_class->run_fast(p) : 0;
- if (error && error != EAGAIN) {
- VLOG_ERR_RL(&rl, "%s: fastpath run failed (%s)",
- p->name, ovs_strerror(error));
- }
- return error;
-}
-
void
ofproto_wait(struct ofproto *p)
{
connmgr_get_memory_usage(ofproto->connmgr, usage);
}
+void
+ofproto_type_get_memory_usage(const char *datapath_type, struct simap *usage)
+{
+ const struct ofproto_class *class;
+
+ datapath_type = ofproto_normalize_type(datapath_type);
+ class = ofproto_class_find__(datapath_type);
+
+ if (class && class->type_get_memory_usage) {
+ class->type_get_memory_usage(datapath_type, usage);
+ }
+}
+
void
ofproto_get_ofproto_controller_info(const struct ofproto *ofproto,
struct shash *info)
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.