Implemented LinkQualityMult per-interface configuration directive.
authorThomas Lopatic <thomas@lopatic.de>
Tue, 15 Feb 2005 17:17:56 +0000 (17:17 +0000)
committerThomas Lopatic <thomas@lopatic.de>
Tue, 15 Feb 2005 17:17:56 +0000 (17:17 +0000)
src/cfgparser/olsrd_conf.c
src/cfgparser/oparse.y
src/cfgparser/oscan.lex
src/link_set.c
src/olsr_cfg.h

index 28fb235..eaa5b55 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: olsrd_conf.c,v 1.31 2004/12/30 16:33:31 kattemat Exp $
+ * $Id: olsrd_conf.c,v 1.32 2005/02/15 17:17:44 tlopatic Exp $
  */
 
 
@@ -391,6 +391,7 @@ olsrd_free_cnf(struct olsrd_config *cnf)
   struct hna6_entry        *h6d, *h6 = cnf->hna6_entries;
   struct olsr_if           *ind, *in = cnf->interfaces;
   struct plugin_entry      *ped, *pe = cnf->plugins;
+  struct olsr_lq_mult      *mult, *next_mult;
   
   while(h4)
     {
@@ -408,6 +409,12 @@ olsrd_free_cnf(struct olsrd_config *cnf)
 
   while(in)
     {
+      for (mult = in->cnf->lq_mult; mult != NULL; mult = next_mult)
+      {
+        next_mult = mult->next;
+        free(mult);
+      }
+
       free(in->cnf);
       ind = in;
       in = in->next;
@@ -501,6 +508,7 @@ get_default_if_config()
     }
   memcpy(&io->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
 
+  io->lq_mult = NULL;
 
   io->hello_params.emission_interval = HELLO_INTERVAL;
   io->hello_params.validity_time = NEIGHB_HOLD_TIME;
@@ -529,6 +537,7 @@ olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
   struct plugin_param      *pp;
   struct ipc_host          *ih = cnf->ipc_hosts;
   struct ipc_net           *ie = cnf->ipc_nets;
+  struct olsr_lq_mult      *mult;
 
   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
   struct in_addr in4;
@@ -755,7 +764,24 @@ olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
          else
            fprintf(fd, "    #HnaValidityTime\t%0.2f\n", in->cnf->hna_params.validity_time);      
          
-         
+          mult = in->cnf->lq_mult;
+
+          if (mult == NULL)
+            fprintf(fd, "    #LinkQualityMult\tdefault 1.0\n");
+
+          else
+          {
+            while (mult != NULL)
+            {
+              inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf,
+                        sizeof (ipv6_buf));
+
+              fprintf(fd, "    LinkQualityMult\t%s %0.2f\n",
+                      ipv6_buf, mult->val);
+
+              mult = mult->next;
+            }
+          }
          
          fprintf(fd, "}\n\n");
          in = in->next;
@@ -785,6 +811,7 @@ olsrd_print_cnf(struct olsrd_config *cnf)
   struct plugin_entry      *pe = cnf->plugins;
   struct ipc_host          *ih = cnf->ipc_hosts;
   struct ipc_net           *ie = cnf->ipc_nets;
+  struct olsr_lq_mult      *mult;
   char ipv6_buf[100];             /* buffer for IPv6 inet_htop */
   struct in_addr in4;
 
@@ -867,10 +894,16 @@ olsrd_print_cnf(struct olsrd_config *cnf)
          printf("\tMID emission/validity    : %0.2f/%0.2f\n", in->cnf->mid_params.emission_interval, in->cnf->mid_params.validity_time);
          printf("\tHNA emission/validity    : %0.2f/%0.2f\n", in->cnf->hna_params.emission_interval, in->cnf->hna_params.validity_time);
          
-         
+          for (mult = in->cnf->lq_mult; mult != NULL; mult = mult->next)
+          {
+            inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf,
+                      sizeof (ipv6_buf));
+
+            printf("\tLinkQualityMult          : %s %0.2f\n",
+                   ipv6_buf, mult->val);
+          }
          
          in = in->next;
-
        }
     }
 
