static ofp_port_t execute_hrw(const struct ofpact_bundle *bundle, const struct flow *flow, struct flow_wildcards *wc, bool (*slave_enabled)(ofp_port_t ofp_port, void *aux), void *aux) { uint32_t flow_hash, best_hash; int best, i; if (bundle->n_slaves > 1) { flow_mask_hash_fields(flow, wc, bundle->fields); } flow_hash = flow_hash_fields(flow, bundle->fields, bundle->basis); best = -1; best_hash = 0; for (i = 0; i < bundle->n_slaves; i++) { if (slave_enabled(bundle->slaves[i], aux)) { uint32_t hash = hash_2words(i, flow_hash); if (best < 0 || hash > best_hash) { best_hash = hash; best = i; } } } return best >= 0 ? bundle->slaves[best] : OFPP_NONE; }
static uint16_t algorithm_hrw(uint32_t hash, unsigned int n_links) { uint32_t best_weight; uint16_t best_link; unsigned int link; best_link = 0; best_weight = hash_2words(hash, 0); for (link = 1; link < n_links; link++) { uint32_t weight = hash_2words(hash, link); if (weight > best_weight) { best_link = link; best_weight = weight; } } return best_link; }
static uint16_t algorithm_iter_hash(uint32_t hash, unsigned int n_links, unsigned int modulo) { uint16_t link; int i; if (modulo < n_links || modulo / 2 > n_links) { modulo = round_up_pow2(n_links); } i = 0; do { link = hash_2words(hash, i++) % modulo; } while (link >= n_links); return link; }
static uint16_t execute_hrw(const struct nx_action_bundle *nab, const struct flow *flow, bool (*slave_enabled)(uint16_t ofp_port, void *aux), void *aux) { uint32_t flow_hash, best_hash; int best, i; flow_hash = flow_hash_fields(flow, ntohs(nab->fields), ntohs(nab->basis)); best = -1; best_hash = 0; for (i = 0; i < ntohs(nab->n_slaves); i++) { if (slave_enabled(bundle_get_slave(nab, i), aux)) { uint32_t hash = hash_2words(i, flow_hash); if (best < 0 || hash > best_hash) { best_hash = hash; best = i; } } } return best >= 0 ? bundle_get_slave(nab, best) : OFPP_NONE; }