lqnatthresh: maintain an advantage for the current (NAT) inet gw
authorSven-Ola Tuecke <sven-ola@gmx.de>
Wed, 2 Jan 2008 13:37:52 +0000 (14:37 +0100)
committerSven-Ola Tuecke <sven-ola@gmx.de>
Wed, 2 Jan 2008 13:37:52 +0000 (14:37 +0100)
lib/httpinfo/src/olsrd_httpinfo.c
src/cfgparser/cfgfile_gen.c
src/cfgparser/olsrd_conf.c
src/cfgparser/oparse.y
src/cfgparser/oscan.lex
src/main.c
src/olsr_cfg.h
src/routing_table.c

index 63d99be..c2bddee 100644 (file)
@@ -846,6 +846,7 @@ static int build_config_body(char *buf, olsr_u32_t bufsize)
     size += snprintf(&buf[size], bufsize-size, "<td>Pollrate: %0.2f</td>\n", olsr_cnf->pollrate);
     size += snprintf(&buf[size], bufsize-size, "<td>TC redundancy: %d</td>\n", olsr_cnf->tc_redundancy);
     size += snprintf(&buf[size], bufsize-size, "<td>MPR coverage: %d</td>\n", olsr_cnf->mpr_coverage);
+    size += snprintf(&buf[size], bufsize-size, "<td>NAT threshold: %f</td>\n", olsr_cnf->lq_nat_thresh);
 
     size += snprintf(&buf[size], bufsize-size, "</tr>\n<tr>\n");
 
