gateway: formatting
authorFerry Huberts <ferry.huberts@pelagic.nl>
Wed, 22 Aug 2012 11:15:20 +0000 (13:15 +0200)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Fri, 24 Aug 2012 08:50:02 +0000 (10:50 +0200)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
Reviewed-by: Henning Rogge <henning.rogge@fkie.fraunhofer.de>
src/gateway.c
src/gateway.h
src/gateway_default_handler.c

index c233bba..1e57ae6 100644 (file)
@@ -68,8 +68,7 @@ static bool v6gw_choosen_external;
  * @param value the encoded 1 byte transport value
  * @return the uplink/downlink speed value (in kbit/s)
  */
-static uint32_t
-deserialize_gw_speed(uint8_t value) {
+static uint32_t deserialize_gw_speed(uint8_t value) {
   uint32_t speed;
   uint32_t exp;
 
@@ -79,7 +78,7 @@ deserialize_gw_speed(uint8_t value) {
     return 0;
   }
 
-  speed = (value >> 3)+1;
+  speed = (value >> 3) + 1;
   exp = value & 7;
 
   while (exp-- > 0) {
@@ -95,8 +94,7 @@ deserialize_gw_speed(uint8_t value) {
  * @param speed the uplink/downlink speed value (in kbit/s)
  * @return value the encoded 1 byte transport value
  */
-static uint8_t
-serialize_gw_speed(uint32_t speed) {
+static uint8_t serialize_gw_speed(uint32_t speed) {
   uint8_t exp = 0;
 
   if (speed == 0) {
@@ -109,9 +107,9 @@ serialize_gw_speed(uint32_t speed) {
 
   while ((speed > 32 || (speed % 10) == 0) && exp < 7) {
     speed /= 10;
-    exp ++;
+    exp++;
   }
-  return ((speed-1) << 3) | exp;
+  return ((speed - 1) << 3) | exp;
 }
 
 /**
@@ -122,9 +120,8 @@ serialize_gw_speed(uint32_t speed) {
  * @param ifh the interface
  * @param flag interface change flags
  */
-static void smartgw_tunnel_monitor (int if_index __attribute__ ((unused)),
-    struct interface *ifh __attribute__ ((unused)),
-    enum olsr_ifchg_flag flag __attribute__ ((unused))) {
+static void smartgw_tunnel_monitor(int if_index __attribute__ ((unused)),
+    struct interface *ifh __attribute__ ((unused)), enum olsr_ifchg_flag flag __attribute__ ((unused))) {
   return;
 }
 
@@ -135,8 +132,7 @@ static void smartgw_tunnel_monitor (int if_index __attribute__ ((unused)),
  * @param ipv6 trigger a ipv6 gateway lookup
  * @return 0 if successful, -1 otherwise
  */
-static int
-olsr_trigger_inetgw_selection(bool ipv4, bool ipv6) {
+static int olsr_trigger_inetgw_selection(bool ipv4, bool ipv6) {
   gw_handler->select_gateway(ipv4, ipv6);
   return ((ipv4 && current_ipv4_gw == NULL) || (ipv6 && current_ipv6_gw == NULL)) ? -1 : 0;
 }
@@ -177,8 +173,7 @@ static void cleanup_gateway_handler(void *ptr) {
 /**
  * Initialize gateway system
  */
-int
-olsr_init_gateways(void) {
+int olsr_init_gateways(void) {
   gw_mem_cookie = olsr_alloc_cookie("Gateway cookie", OLSR_COOKIE_TYPE_MEMORY);
   olsr_cookie_set_memory_size(gw_mem_cookie, sizeof(struct gateway_entry));
 
@@ -231,34 +226,34 @@ void olsr_cleanup_gateways(void) {
 /**
  * Triggers the first lookup of a gateway.
  */
-void
-olsr_trigger_inetgw_startup(void) {
+void olsr_trigger_inetgw_startup(void) {
   gw_handler->handle_startup();
 }
 
 /**
  * Print debug information about gateway entries
  */
-void
-olsr_print_gateway_entries(void) {
+void olsr_print_gateway_entries(void) {
 #ifndef NODEBUG
   struct ipaddr_str buf;
   struct gateway_entry *gw;
   const int addrsize = olsr_cnf->ip_version == AF_INET ? 15 : 39;
 
-  OLSR_PRINTF(0, "\n--- %s ---------------------------------------------------- GATEWAYS\n\n",
-      olsr_wallclock_string());
-  OLSR_PRINTF(0, "%-*s %-6s %-9s %-9s %s\n", addrsize, "IP address", "Type", "Uplink", "Downlink",
-      olsr_cnf->ip_version == AF_INET ? "" : "External Prefix");
+  OLSR_PRINTF(0, "\n--- %s ---------------------------------------------------- GATEWAYS\n\n", olsr_wallclock_string());
+  OLSR_PRINTF(0, "%-*s %-6s %-9s %-9s %s\n",
+      addrsize, "IP address", "Type", "Uplink", "Downlink", olsr_cnf->ip_version == AF_INET ? "" : "External Prefix");
 
   OLSR_FOR_ALL_GATEWAY_ENTRIES(gw) {
-    OLSR_PRINTF(0, "%-*s %s%c%s%c%c %-9u %-9u %s\n", addrsize, olsr_ip_to_string(&buf, &gw->originator),
+    OLSR_PRINTF(0, "%-*s %s%c%s%c%c %-9u %-9u %s\n",
+        addrsize,
+        olsr_ip_to_string(&buf, &gw->originator),
         gw->ipv4nat ? "" : "   ",
         gw->ipv4 ? '4' : ' ',
         gw->ipv4nat ? "(N)" : "",
         (gw->ipv4 && gw->ipv6) ? ',' : ' ',
         gw->ipv6 ? '6' : ' ',
-        gw->uplink, gw->downlink,
+        gw->uplink,
+        gw->downlink,
         gw->external_prefix.prefix_len == 0 ? "" : olsr_ip_prefix_to_string(&gw->external_prefix));
   } OLSR_FOR_ALL_GATEWAY_ENTRIES_END(gw)
 #endif
@@ -274,11 +269,10 @@ olsr_print_gateway_entries(void) {
  * @param mask pointer to netmask of the HNA
  * @param prefixlen of the HNA
  */
-void
-olsr_modifiy_inetgw_netmask(union olsr_ip_addr *mask, int prefixlen) {
+void olsr_modifiy_inetgw_netmask(union olsr_ip_addr *mask, int prefixlen) {
   uint8_t *ptr = OLSR_IP_ADDR_2_HNA_PTR(mask, prefixlen);
 
-  memcpy(ptr, &smart_gateway_netmask, sizeof(smart_gateway_netmask) - prefixlen/8);
+  memcpy(ptr, &smart_gateway_netmask, sizeof(smart_gateway_netmask) - prefixlen / 8);
   if (olsr_cnf->has_ipv4_gateway) {
     ptr[GW_HNA_FLAGS] |= GW_HNA_FLAG_IPV4;
 
@@ -289,7 +283,7 @@ olsr_modifiy_inetgw_netmask(union olsr_ip_addr *mask, int prefixlen) {
   if (olsr_cnf->has_ipv6_gateway) {
     ptr[GW_HNA_FLAGS] |= GW_HNA_FLAG_IPV6;
   }
-  if (!olsr_cnf->has_ipv6_gateway || prefixlen != ipv6_internet_route.prefix_len){
+  if (!olsr_cnf->has_ipv6_gateway || prefixlen != ipv6_internet_route.prefix_len) {
     ptr[GW_HNA_FLAGS] &= ~GW_HNA_FLAG_IPV6PREFIX;
   }
 }
@@ -333,8 +327,7 @@ void refresh_smartgw_netmask(void) {
  * @param mask
  * @return true if is a valid smart gateway HNA, false otherwise
  */
-bool
-olsr_is_smart_gateway(struct olsr_ip_prefix *prefix, union olsr_ip_addr *mask) {
+bool olsr_is_smart_gateway(struct olsr_ip_prefix *prefix, union olsr_ip_addr *mask) {
   uint8_t *ptr;
 
   if (!is_prefix_inetgw(prefix)) {
@@ -353,8 +346,7 @@ olsr_is_smart_gateway(struct olsr_ip_prefix *prefix, union olsr_ip_addr *mask) {
  * @param prefixlen of the HNA
  * @param seqno the sequence number of the HNA
  */
-void
-olsr_update_gateway_entry(union olsr_ip_addr *originator, union olsr_ip_addr *mask, int prefixlen, uint16_t seqno) {
+void olsr_update_gateway_entry(union olsr_ip_addr *originator, union olsr_ip_addr *mask, int prefixlen, uint16_t seqno) {
   struct gateway_entry *gw = olsr_find_gateway_entry(originator);
   uint8_t *ptr = OLSR_IP_ADDR_2_HNA_PTR(mask, prefixlen);
 
@@ -364,8 +356,7 @@ olsr_update_gateway_entry(union olsr_ip_addr *originator, union olsr_ip_addr *ma
     gw->node.key = &gw->originator;
 
     avl_insert(&gateway_tree, &gw->node, AVL_DUP_NO);
-  }
-  else if (olsr_seqno_diff(seqno, gw->seqno) <= 0) {
+  } else if (olsr_seqno_diff(seqno, gw->seqno) <= 0) {
     /* ignore older HNAs */
     return;
   }
@@ -376,8 +367,7 @@ olsr_update_gateway_entry(union olsr_ip_addr *originator, union olsr_ip_addr *ma
   if ((ptr[GW_HNA_FLAGS] & GW_HNA_FLAG_LINKSPEED) != 0) {
     gw->uplink = deserialize_gw_speed(ptr[GW_HNA_UPLINK]);
     gw->downlink = deserialize_gw_speed(ptr[GW_HNA_DOWNLINK]);
-  }
-  else {
+  } else {
     gw->uplink = 0;
     gw->downlink = 0;
   }
@@ -419,8 +409,7 @@ olsr_update_gateway_entry(union olsr_ip_addr *originator, union olsr_ip_addr *ma
  * @param originator
  * @param prefixlen
  */
-void
-olsr_delete_gateway_entry(union olsr_ip_addr *originator, uint8_t prefixlen) {
+void olsr_delete_gateway_entry(union olsr_ip_addr *originator, uint8_t prefixlen) {
   struct gateway_entry *gw = olsr_find_gateway_entry(originator);
   bool change = false;
 
@@ -431,12 +420,10 @@ olsr_delete_gateway_entry(union olsr_ip_addr *originator, uint8_t prefixlen) {
       change = gw->ipv4;
       gw->ipv4 = false;
       gw->ipv4nat = false;
-    }
-    else if (olsr_cnf->ip_version == AF_INET6 && prefixlen == ipv6_internet_route.prefix_len) {
+    } else if (olsr_cnf->ip_version == AF_INET6 && prefixlen == ipv6_internet_route.prefix_len) {
       change = gw->ipv6;
       gw->ipv6 = false;
-    }
-    else if (olsr_cnf->ip_version == AF_INET6 && prefixlen == ipv6_mappedv4_route.prefix_len) {
+    } else if (olsr_cnf->ip_version == AF_INET6 && prefixlen == ipv6_mappedv4_route.prefix_len) {
       change = gw->ipv4;
       gw->ipv4 = false;
       gw->ipv4nat = false;
@@ -469,8 +456,7 @@ olsr_delete_gateway_entry(union olsr_ip_addr *originator, uint8_t prefixlen) {
 
       /* remove gateway entry on a delayed schedule */
       olsr_set_timer(&gw->cleanup_timer, GW_CLEANUP_INTERVAL, 0, false, cleanup_gateway_handler, gw, NULL);
-    }
-    else if (change) {
+    } else if (change) {
       gw_handler->handle_update_gw(gw);
     }
   }
@@ -485,12 +471,12 @@ void olsr_trigger_gatewayloss_check(void) {
   bool ipv6 = false;
 
   if (current_ipv4_gw) {
-       struct tc_entry *tc = olsr_lookup_tc_entry(&current_ipv4_gw->originator);
-       ipv4 = (tc == NULL || tc->path_cost == ROUTE_COST_BROKEN);
+    struct tc_entry *tc = olsr_lookup_tc_entry(&current_ipv4_gw->originator);
+    ipv4 = (tc == NULL || tc->path_cost == ROUTE_COST_BROKEN);
   }
   if (current_ipv6_gw) {
-       struct tc_entry *tc = olsr_lookup_tc_entry(&current_ipv6_gw->originator);
-       ipv6 = (tc == NULL || tc->path_cost == ROUTE_COST_BROKEN);
+    struct tc_entry *tc = olsr_lookup_tc_entry(&current_ipv6_gw->originator);
+    ipv6 = (tc == NULL || tc->path_cost == ROUTE_COST_BROKEN);
   }
 
   if (ipv4 || ipv6) {
@@ -509,8 +495,7 @@ void olsr_trigger_gatewayloss_check(void) {
  *
  * @param h pointer to gateway handler struct
  */
-void
-olsr_set_inetgw_handler(struct olsr_gw_handler *h) {
+void olsr_set_inetgw_handler(struct olsr_gw_handler *h) {
   assert(h);
   gw_handler = h;
 }
@@ -525,8 +510,7 @@ olsr_set_inetgw_handler(struct olsr_gw_handler *h) {
  *   false if triggered by automatic lookup.
  * @return true if an error happened, false otherwise
  */
-bool
-olsr_set_inet_gateway(union olsr_ip_addr *originator, bool ipv4, bool ipv6, bool external) {
+bool olsr_set_inet_gateway(union olsr_ip_addr *originator, bool ipv4, bool ipv6, bool external) {
   struct gateway_entry *entry;
   struct gateway_entry *oldV4 = current_ipv4_gw;
   struct gateway_entry *oldV6 = current_ipv6_gw;
@@ -545,8 +529,7 @@ olsr_set_inet_gateway(union olsr_ip_addr *originator, bool ipv4, bool ipv6, bool
 
   entry = olsr_find_gateway_entry(originator);
   if (entry != NULL) {
-    if (ipv4 && entry != current_ipv4_gw && entry->ipv4
-        && (!entry->ipv4nat || olsr_cnf->smart_gw_allow_nat)) {
+    if (ipv4 && entry != current_ipv4_gw && entry->ipv4 && (!entry->ipv4nat || olsr_cnf->smart_gw_allow_nat)) {
       /* valid ipv4 gateway */
       current_ipv4_gw = entry;
     }
@@ -561,8 +544,7 @@ olsr_set_inet_gateway(union olsr_ip_addr *originator, bool ipv4, bool ipv6, bool
     if ((v4gw_tunnel = olsr_os_add_ipip_tunnel(&current_ipv4_gw->originator, true)) != NULL) {
       olsr_os_inetgw_tunnel_route(v4gw_tunnel->if_index, true, true);
       v4gw_choosen_external = external;
-    }
-    else {
+    } else {
       /* adding the tunnel failed, we try again in the next cycle */
       current_ipv4_gw = NULL;
     }
@@ -575,8 +557,7 @@ olsr_set_inet_gateway(union olsr_ip_addr *originator, bool ipv4, bool ipv6, bool
     if ((v6gw_tunnel = olsr_os_add_ipip_tunnel(&current_ipv6_gw->originator, false)) != NULL) {
       olsr_os_inetgw_tunnel_route(v6gw_tunnel->if_index, false, true);
       v6gw_choosen_external = external;
-    }
-    else {
+    } else {
       /* adding the tunnel failed, we try again in the next cycle */
       current_ipv6_gw = NULL;
     }
index 250d8e5..ffb4a93 100644 (file)
 
 /** gateway HNA flags */
 enum gateway_hna_flags {
-  GW_HNA_FLAG_LINKSPEED  = 1<<0,
-  GW_HNA_FLAG_IPV4       = 1<<1,
-  GW_HNA_FLAG_IPV4_NAT   = 1<<2,
-  GW_HNA_FLAG_IPV6       = 1<<3,
-  GW_HNA_FLAG_IPV6PREFIX = 1<<4
+  GW_HNA_FLAG_LINKSPEED   = 1 << 0,
+  GW_HNA_FLAG_IPV4        = 1 << 1,
+  GW_HNA_FLAG_IPV4_NAT    = 1 << 2,
+  GW_HNA_FLAG_IPV6        = 1 << 3,
+  GW_HNA_FLAG_IPV6PREFIX  = 1 << 4
 };
 
 /** gateway HNA field byte offsets in the netmask field of the HNA */
 enum gateway_hna_fields {
-  GW_HNA_PAD         = 0,
-  GW_HNA_FLAGS       = 1,
-  GW_HNA_UPLINK      = 2,
-  GW_HNA_DOWNLINK    = 3,
-  GW_HNA_V6PREFIXLEN = 4,
-  GW_HNA_V6PREFIX    = 5
+  GW_HNA_PAD              = 0,
+  GW_HNA_FLAGS            = 1,
+  GW_HNA_UPLINK           = 2,
+  GW_HNA_DOWNLINK         = 3,
+  GW_HNA_V6PREFIXLEN      = 4,
+  GW_HNA_V6PREFIX         = 5
 };
 
 /** a gateway entry */
 struct gateway_entry {
-  struct avl_node node;
-  union olsr_ip_addr originator;
-  struct olsr_ip_prefix external_prefix;
-  uint32_t uplink;
-  uint32_t downlink;
-  bool ipv4;
-  bool ipv4nat;
-  bool ipv6;
-
-  struct timer_entry *cleanup_timer;
-  uint16_t seqno;
+    struct avl_node node;
+    union olsr_ip_addr originator;
+    struct olsr_ip_prefix external_prefix;
+    uint32_t uplink;
+    uint32_t downlink;
+    bool ipv4;
+    bool ipv4nat;
+    bool ipv6;
+
+    struct timer_entry *cleanup_timer;
+    uint16_t seqno;
 };
 
 /**
@@ -87,10 +87,10 @@ extern struct avl_tree gateway_tree;
  * The callback list for a gateway plugin
  */
 struct olsr_gw_handler {
-  void (* handle_startup)(void); /**< the startup callback */
-  void (* select_gateway) (bool ipv4, bool ipv6); /**< the gateway selection callback */
-  void (* handle_update_gw)(struct gateway_entry *); /**< the gateway update callback */
-  void (* handle_delete_gw)(struct gateway_entry *); /**< the gateway deletion callback */
+    void (*handle_startup)(void); /**< the startup callback */
+    void (*select_gateway)(bool ipv4, bool ipv6); /**< the gateway selection callback */
+    void (*handle_update_gw)(struct gateway_entry *); /**< the gateway update callback */
+    void (*handle_delete_gw)(struct gateway_entry *); /**< the gateway deletion callback */
 };
 
 /*
index d96c20e..c729e5a 100644 (file)
@@ -28,10 +28,10 @@ static void gw_default_delete_handler(struct gateway_entry *);
  * Callback list for the gateway (default) handler
  */
 static struct olsr_gw_handler gw_def_handler = {
-  &gw_default_startup_handler,
-  &gw_default_choosegw_handler,
-  &gw_default_update_handler,
-  &gw_default_delete_handler
+    &gw_default_startup_handler,
+    &gw_default_choosegw_handler,
+    &gw_default_update_handler,
+    &gw_default_delete_handler
 };
 
 /*
@@ -50,7 +50,7 @@ static inline uint64_t gw_default_calc_threshold(uint64_t path_cost) {
   if (olsr_cnf->smart_gw_thresh == 0) {
     path_cost_times_threshold = path_cost;
   } else {
-    path_cost_times_threshold = (path_cost * (uint64_t)olsr_cnf->smart_gw_thresh + (uint64_t)50) / (uint64_t)100;
+    path_cost_times_threshold = (path_cost * (uint64_t) olsr_cnf->smart_gw_thresh + (uint64_t) 50) / (uint64_t) 100;
   }
 
   return path_cost_times_threshold;
@@ -71,79 +71,79 @@ static inline uint64_t gw_default_calc_threshold(uint64_t path_cost) {
  * @return the weighed path cost
  */
 static inline uint64_t gw_default_weigh_costs(uint64_t path_cost, uint32_t exitUk, uint32_t exitDk) {
-       uint8_t WexitU = olsr_cnf->smart_gw_weight_exitlink_up;
-       uint8_t WexitD = olsr_cnf->smart_gw_weight_exitlink_down;
-       uint8_t Wetx = olsr_cnf->smart_gw_weight_etx;
-       uint8_t Detx = olsr_cnf->smart_gw_divider_etx;
-       uint64_t costU;
-       uint64_t costD;
-       uint64_t costE;
-
-       if (!Detx) {
-               /* only consider path costs (classic behaviour) */
-               return path_cost;
-       }
-
-       if (!exitUk || !exitDk) {
-               /* zero bandwidth */
-               return UINT64_MAX;
-       }
-
-       /*
-        * Weighing of the path costs:
-        *
-        * exitUm = the gateway exit link uplink   bandwidth, in Mbps
-        * exitDm = the gateway exit link downlink bandwidth, in Mbps
-        * WexitU = the gateway exit link uplink   bandwidth weight   (configured)
-        * WexitD = the gateway exit link downlink bandwidth weight   (configured)
-        * Wetx   = the ETX path cost weight                          (configured)
-        * Detx   = the ETX path cost divider                         (configured)
-        *
-        *                      WexitU   WexitD   Wetx
-        * path_cost_weighed =  ------ + ------ + ---- * path_cost
-        *                      exitUm   exitDm   Detx
-        *
-        * Since the gateway exit link bandwidths are in Kbps, the following formula
-        * is used to convert them to the desired Mbps:
-        *
-        *       bwK
-        * bwM = ----       bwK = bandwidth in Kbps
-        *       1000       bwM = bandwidth in Mbps
-        *
-        * exitUm = the gateway exit link uplink   bandwidth, in Kbps
-        * exitDm = the gateway exit link downlink bandwidth, in Kbps
-        *
-        *                      1000 * WexitU   1000 * WexitD   Wetx
-        * path_cost_weighed =  ------------- + ------------- + ---- * path_cost
-        *                          exitUk          exitDk      Detx
-        *
-        *
-        * Analysis of the required bit width of the result:
-        *
-        * exitUk    = 29 bits = [1,   320,000,000]
-        * exitDk    = 29 bits = [1,   320,000,000]
-        * WexitU    =  8 bits = [1,           255]
-        * WexitD    =  8 bits = [1,           255]
-        * Wetx      =  8 bits = [1,           255]
-        * Detx      =  8 bits = [1,           255]
-        * path_cost = 32 bits = [1, 4,294,967,295]
-        *
-        *                          1000 * 255   1000 * 255   255
-        * path_cost_weighed(max) = ---------- + ---------- + --- * 4,294,967,295
-        *                               1             1       1
-        *
-        * path_cost_weighed(max) = 0x3E418    + 0x3E418    + 0xFEFFFFFF01
-        * path_cost_weighed(max) = 0xFF0007C731
-        *
-        * Because we can multiply 0xFF0007C731 by 2^24 without overflowing a
-        * 64 bits number, we do this to increase accuracy.
-        */
-
-       costU = (((uint64_t)(1000 * WexitU   )) << 24) / exitUk;
-       costD = (((uint64_t)(1000 * WexitD   )) << 24) / exitDk;
-       costE = (((uint64_t)(Wetx * path_cost)) << 24) / Detx;
-
-       return (costU + costD + costE);
+  uint8_t WexitU = olsr_cnf->smart_gw_weight_exitlink_up;
+  uint8_t WexitD = olsr_cnf->smart_gw_weight_exitlink_down;
+  uint8_t Wetx = olsr_cnf->smart_gw_weight_etx;
+  uint8_t Detx = olsr_cnf->smart_gw_divider_etx;
+  uint64_t costU;
+  uint64_t costD;
+  uint64_t costE;
+
+  if (!Detx) {
+    /* only consider path costs (classic behaviour) */
+    return path_cost;
+  }
+
+  if (!exitUk || !exitDk) {
+    /* zero bandwidth */
+    return UINT64_MAX;
+  }
+
+  /*
+   * Weighing of the path costs:
+   *
+   * exitUm = the gateway exit link uplink   bandwidth, in Mbps
+   * exitDm = the gateway exit link downlink bandwidth, in Mbps
+   * WexitU = the gateway exit link uplink   bandwidth weight   (configured)
+   * WexitD = the gateway exit link downlink bandwidth weight   (configured)
+   * Wetx   = the ETX path cost weight                          (configured)
+   * Detx   = the ETX path cost divider                         (configured)
+   *
+   *                      WexitU   WexitD   Wetx
+   * path_cost_weighed =  ------ + ------ + ---- * path_cost
+   *                      exitUm   exitDm   Detx
+   *
+   * Since the gateway exit link bandwidths are in Kbps, the following formula
+   * is used to convert them to the desired Mbps:
+   *
+   *       bwK
+   * bwM = ----       bwK = bandwidth in Kbps
+   *       1000       bwM = bandwidth in Mbps
+   *
+   * exitUm = the gateway exit link uplink   bandwidth, in Kbps
+   * exitDm = the gateway exit link downlink bandwidth, in Kbps
+   *
+   *                      1000 * WexitU   1000 * WexitD   Wetx
+   * path_cost_weighed =  ------------- + ------------- + ---- * path_cost
+   *                          exitUk          exitDk      Detx
+   *
+   *
+   * Analysis of the required bit width of the result:
+   *
+   * exitUk    = 29 bits = [1,   320,000,000]
+   * exitDk    = 29 bits = [1,   320,000,000]
+   * WexitU    =  8 bits = [1,           255]
+   * WexitD    =  8 bits = [1,           255]
+   * Wetx      =  8 bits = [1,           255]
+   * Detx      =  8 bits = [1,           255]
+   * path_cost = 32 bits = [1, 4,294,967,295]
+   *
+   *                          1000 * 255   1000 * 255   255
+   * path_cost_weighed(max) = ---------- + ---------- + --- * 4,294,967,295
+   *                               1             1       1
+   *
+   * path_cost_weighed(max) = 0x3E418    + 0x3E418    + 0xFEFFFFFF01
+   * path_cost_weighed(max) = 0xFF0007C731
+   *
+   * Because we can multiply 0xFF0007C731 by 2^24 without overflowing a
+   * 64 bits number, we do this to increase accuracy.
+   */
+
+  costU = (((uint64_t) (1000 * WexitU)) << 24) / exitUk;
+  costD = (((uint64_t) (1000 * WexitD)) << 24) / exitDk;
+  costE = (((uint64_t) (Wetx * path_cost)) << 24) / Detx;
+
+  return (costU + costD + costE);
 }
 
 /**
@@ -191,7 +191,7 @@ static void gw_default_choose_gateway(void) {
     tc = olsr_lookup_tc_entry(&gw->originator);
 
     if (!tc) {
-         /* gateways should not exist without tc entry */
+      /* gateways should not exist without tc entry */
       continue;
     }
 
@@ -208,13 +208,13 @@ static void gw_default_choose_gateway(void) {
     /* determine the path cost */
     path_cost = gw_default_weigh_costs(tc->path_cost, gw->uplink, gw->downlink);
 
-    if (!gw_def_finished_ipv4 && gw->ipv4 && gw->ipv4nat == olsr_cnf->smart_gw_allow_nat && path_cost < cost_ipv4 &&
-        (!eval_cost_ipv4_threshold || (path_cost < cost_ipv4_threshold))) {
+    if (!gw_def_finished_ipv4 && gw->ipv4 && gw->ipv4nat == olsr_cnf->smart_gw_allow_nat && path_cost < cost_ipv4
+        && (!eval_cost_ipv4_threshold || (path_cost < cost_ipv4_threshold))) {
       inet_ipv4 = gw;
       cost_ipv4 = path_cost;
     }
-    if (!gw_def_finished_ipv6 && gw->ipv6 && path_cost < cost_ipv6 &&
-        (!eval_cost_ipv6_threshold || (path_cost < cost_ipv6_threshold))) {
+    if (!gw_def_finished_ipv6 && gw->ipv6 && path_cost < cost_ipv6
+        && (!eval_cost_ipv6_threshold || (path_cost < cost_ipv6_threshold))) {
       inet_ipv6 = gw;
       cost_ipv6 = path_cost;
     }
@@ -228,7 +228,7 @@ static void gw_default_choose_gateway(void) {
   dual = (inet_ipv4 == inet_ipv6) && (inet_ipv4 != NULL);
 
   if (inet_ipv4) {
-       /* we are dealing with an IPv4 or dual stack gateway */
+    /* we are dealing with an IPv4 or dual stack gateway */
     olsr_set_inet_gateway(&inet_ipv4->originator, true, dual, false);
   }
   if (inet_ipv6 && !dual) {
@@ -250,16 +250,14 @@ static void gw_default_choose_gateway(void) {
  */
 static void gw_default_timer(void *unused __attribute__ ((unused))) {
   /* accept a 10% increase/decrease in the number of gateway nodes without triggering a stablecount reset */
-  if (((tc_tree.count * 10) <= (gw_def_nodecount * 11)) ||
-      ((tc_tree.count * 10) >= (gw_def_nodecount *  9))) {
+  if (((tc_tree.count * 10) <= (gw_def_nodecount * 11)) || ((tc_tree.count * 10) >= (gw_def_nodecount * 9))) {
     gw_def_nodecount = tc_tree.count;
   }
 
   if (tc_tree.count == gw_def_nodecount) {
     /* the number of gateway nodes is 'stable' */
     gw_def_stablecount++;
-  }
-  else {
+  } else {
     /* there was a significant change in the number of gateway nodes */
     gw_def_nodecount = tc_tree.count;
     gw_def_stablecount = 0;