X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=2dd3c9f71287d0380b41fd3dd48fe48c89acedc9;hb=b772ded808ccc1b3cce2c10377a35637b1beb28c;hp=64adef669b11693c55b3434e717f4b65b0cd9a37;hpb=8f93e93c807d3acd06fb3b367276f574164b1a9c;p=sliver-openvswitch.git diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 64adef669..2dd3c9f71 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -33,13 +33,13 @@ #include "ofp-print.h" #include "ofp-util.h" #include "ofpbuf.h" +#include "ofproto-provider.h" #include "openflow/nicira-ext.h" #include "openflow/openflow.h" #include "packets.h" #include "pinsched.h" #include "pktbuf.h" #include "poll-loop.h" -#include "private.h" #include "shash.h" #include "sset.h" #include "timeval.h" @@ -289,7 +289,9 @@ ofproto_create(const char *datapath_name, const char *datapath_type, struct ofproto **ofprotop) { const struct ofproto_class *class; + struct classifier *table; struct ofproto *ofproto; + int n_tables; int error; *ofprotop = NULL; @@ -320,6 +322,8 @@ ofproto_create(const char *datapath_name, const char *datapath_type, 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); @@ -335,14 +339,20 @@ ofproto_create(const char *datapath_name, const char *datapath_type, 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); @@ -407,6 +417,18 @@ ofproto_set_in_band_queue(struct ofproto *ofproto, int queue_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, @@ -653,8 +675,7 @@ ofproto_flush__(struct ofproto *ofproto) } 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; @@ -673,7 +694,7 @@ ofproto_flush__(struct ofproto *ofproto) static void ofproto_destroy__(struct ofproto *ofproto) { - size_t i; + struct classifier *table; assert(list_is_empty(&ofproto->pending)); @@ -690,9 +711,9 @@ ofproto_destroy__(struct ofproto *ofproto) 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); @@ -845,16 +866,7 @@ ofproto_get_ofproto_controller_info(const struct ofproto *ofproto, void ofproto_free_ofproto_controller_info(struct shash *info) { - struct shash_node *node; - - SHASH_FOR_EACH (node, info) { - struct ofproto_controller_info *cinfo = node->data; - while (cinfo->pairs.n) { - free((char *) cinfo->pairs.values[--cinfo->pairs.n]); - } - free(cinfo); - } - shash_destroy(info); + connmgr_free_controller_info(info); } /* Makes a deep copy of 'old' into 'port'. */ @@ -1102,17 +1114,11 @@ static struct netdev * 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)", @@ -1378,8 +1384,8 @@ ofproto_rule_destroy__(struct rule *rule) /* This function allows an ofproto implementation to destroy any rules that * remain when its ->destruct() function is called. The caller must have * already uninitialized any derived members of 'rule' (step 5 described in the - * large comment in ofproto/private.h titled "Life Cycle"). This function - * implements steps 6 and 7. + * large comment in ofproto/ofproto-provider.h titled "Life Cycle"). + * This function implements steps 6 and 7. * * This function should only be called from an ofproto implementation's * ->destruct() function. It is not suitable elsewhere. */ @@ -1398,13 +1404,12 @@ static bool rule_has_out_port(const struct rule *rule, uint16_t out_port) { const union ofp_action *oa; - struct actions_iterator i; + size_t left; if (out_port == OFPP_NONE) { return true; } - for (oa = actions_first(&i, rule->actions, rule->n_actions); oa; - oa = actions_next(&i)) { + OFPUTIL_ACTION_FOR_EACH_UNSAFE (oa, left, rule->actions, rule->n_actions) { if (action_outputs_to_port(oa, htons(out_port))) { return true; } @@ -1921,7 +1926,6 @@ static void flow_stats_ds(struct rule *rule, struct ds *results) { uint64_t packet_count, byte_count; - size_t act_len = sizeof *rule->actions * rule->n_actions; rule->ofproto->ofproto_class->rule_get_stats(rule, &packet_count, &byte_count); @@ -1936,8 +1940,8 @@ flow_stats_ds(struct rule *rule, struct ds *results) ds_put_format(results, "n_bytes=%"PRIu64", ", byte_count); cls_rule_format(&rule->cr, results); ds_put_char(results, ','); - if (act_len > 0) { - ofp_print_actions(results, &rule->actions->header, act_len); + if (rule->n_actions > 0) { + ofp_print_actions(results, rule->actions, rule->n_actions); } else { ds_put_cstr(results, "drop"); } @@ -1951,7 +1955,7 @@ ofproto_get_all_flows(struct ofproto *p, struct ds *results) { 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; @@ -2177,7 +2181,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, struct flow_mod *fm, /* 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) { @@ -2811,8 +2815,8 @@ ofoperation_destroy(struct ofoperation *op) * If 'op' is a "delete flow" operation, 'error' must be 0. That is, flow * deletions are not allowed to fail. * - * Please see the large comment in ofproto/private.h titled "Asynchronous - * Operation Support" for more information. */ + * Please see the large comment in ofproto/ofproto-provider.h titled + * "Asynchronous Operation Support" for more information. */ void ofoperation_complete(struct ofoperation *op, int error) {