sgw: fix cost calculation for advertised speeds greater or equal than MAX
[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 #define MAX_SMARTGW_SPEED 320000000
10
11 int64_t gw_costs_weigh(bool up, const struct costs_weights weights, uint32_t path_cost, uint32_t exitUk, uint32_t exitDk) {
12   int64_t costU;
13   int64_t costD;
14   int64_t costE;
15
16   if (!up) {
17     /* interface is down */
18     return INT64_MAX;
19   }
20
21   if (!weights.Detx) {
22     /* only consider path costs (classic behaviour) (but scale to 64 bit) */
23     return ((int64_t) path_cost) << SCALING_SHIFT_CLASSIC;
24   }
25
26   if (!exitUk || !exitDk) {
27     /* zero bandwidth */
28     return INT64_MAX;
29   }
30
31   if ((exitUk >= MAX_SMARTGW_SPEED) && (exitDk >= MAX_SMARTGW_SPEED)) {
32     /* maximum bandwidth: only consider path costs */
33     return path_cost;
34   }
35
36   costU = (((int64_t) (1000 * weights.WexitU))    << SCALING_SHIFT) / exitUk;
37   costD = (((int64_t) (1000 * weights.WexitD))    << SCALING_SHIFT) / exitDk;
38   costE = (((int64_t) (weights.Wetx * path_cost)) << SCALING_SHIFT) / weights.Detx;
39
40   return (costU + costD + costE);
41 }
42
43 #ifdef __cplusplus
44 }
45 #endif /* __cplusplus */