gateway: add helper function gw_default_calc_threshold
[olsrd.git] / src / gateway_default_handler.c
index ac14716..d8a5adb 100644 (file)
@@ -38,6 +38,24 @@ static struct olsr_gw_handler gw_def_handler = {
  * Helper functions
  */
 
+/**
+ * Calculate the threshold path cost.
+ *
+ * @param path_cost the path cost
+ * @return the threshold path cost
+ */
+static inline olsr_linkcost gw_default_calc_threshold(olsr_linkcost path_cost) {
+  olsr_linkcost path_cost_times_threshold;
+
+  if (olsr_cnf->smart_gw_thresh == 0) {
+    path_cost_times_threshold = path_cost;
+  } else {
+    path_cost_times_threshold = ((long long) path_cost * (long long) olsr_cnf->smart_gw_thresh + 50LL) / 100LL;
+  }
+
+  return path_cost_times_threshold;
+}
+
 /**
  * Look through the gateway list and select the best gateway
  * depending on the distance to this router
@@ -59,13 +77,19 @@ static void gw_default_choose_gateway(void) {
       continue;
     }
 
-    /* determine the path costs threshold */
-    if (olsr_cnf->smart_gw_thresh == 0) {
-      path_cost_times_threshold = tc->path_cost;
-    } else {
-      path_cost_times_threshold = ((long long)tc->path_cost * (long long)olsr_cnf->smart_gw_thresh + 50LL) / 100LL;
+    if (tc->path_cost == ROUTE_COST_BROKEN) {
+      /* do not consider nodes with an infinite ETX */
+      continue;
     }
 
+    if (!gw->uplink || !gw->downlink) {
+      /* do not consider nodes without bandwidth or with a uni-directional link */
+      continue;
+    }
+
+    /* determine the path costs threshold */
+    path_cost_times_threshold = gw_default_calc_threshold(tc->path_cost);
+
     if (!gw_def_finished_ipv4 && gw->ipv4 && gw->ipv4nat == olsr_cnf->smart_gw_allow_nat && path_cost_times_threshold < cost_ipv4) {
       inet_ipv4 = gw;
       cost_ipv4 = path_cost_times_threshold;
@@ -213,9 +237,9 @@ static void gw_default_choosegw_handler(bool ipv4, bool ipv6) {
  * @param gw the gateway entry
  */
 static void gw_default_update_handler(struct gateway_entry *gw) {
-  bool v4changed = (gw == olsr_get_ipv4_inet_gateway(NULL))
+  bool v4changed = gw && (gw == olsr_get_ipv4_inet_gateway(NULL))
       && (!gw->ipv4 || (gw->ipv4nat && !olsr_cnf->smart_gw_allow_nat));
-  bool v6changed = (gw == olsr_get_ipv6_inet_gateway(NULL)) && !gw->ipv6;
+  bool v6changed = gw && (gw == olsr_get_ipv6_inet_gateway(NULL)) && !gw->ipv6;
 
   if (v4changed || v6changed) {
     olsr_gw_default_lookup_gateway(v4changed, v6changed);
@@ -228,10 +252,10 @@ static void gw_default_update_handler(struct gateway_entry *gw) {
  * @param gw the gateway entry
  */
 static void gw_default_delete_handler(struct gateway_entry *gw) {
-  bool isv4 = (gw == olsr_get_ipv4_inet_gateway(NULL));
-  bool isv6 = (gw == olsr_get_ipv6_inet_gateway(NULL));
+  bool isv4 = gw && (gw == olsr_get_ipv4_inet_gateway(NULL));
+  bool isv6 = gw && (gw == olsr_get_ipv6_inet_gateway(NULL));
 
-  if (gw && (isv4 || isv6)) {
+  if (isv4 || isv6) {
     olsr_gw_default_lookup_gateway(isv4, isv6);
   }
 }