index 6b50bc9..26047b1 100644 (file)
@@ -181,6 +181,9 @@ olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
   fprintf(fd, "# Link quality window size\n\n");
   fprintf(fd, "LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
 
+  fprintf(fd, "# NAT threshold\n\n");
+  fprintf(fd, "NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
+
   fprintf(fd, "# Clear screen when printing debug output?\n\n");
   fprintf(fd, "ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
 
@@ -462,6 +465,9 @@ olsrd_write_cnf_buf(struct olsrd_config *cnf, char *buf, olsr_u32_t bufsize)
   WRITE_TO_BUF("# Link quality window size\n\n");
   WRITE_TO_BUF("LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
 
+  WRITE_TO_BUF("# NAT threshold\n\n");
+  WRITE_TO_BUF("NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
+
   WRITE_TO_BUF("# Clear screen when printing debug output?\n\n");
   WRITE_TO_BUF("ClearScreen\t%s\n\n", cnf->clear_screen ? "yes" : "no");
 
index 0f3c166..abf1b9e 100644 (file)
@@ -291,6 +291,13 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
       return -1;
     }
 
+  /* NAT threshold value */
+  if(cnf->lq_level && (cnf->lq_nat_thresh < 0.1 || cnf->lq_nat_thresh > 1.0))
+    {
+      fprintf(stderr, "NAT threshold %f is not allowed\n", cnf->lq_nat_thresh);
+      return -1;
+    }
+
   if(in == NULL)
     {
       fprintf(stderr, "No interfaces configured!\n");
@@ -456,6 +463,7 @@ set_default_cnf(struct olsrd_config *cnf)
     cnf->lq_dlimit = DEF_LQ_DIJK_LIMIT;
     cnf->lq_dinter = DEF_LQ_DIJK_INTER;
     cnf->lq_wsize = DEF_LQ_WSIZE;
+    cnf->lq_nat_thresh = DEF_LQ_NAT_THRESH;
     cnf->clear_screen = DEF_CLEAR_SCREEN;
 
     cnf->del_gws = OLSR_FALSE;
@@ -577,6 +585,8 @@ olsrd_print_cnf(struct olsrd_config *cnf)
 
   printf("LQ window size   : %d\n", cnf->lq_wsize);
 
+  printf("NAT threshold    : %f\n", cnf->lq_nat_thresh);
+
   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
 
   /* Interfaces */
index daf911d..e3e54cf 100644 (file)
@@ -188,6 +188,7 @@ static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
 %token TOK_LQ_FISH
 %token TOK_LQ_DLIMIT
 %token TOK_LQ_WSIZE
+%token TOK_LQ_NAT_THRESH
 %token TOK_LQ_MULT
 %token TOK_CLEAR_SCREEN
 %token TOK_PLPARAM
@@ -242,6 +243,7 @@ stmt:       idebug
           | alq_level
           | alq_fish
           | alq_dlimit
+          | anat_thresh
           | alq_wsize
           | bclear_screen
           | vcomment
@@ -978,6 +980,14 @@ alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
 }
 ;
 
+anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
+{
+  PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", $2->floating);
+  olsr_cnf->lq_nat_thresh = $2->floating;
+  free($2);
+}
+;
+
 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
 {
   PARSER_DEBUG_PRINTF("Clear screen %s\n", olsr_cnf->clear_screen ? "enabled" : "disabled");
index 2b0fef9..9ce27b0 100644 (file)
@@ -383,6 +383,11 @@ IPV6ADDR {IP6PAT1}|{IP6PAT2}|{IP6PAT3}|{IP6PAT4}|{IP6PAT5}|{IP6PAT6}|{IP6PAT7}|{
     return TOK_LQ_WSIZE;
 }
 
+"NatThreshold" {
+    yylval = NULL;
+    return TOK_LQ_NAT_THRESH;
+}
+
 "LinkQualityMult" {
     yylval = NULL;
     return TOK_LQ_MULT;
index 5a2ed09..b0019aa 100644 (file)
@@ -523,7 +523,7 @@ print_usage(void)
           "An error occured somwhere between your keyboard and your chair!\n"
           "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n"
           "  [-d <debug_level>] [-ipv6] [-multi <IPv6 multicast address>]\n"
-          "  [-lql <LQ level>] [-lqw <LQ winsize>]\n"
+          "  [-lql <LQ level>] [-lqw <LQ winsize>] [-lqnt <nat threshold>]\n"
           "  [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n"
           "  [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n"
           "  [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n"
@@ -664,6 +664,27 @@ olsr_process_arguments(int argc, char *argv[],
          continue;
        }
       
+      /*
+       * Set NAT threshold
+       */
+      if (strcmp(*argv, "-lqnt") == 0) 
+       {
+         float tmp_lq_nat_thresh;
+         NEXT_ARG;
+          CHECK_ARGC;
+
+         sscanf(*argv,"%f", &tmp_lq_nat_thresh);
+
+         if(tmp_lq_nat_thresh < 0.1 || tmp_lq_nat_thresh > 1.0)
+           {
+             printf("NAT threshold %f not allowed. Range [%f-%f]\n", 
+                    tmp_lq_nat_thresh, 0.1, 1.0);
+             olsr_exit(__func__, EXIT_FAILURE);
+           }
+         olsr_cnf->lq_nat_thresh = tmp_lq_nat_thresh;
+         continue;
+       }
+
       /*
        * Enable additional debugging information to be logged.
        */
index c893c58..8a02d37 100644 (file)
@@ -66,6 +66,7 @@
 #define DEF_LQ_FISH         0
 #define DEF_LQ_DIJK_LIMIT   255
 #define DEF_LQ_DIJK_INTER   0.0
+#define DEF_LQ_NAT_THRESH   1.0
 #define DEF_LQ_WSIZE        12
 #define DEF_CLEAR_SCREEN    OLSR_FALSE
 
@@ -240,6 +241,7 @@ struct olsrd_config
 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
   int                      rts;                  /* Socket used for route changes on BSDs */
 #endif
+  float                    lq_nat_thresh;
 };
 
 #if defined __cplusplus
index f9db44a..242a9bb 100644 (file)
 
 #include <assert.h>
 
+/*
+ * Sven-Ola: if the current internet gateway is switched, the
+ * NAT connection info is lost for any active TCP/UDP session.
+ * For this reason, we do not want to switch if the advantage
+ * is only minimal (cost of loosing all NATs is too high).
+ * The following rt_path keeps track of the current inet gw.
+ */
+static struct rt_path *current_inetgw = NULL;
+
 /* Root of our RIB */
 struct avl_tree routingtree;
 
@@ -343,6 +352,11 @@ olsr_free_rt_path(struct rt_path *rtp)
     rtp->rtp_tc = NULL;
   }
 
+  /* no current inet gw if the rt_path is removed */
+  if (current_inetgw == rtp) {
+    current_inetgw = NULL;
+  }
+
   free(rtp);
 }
 
@@ -410,15 +424,20 @@ olsr_get_nh(const struct rt_entry *rt)
  * than the second one, FALSE otherwise.
  */
 static olsr_bool
-olsr_cmp_rtp(const struct rt_path *rtp1, const struct rt_path *rtp2)
+olsr_cmp_rtp(const struct rt_path *rtp1, const struct rt_path *rtp2, const struct rt_path *inetgw)
 {
-   /* etx comes first */
-    if (rtp1->rtp_metric.etx < rtp2->rtp_metric.etx) {
+    float etx1 = rtp1->rtp_metric.etx;
+    float etx2 = rtp2->rtp_metric.etx;
+    if (inetgw == rtp1) etx1 *= olsr_cnf->lq_nat_thresh;
+    if (inetgw == rtp2) etx2 *= olsr_cnf->lq_nat_thresh;
+
+    /* etx comes first */
+    if (etx1 < etx2) {
       return OLSR_TRUE;
     }
 
     /* hopcount is next tie breaker */
-    if ((rtp1->rtp_metric.etx == rtp2->rtp_metric.etx) &&
+    if ((etx1 == etx2) &&
         (rtp1->rtp_metric.hops < rtp2->rtp_metric.hops)) {
       return OLSR_TRUE;
     }
@@ -442,7 +461,7 @@ olsr_cmp_rtp(const struct rt_path *rtp1, const struct rt_path *rtp2)
 olsr_bool
 olsr_cmp_rt(const struct rt_entry *rt1, const struct rt_entry *rt2)
 {
-  return olsr_cmp_rtp(rt1->rt_best, rt2->rt_best);
+  return olsr_cmp_rtp(rt1->rt_best, rt2->rt_best, NULL);
 }
 
 /**
@@ -463,10 +482,14 @@ olsr_rt_best(struct rt_entry *rt)
   while ((node = avl_walk_next(node))) {
     struct rt_path *rtp = node->data;
 
-    if (olsr_cmp_rtp(rtp, rt->rt_best)) {
+    if (olsr_cmp_rtp(rtp, rt->rt_best, current_inetgw)) {
       rt->rt_best = rtp;
     }
   }
+
+  if (0 == rt->rt_dst.prefix_len) {
+    current_inetgw = rt->rt_best;
+  }
 }
 
 /**