X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=424d2ced2c2b88be9043380d2dfc64315cdfeb4d;hb=390eadaa790e7442d1738933937150c49e96d3d4;hp=34b06425b70bcea0fe33c0d1ea1bb3238e77d934;hpb=fe7e574970ae0ba1b8515a329c9ce88f22365b95;p=sliver-openvswitch.git diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 34b06425b..424d2ced2 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -531,15 +531,30 @@ ofproto_create(const char *datapath_name, const char *datapath_type, ovs_rwlock_init(&ofproto->groups_rwlock); hmap_init(&ofproto->groups); ovs_mutex_unlock(&ofproto_mutex); - ofproto->ogf.capabilities = OFPGFC_CHAINING | OFPGFC_SELECT_LIVENESS; + ofproto->ogf.capabilities = OFPGFC_CHAINING | OFPGFC_SELECT_LIVENESS | + OFPGFC_SELECT_WEIGHT; ofproto->ogf.max_groups[OFPGT11_ALL] = OFPG_MAX; ofproto->ogf.max_groups[OFPGT11_SELECT] = OFPG_MAX; ofproto->ogf.max_groups[OFPGT11_INDIRECT] = OFPG_MAX; ofproto->ogf.max_groups[OFPGT11_FF] = OFPG_MAX; ofproto->ogf.actions[0] = -#define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) (1 << ENUM) | -#include "ofp-util.def" - 0; + (1 << OFPAT11_OUTPUT) | + (1 << OFPAT11_COPY_TTL_OUT) | + (1 << OFPAT11_COPY_TTL_IN) | + (1 << OFPAT11_SET_MPLS_TTL) | + (1 << OFPAT11_DEC_MPLS_TTL) | + (1 << OFPAT11_PUSH_VLAN) | + (1 << OFPAT11_POP_VLAN) | + (1 << OFPAT11_PUSH_MPLS) | + (1 << OFPAT11_POP_MPLS) | + (1 << OFPAT11_SET_QUEUE) | + (1 << OFPAT11_GROUP) | + (1 << OFPAT11_SET_NW_TTL) | + (1 << OFPAT11_DEC_NW_TTL) | + (1 << OFPAT12_SET_FIELD); +/* not supported: + * (1 << OFPAT13_PUSH_PBB) | + * (1 << OFPAT13_POP_PBB) */ error = ofproto->ofproto_class->construct(ofproto); if (error) { @@ -723,7 +738,7 @@ ofproto_set_n_handler_threads(unsigned limit) if (limit) { n_handler_threads = limit; } else { - int n_proc = sysconf(_SC_NPROCESSORS_ONLN); + int n_proc = count_cpu_cores(); n_handler_threads = n_proc > 2 ? n_proc - 2 : 1; } } @@ -869,6 +884,27 @@ ofproto_port_get_stp_status(struct ofproto *ofproto, ofp_port_t ofp_port, ? ofproto->ofproto_class->get_stp_port_status(ofport, s) : EOPNOTSUPP); } + +/* Retrieves STP port statistics of 'ofp_port' on 'ofproto' and stores it in + * 's'. If the 'enabled' member in 's' is false, then the other members + * are not meaningful. + * + * Returns 0 if successful, otherwise a positive errno value.*/ +int +ofproto_port_get_stp_stats(struct ofproto *ofproto, ofp_port_t ofp_port, + struct ofproto_port_stp_stats *s) +{ + struct ofport *ofport = ofproto_get_port(ofproto, ofp_port); + if (!ofport) { + VLOG_WARN_RL(&rl, "%s: cannot get STP stats on nonexistent " + "port %"PRIu16, ofproto->name, ofp_port); + return ENODEV; + } + + return (ofproto->ofproto_class->get_stp_port_stats + ? ofproto->ofproto_class->get_stp_port_stats(ofport, s) + : EOPNOTSUPP); +} /* Queue DSCP configuration. */ @@ -1123,7 +1159,7 @@ ofproto_configure_table(struct ofproto *ofproto, int table_id, } table->max_flows = s->max_flows; - ovs_rwlock_rdlock(&table->cls.rwlock); + ovs_rwlock_wrlock(&table->cls.rwlock); if (classifier_count(&table->cls) > table->max_flows && table->eviction_fields) { /* 'table' contains more flows than allowed. We might not be able to @@ -1139,6 +1175,10 @@ ofproto_configure_table(struct ofproto *ofproto, int table_id, break; } } + + classifier_set_prefix_fields(&table->cls, + s->prefix_fields, s->n_prefix_fields); + ovs_rwlock_unlock(&table->cls.rwlock); } @@ -1757,12 +1797,18 @@ ofproto_port_add(struct ofproto *ofproto, struct netdev *netdev, update_port(ofproto, netdev_name); } if (ofp_portp) { - struct ofproto_port ofproto_port; - - ofproto_port_query_by_name(ofproto, netdev_get_name(netdev), - &ofproto_port); - *ofp_portp = error ? OFPP_NONE : ofproto_port.ofp_port; - ofproto_port_destroy(&ofproto_port); + *ofp_portp = OFPP_NONE; + if (!error) { + struct ofproto_port ofproto_port; + + error = ofproto_port_query_by_name(ofproto, + netdev_get_name(netdev), + &ofproto_port); + if (!error) { + *ofp_portp = ofproto_port.ofp_port; + ofproto_port_destroy(&ofproto_port); + } + } } return error; } @@ -1989,9 +2035,13 @@ alloc_ofp_port(struct ofproto *ofproto, const char *netdev_name) /* Search for a free OpenFlow port number. We try not to * immediately reuse them to prevent problems due to old - * flows. */ + * flows. + * + * We limit the automatically assigned port numbers to the lower half + * of the port range, to reserve the upper half for assignment by + * controllers. */ for (;;) { - if (++ofproto->alloc_port_no >= ofproto->max_ports) { + if (++ofproto->alloc_port_no >= MIN(ofproto->max_ports, 32768)) { ofproto->alloc_port_no = 1; } last_used_at = ofport_get_usage(ofproto, @@ -3036,7 +3086,7 @@ handle_table_stats_request(struct ofconn *ofconn, ots = xcalloc(p->n_tables, sizeof *ots); for (i = 0; i < p->n_tables; i++) { ots[i].table_id = i; - sprintf(ots[i].name, "table%zu", i); + sprintf(ots[i].name, "table%"PRIuSIZE, i); ots[i].match = htonll(OFPXMT13_MASK); ots[i].wildcards = htonll(OFPXMT13_MASK); ots[i].write_actions = htonl(OFPAT11_OUTPUT); @@ -6599,7 +6649,7 @@ static void oftable_init(struct oftable *table) { memset(table, 0, sizeof *table); - classifier_init(&table->cls); + classifier_init(&table->cls, flow_segment_u32s); table->max_flows = UINT_MAX; }