sgw: add SmartGatewayMaxCostMaxEtx configuration setting
authorFerry Huberts <ferry.huberts@pelagic.nl>
Tue, 13 Oct 2015 10:42:21 +0000 (12:42 +0200)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Tue, 13 Oct 2015 11:14:39 +0000 (13:14 +0200)
SmartGatewayMaxCostMaxEtx: When a node advertises the maximum bandwidth
and its ETX is below the value of this setting then the resulting gateway
costs are equal to the ETX, otherwise the normal calculation of the
gateway costs applies (default is 2560).

This avoids instability in the mesh when a far-away node advertises
maximum bandwidth.

Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
README-Olsr-Extensions
files/olsrd.conf.default.full.txt
src/cfgparser/cfgfile_gen.c
src/cfgparser/olsrd_conf.c
src/cfgparser/oparse.y
src/cfgparser/oscan.lex
src/egressFile.c
src/gateway_costs.c
src/gateway_costs.h
src/gateway_default_handler.c
src/olsr_cfg.h

index b5ce50f..6884e74 100644 (file)
@@ -333,6 +333,10 @@ All other parameters will be ignored if SmartGateway is set to "no"
 13-SmartGatewayWeightExitLinkUp, SmartGatewayWeightExitLinkDown,
    SmartGatewayWeightEtx and SmartGatewayDividerEtx control the weighing
    of gateway bandwidth and ETX costs.
+14-SmartGatewayMaxCostMaxEtx: When a node advertises the maximum bandwidth
+   and its ETX is below the value of this setting then the resulting gateway
+   costs are equal to the ETX, otherwise the normal calculation of the
+   gateway costs applies (default is 2560).
 
    If SmartGatewayDividerEtx is zero then no weighing is performed (classical
    behaviour). Classical behaviour only takes ETX costs into account when
index 13ea5f5..7283079 100644 (file)
 
 # SmartGatewayDividerEtx 0
 
+# When a node advertises the maximum bandwidth and its ETX
+# is below the value of this setting then the resulting gateway
+# costs are equal to the ETX, otherwise the normal calculation
+# of the gateway costs applies.
+# (default is 2560)
+
+# SmartGatewayMaxCostMaxEtx 2560
+
 # Defines what kind of Uplink this node will publish as a
 # smartgateway. The existence of the uplink is detected by
 # a route to 0.0.0.0/0, ::ffff:0:0/96 and/or 2000::/3.
index 3cf85b4..d7948b9 100644 (file)
@@ -853,6 +853,17 @@ void olsrd_write_cnf_autobuf(struct autobuf *out, struct olsrd_config *cnf) {
       cnf->smart_gw_divider_etx == DEF_GW_DIVIDER_ETX ? "# " : "",
       cnf->smart_gw_divider_etx);
   abuf_appendf(out,
+      "\n"
+      "# When a node advertises the maximum bandwidth and its ETX\n"
+      "# is below the value of this setting then the resulting gateway\n"
+      "# costs are equal to the ETX, otherwise the normal calculation\n"
+      "# of the gateway costs applies.\n"
+      "# (default is %u)\n"
+      "\n", DEF_GW_MAX_COST_MAX_ETX);
+  abuf_appendf(out, "%sSmartGatewayMaxCostMaxEtx %d\n",
+        cnf->smart_gw_path_max_cost_etx_max == DEF_GW_MAX_COST_MAX_ETX ? "# " : "",
+        cnf->smart_gw_path_max_cost_etx_max);
+  abuf_appendf(out,
     "\n"
     "# Defines what kind of Uplink this node will publish as a\n"
     "# smartgateway. The existence of the uplink is detected by\n"
index 0c2c44d..37a1cb6 100644 (file)
@@ -999,6 +999,7 @@ set_default_cnf(struct olsrd_config *cnf, char * configuration_file)
   cnf->smart_gw_weight_exitlink_down = DEF_GW_WEIGHT_EXITLINK_DOWN;
   cnf->smart_gw_weight_etx = DEF_GW_WEIGHT_ETX;
   cnf->smart_gw_divider_etx = DEF_GW_DIVIDER_ETX;
+  cnf->smart_gw_path_max_cost_etx_max = DEF_GW_MAX_COST_MAX_ETX;
   cnf->smart_gw_type = DEF_GW_TYPE;
   smartgw_set_uplink(cnf, DEF_UPLINK_SPEED);
   cnf->smart_gw_uplink_nat = DEF_GW_UPLINK_NAT;
index aa42842..ad36e04 100644 (file)
@@ -237,6 +237,7 @@ static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
 %token TOK_SMART_GW_WEIGHT_EXITLINK_DOWN
 %token TOK_SMART_GW_WEIGHT_ETX
 %token TOK_SMART_GW_DIVIDER_ETX
+%token TOK_SMART_GW_MAX_COST_MAX_ETX
 %token TOK_SMART_GW_UPLINK
 %token TOK_SMART_GW_UPLINK_NAT
 %token TOK_SMART_GW_SPEED
@@ -1554,6 +1555,14 @@ asmart_gw_divider_etx: TOK_SMART_GW_DIVIDER_ETX TOK_INTEGER
 }
 ;
 
