Signed-off-by: Simon Horman <[email protected]>
---
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
[email protected]
http://openvswitch.org/mailman/listinfo/dev