[ovs-dev] Stochastic group select using kernel module

Rhaban Hark rhabanhark at gmail.com
Sun Feb 15 12:58:21 UTC 2015


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



More information about the dev mailing list