+asmart_gw_divider_etx: TOK_SMART_GW_MAX_COST_MAX_ETX TOK_INTEGER
+{
+  PARSER_DEBUG_PRINTF("Smart gateway max cost max ETX: %d\n", $2->integer);
+  olsr_cnf->smart_gw_path_max_cost_etx_max = $2->integer;
+  free($2);
+}
+;
+
 ssmart_gw_uplink: TOK_SMART_GW_UPLINK TOK_STRING
 {
        PARSER_DEBUG_PRINTF("Smart gateway uplink: %s\n", $2->string);
index fccc906..8d499c0 100644 (file)
@@ -561,6 +561,11 @@ IPV6ADDR {IPV6PAT1}|{IPV6PAT2}|{IPV6PAT3}|{IPV6PAT4}|{IPV6PAT5}|{IPV6PAT6}|{IPV6
     return TOK_SMART_GW_DIVIDER_ETX;
 }
 
+"SmartGatewayMaxCostMaxEtx" {
+    yylval = NULL;
+    return TOK_SMART_GW_MAX_COST_MAX_ETX;
+}
+
 "SmartGatewayUplink" {
     yylval = NULL;
     return TOK_SMART_GW_UPLINK;
index 301bba4..462f859 100644 (file)
@@ -343,7 +343,7 @@ bool egressBwCalculateCosts(struct egress_if_bw * bw, bool up) {
 
   {
     int64_t costsPrevious = bw->costs;
-    bw->costs = gw_costs_weigh(up, gw_costs_weights_storage, bw->path_cost, bw->egressUk, bw->egressDk);
+    bw->costs = gw_costs_weigh(up, gw_costs_weights_storage, bw->path_cost, olsr_cnf->smart_gw_path_max_cost_etx_max, bw->egressUk, bw->egressDk);
     return (costsPrevious != bw->costs);
   }
 }
index b1d8132..f0b8d3d 100644 (file)
@@ -8,7 +8,7 @@ extern "C" {
 #define SCALING_SHIFT 23
 #define MAX_SMARTGW_SPEED 320000000
 
-int64_t gw_costs_weigh(bool up, const struct costs_weights weights, uint32_t path_cost, uint32_t exitUk, uint32_t exitDk) {
+int64_t gw_costs_weigh(bool up, const struct costs_weights weights, uint32_t path_cost, uint32_t max_cost_etx_max, uint32_t exitUk, uint32_t exitDk) {
   int64_t costU;
   int64_t costD;
   int64_t costE;
@@ -28,8 +28,8 @@ int64_t gw_costs_weigh(bool up, const struct costs_weights weights, uint32_t pat
     return INT64_MAX;
   }
 
-  if ((exitUk >= MAX_SMARTGW_SPEED) && (exitDk >= MAX_SMARTGW_SPEED)) {
-    /* maximum bandwidth: only consider path costs */
+  if ((exitUk >= MAX_SMARTGW_SPEED) && (exitDk >= MAX_SMARTGW_SPEED) && (path_cost < max_cost_etx_max)) {
+    /* maximum bandwidth AND below max_cost_etx_max: only consider path costs */
     return path_cost;
   }
 
index 72f49a6..5cafc90 100644 (file)
@@ -78,14 +78,19 @@ extern "C" {
    * If the ETX divider is zero, then no weighing is performed and only the path
    * costs are considered (classic behaviour), but scaled to a 64 bit number.
    *
+   * If path_cost is the maximum AND path_cost < max_cost_etx_max then
+   * the gateway costs are equal to path_cost.
+   *
    * @param up true when the relevant interface is up
    * @param weights the weights for the calculation
    * @param path_cost the (ETX) path cost to the gateway
+   * @param max_cost_etx_max the maximum (ETX) path cost for when path_costs is the maximum
+   * to take the calculation shortcut.
    * @param exitUk the gateway exit link uplink bandwidth (in kbps)
    * @param exitDk the gateway exit link downlink bandwidth (in kbps)
    * @return the weighed path cost, INT64_MAX when up is false or when exitUk and/or exitDk are zero
    */
-  int64_t gw_costs_weigh(bool up, const struct costs_weights weights, uint32_t path_cost, uint32_t exitUk, uint32_t exitDk);
+  int64_t gw_costs_weigh(bool up, const struct costs_weights weights, uint32_t path_cost, uint32_t max_cost_etx_max, uint32_t exitUk, uint32_t exitDk);
 
 #ifdef __cplusplus
 }
index 958495c..48a3745 100644 (file)
@@ -267,7 +267,7 @@ static int64_t gw_default_getcosts(struct gateway_entry *gw) {
   }
 
   /* determine the path cost */
-  return gw_costs_weigh(true, gw_costs_weights, tc->path_cost, gw->uplink, gw->downlink);
+  return gw_costs_weigh(true, gw_costs_weights, tc->path_cost, olsr_cnf->smart_gw_path_max_cost_etx_max, gw->uplink, gw->downlink);
 }
 
 /**
index 8eb9938..0f29d99 100644 (file)
 #define DEF_GW_WEIGHT_EXITLINK_DOWN 1
 #define DEF_GW_WEIGHT_ETX           1
 #define DEF_GW_DIVIDER_ETX          0
+#define DEF_GW_MAX_COST_MAX_ETX     2560
 #define DEF_GW_TYPE          GW_UPLINK_IPV46
 #define DEF_GW_UPLINK_NAT    true
 #define DEF_UPLINK_SPEED     128
@@ -331,6 +332,7 @@ struct olsrd_config {
   uint8_t smart_gw_weight_exitlink_down;
   uint8_t smart_gw_weight_etx;
   uint32_t smart_gw_divider_etx;
+  uint32_t smart_gw_path_max_cost_etx_max;
   enum smart_gw_uplinktype smart_gw_type;
   uint32_t smart_gw_uplink, smart_gw_downlink;
   bool smart_gateway_bandwidth_zero;