7a4ebf90005aeccfeb86576f97f51bf904606206
[olsrd.git] / src / gateway_costs.c
1 #include "gateway_costs.h"
2
3 #ifdef __cplusplus
4 extern "C" {
5 #endif /* __cplusplus */
6
7 #define SCALING_SHIFT_CLASSIC 31
8 #define SCALING_SHIFT 23
9
10 int64_t gw_costs_weigh(bool up, const struct costs_weights weights, uint32_t path_cost, uint32_t exitUk, uint32_t exitDk) {
11   int64_t costU;
12   int64_t costD;
13   int64_t costE;
14
15   if (!up) {
16     /* interface is down */
17     return INT64_MAX;
18   }
19
20   if (!weights.Detx) {
21     /* only consider path costs (classic behaviour) (but scale to 64 bit) */
22     return ((int64_t) path_cost) << SCALING_SHIFT_CLASSIC;
23   }
24
25   if (!exitUk || !exitDk) {
26     /* zero bandwidth */
27     return INT64_MAX;
28   }
29
30   if ((exitUk == UINT32_MAX) && (exitDk == UINT32_MAX)) {
31     /* maximum bandwidth: only consider path costs */
32     return path_cost;
33   }
34
35   costU = (((int64_t) (1000 * weights.WexitU))    << SCALING_SHIFT) / exitUk;
36   costD = (((int64_t) (1000 * weights.WexitD))    << SCALING_SHIFT) / exitDk;
37   costE = (((int64_t) (weights.Wetx * path_cost)) << SCALING_SHIFT) / weights.Detx;
38
39   return (costU + costD + costE);
40 }
41
42 #ifdef __cplusplus
43 }
44 #endif /* __cplusplus */