index 5991059..478f3a3 100644 (file)
@@ -38,7 +38,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: oparse.y,v 1.23 2005/01/01 12:13:58 kattemat Exp $
+ * $Id: oparse.y,v 1.24 2005/02/15 17:17:46 tlopatic Exp $
  */
 
 
@@ -62,8 +62,61 @@ int yylex(void);
 
 static int ifs_in_curr_cfg = 0;
 
+static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg);
 
+static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
+{
+  union olsr_ip_addr addr;
+  int i;
+  struct olsr_if *walker;
+  struct olsr_lq_mult *mult;
+
+#if PARSER_DEBUG > 0
+  printf("\tLinkQualityMult %s %0.2f\n",
+         (ip_addr_arg != NULL) ? ip_addr_arg->string : "any",
+         mult_arg->floating);
+#endif
+
+  memset(&addr, 0, sizeof (union olsr_ip_addr));
+
+  if(ip_addr_arg != NULL &&
+     inet_pton(cnf->ip_version, ip_addr_arg->string, &addr) < 0)
+  {
+    fprintf(stderr, "Cannot parse IP address %s.\n", ip_addr_arg->string);
+    return -1;
+  }
+
+  walker = cnf->interfaces;
+
+  for (i = 0; i < ifs_in_curr_cfg; i++)
+  {
+    mult = malloc(sizeof (struct olsr_lq_mult));
+
+    if (mult == NULL)
+    {
+      fprintf(stderr, "Out of memory (LQ multiplier).\n");
+      return -1;
+    }
+
+    memcpy(&mult->addr, &addr, sizeof (union olsr_ip_addr));
+    mult->val = mult_arg->floating;
+
+    mult->next = walker->cnf->lq_mult;
+    walker->cnf->lq_mult = mult;
+
+    walker = walker->next;
+  }
 
+  if (ip_addr_arg != NULL)
+  {
+    free(ip_addr_arg->string);
+    free(ip_addr_arg);
+  }
+
+  free(mult_arg);
+
+  return 0;
+}
 %}
 
 %token TOK_OPEN
@@ -96,6 +149,7 @@ static int ifs_in_curr_cfg = 0;
 %token TOK_MPRCOVERAGE
 %token TOK_LQ_LEVEL
 %token TOK_LQ_WSIZE
+%token TOK_LQ_MULT
 %token TOK_CLEAR_SCREEN
 %token TOK_PLNAME
 %token TOK_PLPARAM
@@ -119,6 +173,7 @@ static int ifs_in_curr_cfg = 0;
 
 %token TOK_IP4_ADDR
 %token TOK_IP6_ADDR
+%token TOK_DEFAULT
 
 %token TOK_COMMENT
 
@@ -211,6 +266,7 @@ ifstmt:      vcomment
              | isetmidval
              | isethnaint
              | isethnaval
+             | isetlqmult
 ;
 
 plbody:     TOK_OPEN plstmts TOK_CLOSE
@@ -547,6 +603,25 @@ isethnaval: TOK_HNAVAL TOK_FLOAT
 }
 ;
 
+isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
+{
+  if (lq_mult_helper($2, $3) < 0)
+    YYABORT;
+}
+
+          | TOK_LQ_MULT TOK_IP4_ADDR TOK_FLOAT
+{
+  if (lq_mult_helper($2, $3) < 0)
+    YYABORT;
+}
+
+          | TOK_LQ_MULT TOK_IP6_ADDR TOK_FLOAT
+{
+  if (lq_mult_helper($2, $3) < 0)
+    YYABORT;
+}
+
+          ;
 
 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
 {
index 997b764..2c5025b 100644 (file)
@@ -38,7 +38,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: oscan.lex,v 1.14 2004/11/30 17:12:28 tlopatic Exp $
+ * $Id: oscan.lex,v 1.15 2005/02/15 17:17:56 tlopatic Exp $
  */
 
 
@@ -115,7 +115,6 @@ IP6PAT9 ::
 
 IPV6ADDR {IP6PAT1}|{IP6PAT2}|{IP6PAT3}|{IP6PAT4}|{IP6PAT5}|{IP6PAT6}|{IP6PAT7}|{IP6PAT8}|{IP6PAT9}
 
-
 %%
 
 \s*"#".*\n {
@@ -209,6 +208,10 @@ IPV6ADDR {IP6PAT1}|{IP6PAT2}|{IP6PAT3}|{IP6PAT4}|{IP6PAT5}|{IP6PAT6}|{IP6PAT7}|{
   return TOK_IP6_ADDR;
 }
 
+"default" {
+  yylval = NULL;
+  return TOK_DEFAULT;
+}
 
 {DECDIGIT}+ {
 
@@ -368,6 +371,11 @@ IPV6ADDR {IP6PAT1}|{IP6PAT2}|{IP6PAT3}|{IP6PAT4}|{IP6PAT5}|{IP6PAT6}|{IP6PAT7}|{
   return TOK_LQ_WSIZE;
 }
 
+"LinkQualityMult" {
+  yylval = NULL;
+  return TOK_LQ_MULT;
+}
+
 "ClearScreen" {
   yylval = NULL;
   return TOK_CLEAR_SCREEN;
index b9c40ef..0175e05 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: link_set.c,v 1.48 2005/02/14 15:54:29 tlopatic Exp $
+ * $Id: link_set.c,v 1.49 2005/02/15 17:17:42 tlopatic Exp $
  */
 
 
@@ -852,6 +852,47 @@ void olsr_print_link_set(void)
   }
 }
 
+static void multiply_link_quality(struct link_entry *entry)
+{
+  struct interface *inter;
+  struct olsr_if *cfg_inter;
+  struct olsr_lq_mult *mult;
+  float val = -1.0;
+  union olsr_ip_addr null_addr;
+
+  // find the interface for the link
+
+  inter = if_ifwithaddr(&entry->local_iface_addr);
+
+  // find the interface configuration for the interface
+
+  for (cfg_inter = olsr_cnf->interfaces; cfg_inter != NULL;
+       cfg_inter = cfg_inter->next)
+    if (cfg_inter->interf == inter)
+      break;
+
+  // create a null address for comparison
+
+  memset(&null_addr, 0, sizeof (union olsr_ip_addr));
+
+  // loop through the multiplier entries
+
+  for (mult = cfg_inter->cnf->lq_mult; mult != NULL; mult = mult->next)
+  {
+    // use the default multiplier only if there isn't any entry that
+    // has a matching IP address
+
+    if ((COMP_IP(&mult->addr, &null_addr) && val < 0.0) ||
+        COMP_IP(&mult->addr, &entry->neighbor_iface_addr))
+      val = mult->val;
+  }
+
+  // if we have found an entry, then multiply
+
+  if (val >= 0)
+    entry->loss_link_quality *= val;
+}
+
 static void update_packet_loss_worker(struct link_entry *entry, int lost)
 {
   unsigned char mask = 1 << (entry->loss_index & 7);
@@ -916,6 +957,10 @@ static void update_packet_loss_worker(struct link_entry *entry, int lost)
     (float)(entry->total_packets - entry->lost_packets) /
     (float)(entry->loss_window_size);
 
+  // multiply the calculated link quality with the user-specified multiplier
+
+  multiply_link_quality(entry);
+
   // if the link quality has changed by more than 10 percent,
   // print the new link quality table
 
index 54116e7..ce9a8eb 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: olsr_cfg.h,v 1.16 2004/11/21 11:28:56 kattemat Exp $
+ * $Id: olsr_cfg.h,v 1.17 2005/02/15 17:17:43 tlopatic Exp $
  */
 
 
@@ -117,6 +117,13 @@ struct olsr_msg_params
   float                    validity_time;
 };
 
+struct olsr_lq_mult
+{
+  union olsr_ip_addr addr;
+  float val;
+  struct olsr_lq_mult *next;
+};
+
 struct if_config_options
 {
   union olsr_ip_addr       ipv4_broadcast;
@@ -127,6 +134,7 @@ struct if_config_options
   struct olsr_msg_params   tc_params;
   struct olsr_msg_params   mid_params;
   struct olsr_msg_params   hna_params;
+  struct olsr_lq_mult      *lq_mult;
 };