Hi,

we want to achieve round-robin over different action-buckets in a group table. Since we expect packets with identical headers (same ip & mac address), the current implementation is not sufficient. As far as i know ovs is using the hashed mac address to determine the selected bucket.

Based on https://github.com/saeenali/openvswitch/wiki/Stochastic-Switching-using-Open-vSwitch-in-Mininet (which seems to work only with a fixed total bucket-weight of 10), i've changed ofproto/ofproto-dpif-xlate.c to achieve this more generic, which works great. In fact we're not making round-robin, rather it randomly selects an output bucket considering their weights.

However, we have to tell ovs to always use slow-path (ctx->xout->slow |= SLOW_CONTROLLER). Is there a chance to randomly select the output bucket in the kernel module while the packet headers are always identically or does this conflict with the idea of the kernel module which basically forwards corresponding to the packet headers?


ofproto/ofproto-dpif-xlate.c

18a19,21
> #include <stdlib.h>
> #include <time.h>
>
326a330,331
> static bool is_srand_initialized = false;
>
903,904c908
<                        const struct group_dpif *group,
<                        uint32_t basis)
---
>                        const struct group_dpif *group)
906,908c910,914
<     const struct ofputil_bucket *best_bucket = NULL;
<     uint32_t best_score = 0;
<     int i = 0;
---
>     // initialize random seed
>     if (!is_srand_initialized) {
>         srand(time(NULL));
>         is_srand_initialized = true;
>     }
912a919,920
>     uint32_t total_weights = 0;
>
916,920c924,937
< uint32_t score = (hash_int(i, basis) & 0xffff) * bucket->weight;
<             if (score >= best_score) {
<                 best_bucket = bucket;
<                 best_score = score;
<             }
---
>             total_weights += bucket->weight;
>         }
>     }
>
>     float rand_num = (float)(rand() % 101) / 100;
>     uint32_t chosen_value = (uint32_t)(rand_num * (float)total_weights);
>
>     total_weights = 0;
>     LIST_FOR_EACH (bucket, list_node, buckets) {
>         if (bucket_is_alive(ctx, bucket, 0)) {
> if(chosen_value >= total_weights && chosen_value < (total_weights + bucket->weight)){
>                 return bucket;
>             }
>             total_weights += bucket->weight;
922d938
<         i++;
925c941
<     return best_bucket;
---
>     return NULL;
2171d2186
<     uint32_t basis;
2173,2174c2188,2192
<     basis = hash_mac(ctx->xin->flow.dl_dst, 0, 0);
<     bucket = group_best_live_bucket(ctx, group, basis);
---
>     // The following tells the caching code that every packet in
>     // the flow in question must go to the userspace "slow path".
>     ctx->xout->slow |= SLOW_CONTROLLER;
>
>     bucket = group_best_live_bucket(ctx, group);
3124c3142
<
---
>

Thanks in advance,
Rhaban Hark
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to