Signed-off-by: Simon Horman <ho...@verge.net.au> ---
v8 * First post --- ofproto/ofproto-dpif-xlate.c | 24 ++++++++++++++++++------ ofproto/ofproto.c | 3 ++- tests/ofproto-dpif.at | 12 ++++++++++++ tests/ofproto.at | 2 +- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 8665dab..85c4ccf 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -795,20 +795,24 @@ group_first_live_bucket(const struct xlate_ctx *ctx, return NULL; } -static void +static unsigned group_all_live_buckets(const struct xlate_ctx *ctx, const struct group_dpif *group, struct ofpbuf *live_buckets) { struct ofputil_bucket *bucket; const struct list *buckets; + unsigned weight = 0; group_dpif_get_buckets(group, &buckets); LIST_FOR_EACH (bucket, list_node, buckets) { if (bucket_is_alive(ctx, bucket, 0)) { ofpbuf_push(live_buckets, &bucket, sizeof bucket); + weight += bucket->weight; } } + + return weight; } static bool @@ -1936,19 +1940,27 @@ xlate_select_group(struct xlate_ctx *ctx, struct group_dpif *group) struct ofputil_bucket *stub[1024 / sizeof *bucket]; struct ofpbuf live_buckets; uint32_t hash; + unsigned weight; + size_t offset; ofpbuf_use_stub(&live_buckets, stub, sizeof stub); - group_all_live_buckets(ctx, group, &live_buckets); - if (live_buckets.size == 0) { + weight = group_all_live_buckets(ctx, group, &live_buckets); + if (weight == 0) { goto out; } memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst); hash = hash_bytes(ctx->xin->flow.dl_dst, sizeof ctx->xin->flow.dl_dst, 0); - bucket = ofpbuf_at_assert(&live_buckets, - (hash % (live_buckets.size / sizeof *bucket)) * - sizeof *bucket, sizeof *bucket); + weight = hash % weight; + + for (offset = 0; offset < live_buckets.size; offset += sizeof *bucket) { + bucket = ofpbuf_at_assert(&live_buckets, offset, sizeof *bucket); + if (weight < (*bucket)->weight) { + break; + } + weight -= (*bucket)->weight; + } xlate_group_bucket(ctx, *bucket); out: diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index ecce2e9..7a9e853 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -528,7 +528,8 @@ 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; diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 7ebad78..616da93 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -137,6 +137,18 @@ AT_CHECK([tail -1 stdout], [0], OVS_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([ofproto-dpif - select group with weight]) +OVS_VSWITCHD_START +ADD_OF_PORTS([br0], [1], [10], [11], [12]) +AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=select,bucket=output:10,bucket=output:11,weight=2,bucket=output:12,weight=0']) +AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=write_actions(group:1234)']) +AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:07,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout]) +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: 11 +]) +OVS_VSWITCHD_STOP +AT_CLEANUP + AT_SETUP([ofproto-dpif - fast failover group]) OVS_VSWITCHD_START ADD_OF_PORTS([br0], [1], [10], [11]) diff --git a/tests/ofproto.at b/tests/ofproto.at index c3a086d..1fb6c81 100644 --- a/tests/ofproto.at +++ b/tests/ofproto.at @@ -306,7 +306,7 @@ AT_CHECK([STRIP_XIDS stdout], [0], [dnl OFPST_GROUP_FEATURES reply (OF1.2): Group table: Types: 0x0 - Capabilities: 0x6 + Capabilities: 0x7 ]) OVS_VSWITCHD_STOP AT_CLEANUP -- 1.8.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev