struct ofproto **ofprotop)
{
const struct ofproto_class *class;
+ struct classifier *table;
struct ofproto *ofproto;
+ int n_tables;
int error;
*ofprotop = NULL;
hmap_insert(&all_ofprotos, &ofproto->hmap_node,
hash_string(ofproto->name, 0));
ofproto->datapath_id = 0;
+ ofproto_set_flow_eviction_threshold(ofproto,
+ OFPROTO_FLOW_EVICTON_THRESHOLD_DEFAULT);
ofproto->fallback_dpid = pick_fallback_dpid();
ofproto->mfr_desc = xstrdup(DEFAULT_MFR_DESC);
ofproto->hw_desc = xstrdup(DEFAULT_HW_DESC);
list_init(&ofproto->pending);
hmap_init(&ofproto->deletions);
- error = ofproto->ofproto_class->construct(ofproto);
+ error = ofproto->ofproto_class->construct(ofproto, &n_tables);
if (error) {
VLOG_ERR("failed to open datapath %s: %s",
datapath_name, strerror(error));
ofproto_destroy__(ofproto);
return error;
}
- assert(ofproto->n_tables > 0);
+
+ assert(n_tables >= 1 && n_tables <= 255);
+ ofproto->n_tables = n_tables;
+ ofproto->tables = xmalloc(n_tables * sizeof *ofproto->tables);
+ OFPROTO_FOR_EACH_TABLE (table, ofproto) {
+ classifier_init(table);
+ }
ofproto->datapath_id = pick_datapath_id(ofproto);
VLOG_INFO("using datapath ID %016"PRIx64, ofproto->datapath_id);
connmgr_set_in_band_queue(ofproto->connmgr, queue_id);
}
+/* Sets the number of flows at which eviction from the kernel flow table
+ * will occur. */
+void
+ofproto_set_flow_eviction_threshold(struct ofproto *ofproto, unsigned threshold)
+{
+ if (threshold < OFPROTO_FLOW_EVICTION_THRESHOLD_MIN) {
+ ofproto->flow_eviction_threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_MIN;
+ } else {
+ ofproto->flow_eviction_threshold = threshold;
+ }
+}
+
void
ofproto_set_desc(struct ofproto *p,
const char *mfr_desc, const char *hw_desc,
}
group = ofopgroup_create(ofproto);
- for (table = ofproto->tables; table < &ofproto->tables[ofproto->n_tables];
- table++) {
+ OFPROTO_FOR_EACH_TABLE (table, ofproto) {
struct rule *rule, *next_rule;
struct cls_cursor cursor;
static void
ofproto_destroy__(struct ofproto *ofproto)
{
- size_t i;
+ struct classifier *table;
assert(list_is_empty(&ofproto->pending));
hmap_destroy(&ofproto->ports);
shash_destroy(&ofproto->port_by_name);
- for (i = 0; i < ofproto->n_tables; i++) {
- assert(classifier_is_empty(&ofproto->tables[i]));
- classifier_destroy(&ofproto->tables[i]);
+ OFPROTO_FOR_EACH_TABLE (table, ofproto) {
+ assert(classifier_is_empty(table));
+ classifier_destroy(table);
}
free(ofproto->tables);
ofport_open(const struct ofproto_port *ofproto_port, struct ofp_phy_port *opp)
{
uint32_t curr, advertised, supported, peer;
- struct netdev_options netdev_options;
enum netdev_flags flags;
struct netdev *netdev;
int error;
- memset(&netdev_options, 0, sizeof netdev_options);
- netdev_options.name = ofproto_port->name;
- netdev_options.type = ofproto_port->type;
- netdev_options.ethertype = NETDEV_ETH_TYPE_NONE;
-
- error = netdev_open(&netdev_options, &netdev);
+ error = netdev_open(ofproto_port->name, ofproto_port->type, &netdev);
if (error) {
VLOG_WARN_RL(&rl, "ignoring port %s (%"PRIu16") because netdev %s "
"cannot be opened (%s)",
{
struct classifier *cls;
- for (cls = &p->tables[0]; cls < &p->tables[p->n_tables]; cls++) {
+ OFPROTO_FOR_EACH_TABLE (cls, p) {
struct cls_cursor cursor;
struct rule *rule;
/* Pick table. */
if (fm->table_id == 0xff) {
uint8_t table_id;
- if (ofproto->n_tables > 1) {
+ if (ofproto->ofproto_class->rule_choose_table) {
error = ofproto->ofproto_class->rule_choose_table(ofproto, &fm->cr,
&table_id);
if (error) {