merge LinkQualityMults of Interface Defaults with LinkQualityMults of interface sections
[olsrd.git] / src / cfgparser / olsrd_conf.c
index 3ad2673..f8558dd 100644 (file)
@@ -145,6 +145,46 @@ olsrd_parse_cnf(const char *filename)
   return 0;
 }
 
+/* prints an interface (and checks it againt the default config) and the inverted config */
+static void
+olsrd_print_interface_cnf(struct if_config_options *cnf, struct if_config_options *cnfi, bool defcnf)
+{
+  struct olsr_lq_mult *mult;
+  int lq_mult_cnt = 0;
+  char ipv6_buf[INET6_ADDRSTRLEN];                  /* buffer for IPv6 inet_htop */
+
+  if (cnf->ipv4_multicast.v4.s_addr) {
+    printf("\tIPv4 broadcast/multicast : %s%s\n", inet_ntoa(cnf->ipv4_multicast.v4),DEFAULT_STR(ipv4_multicast.v4.s_addr));
+  } else {
+    printf("\tIPv4 broadcast/multicast : AUTO%s\n",DEFAULT_STR(ipv4_multicast.v4.s_addr));
+  }
+
+  if (cnf->mode==IF_MODE_ETHER){
+    printf("\tMode           : ether%s\n",DEFAULT_STR(mode));
+  } else {
+    printf("\tMode           : mesh%s\n",DEFAULT_STR(mode));
+  }
+
+  printf("\tIPv6 multicast           : %s%s\n", inet_ntop(AF_INET6, &cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)),DEFAULT_STR(ipv6_multicast.v6));
+
+  printf("\tHELLO emission/validity  : %0.2f%s/%0.2f%s\n", cnf->hello_params.emission_interval, DEFAULT_STR(hello_params.emission_interval),
+         cnf->hello_params.validity_time,DEFAULT_STR(hello_params.validity_time));
+  printf("\tTC emission/validity     : %0.2f%s/%0.2f%s\n", cnf->tc_params.emission_interval, DEFAULT_STR(tc_params.emission_interval),
+         cnf->tc_params.validity_time,DEFAULT_STR(tc_params.validity_time));
+  printf("\tMID emission/validity    : %0.2f%s/%0.2f%s\n", cnf->mid_params.emission_interval, DEFAULT_STR(mid_params.emission_interval),
+         cnf->mid_params.validity_time,DEFAULT_STR(mid_params.validity_time));
+  printf("\tHNA emission/validity    : %0.2f%s/%0.2f%s\n", cnf->hna_params.emission_interval, DEFAULT_STR(hna_params.emission_interval),
+         cnf->hna_params.validity_time,DEFAULT_STR(hna_params.validity_time));
+
+  for (mult = cnf->lq_mult; mult != NULL; mult = mult->next) {
+    lq_mult_cnt++;
+    printf("\tLinkQualityMult          : %s %0.2f %s\n", inet_ntop(olsr_cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
+      (float)(mult->value) / 65536.0, ((lq_mult_cnt > cnf->orig_lq_mult_cnt)?" (d)":""));
+  }
+
+  printf("\tAutodetect changes       : %s%s\n", cnf->autodetect_chg ? "yes" : "no",DEFAULT_STR(autodetect_chg));
+}
+
 int
 olsrd_sanity_check_cnf(struct olsrd_config *cnf)
 {
@@ -282,18 +322,25 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
 
   /* Interfaces */
   while (in) {
-    struct olsr_lq_mult *mult;
+    struct olsr_lq_mult *mult, *mult_orig;
 
     io = in->cnf;
 
+printf("dev %s before applying defaultSection:\n",in->name);
+    olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
+
     /*apply defaults (if this is not the default interface stub)*/
     if (in->cnf != cnf->interface_defaults)
     {
       size_t pos;
+      struct olsr_lq_mult *mult_temp, *mult_orig_walk;
       uint8_t *cnfptr = (uint8_t*)in->cnf;
       uint8_t *cnfiptr = (uint8_t*)in->cnfi;
       uint8_t *defptr = (uint8_t*)cnf->interface_defaults;
 
+      /*save interface specific lqmults, as they are merged togehter later*/
+      mult_orig = io->lq_mult;
+
       assert(in->cnf);
       assert(in->cnfi);
       for (pos = 0; pos < sizeof(*in->cnf); pos++) {
@@ -302,16 +349,34 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
         }
         else cnfiptr[pos]=0xFF;
       }
+
+      io->lq_mult=NULL;
+      /*copy default lqmults into this interface*/
+      for (mult = cnf->interface_defaults->lq_mult; mult; mult=mult->next) {
+        /*search same lqmult in orig_list*/
+        for (mult_orig_walk = mult_orig; mult_orig_walk; mult_orig_walk=mult_orig_walk->next) {
+          if (ipequal(&mult_orig_walk->addr,&mult->addr)) {
+            break;
+          }
+        }
+        if (mult_orig_walk == NULL) {
+          mult_temp=malloc(sizeof(struct olsr_lq_mult));
+          memcpy(mult_temp,mult,sizeof(struct olsr_lq_mult));
+          mult_temp->next=io->lq_mult;
+          io->lq_mult=mult_temp;
+        }
+      }
     }
     else
     { /* check if there are no lqmults
        *  as copying the pointer to the interfaces, 
        *  would lead 1. to unexpected results if this interface defines its own lqmults 
-       *  2. to problems when freeing lqmult structures them) */
+       *  2. to problems when freeing lqmult structures them) 
       if (io->lq_mult!=NULL) {
         fprintf(stderr, "LinkQualityMult directives are not supported within InterfaceDefaults section!\n", in->name);
         return -1;
-      }
+      }*/
+      mult_orig = NULL;
     }
 
     if (in->name == NULL || !strlen(in->name)) {
@@ -365,6 +430,19 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
       return -1;
     }
 
+    /*merge lqmults*/
+    if (mult_orig!=NULL) {
+      io->orig_lq_mult_cnt=1;
+      /*search last of interface specific lqmults*/
+      mult = mult_orig;
+      while (mult->next!=NULL) {
+        mult=mult->next;
+      }
+      /*append default lqmults ath the end of the interface specific (to ensure they can overwrite them)*/
+      mult->next=io->lq_mult;
+      io->lq_mult=mult_orig;
+    }
+
     for (mult = io->lq_mult; mult; mult=mult->next) {
       if (mult->value > LINK_LOSS_MULTIPLIER) {
         struct ipaddr_str buf;
@@ -523,39 +601,6 @@ get_default_if_config(void)
 
 }
 
-/* prints an interface (and checks it againt the default config) and the inverted config */
-static void
-olsrd_print_interface_cnf(struct if_config_options *cnf, struct if_config_options *cnfi, bool defcnf)
-{
-  char ipv6_buf[INET6_ADDRSTRLEN];                  /* buffer for IPv6 inet_htop */
-
-  if (cnf->ipv4_multicast.v4.s_addr) {
-    printf("\tIPv4 broadcast/multicast : %s%s\n", inet_ntoa(cnf->ipv4_multicast.v4),DEFAULT_STR(ipv4_multicast.v4.s_addr));
-  } else {
-    printf("\tIPv4 broadcast/multicast : AUTO%s\n",DEFAULT_STR(ipv4_multicast.v4.s_addr));
-  }
-
-  if (cnf->mode==IF_MODE_ETHER){
-    printf("\tMode           : ether%s\n",DEFAULT_STR(mode));
-  } else {
-    printf("\tMode           : mesh%s\n",DEFAULT_STR(mode));
-  }
-
-  printf("\tIPv6 multicast           : %s%s\n", inet_ntop(AF_INET6, &cnf->ipv6_multicast.v6, ipv6_buf, sizeof(ipv6_buf)),DEFAULT_STR(ipv6_multicast.v6));
-
-  printf("\tHELLO emission/validity  : %0.2f%s/%0.2f%s\n", cnf->hello_params.emission_interval, DEFAULT_STR(hello_params.emission_interval),
-         cnf->hello_params.validity_time,DEFAULT_STR(hello_params.validity_time));
-  printf("\tTC emission/validity     : %0.2f%s/%0.2f%s\n", cnf->tc_params.emission_interval, DEFAULT_STR(tc_params.emission_interval),
-         cnf->tc_params.validity_time,DEFAULT_STR(tc_params.validity_time));
-  printf("\tMID emission/validity    : %0.2f%s/%0.2f%s\n", cnf->mid_params.emission_interval, DEFAULT_STR(mid_params.emission_interval),
-         cnf->mid_params.validity_time,DEFAULT_STR(mid_params.validity_time));
-  printf("\tHNA emission/validity    : %0.2f%s/%0.2f%s\n", cnf->hna_params.emission_interval, DEFAULT_STR(hna_params.emission_interval),
-         cnf->hna_params.validity_time,DEFAULT_STR(hna_params.validity_time));
-
-  printf("\tAutodetect changes       : %s%s\n", cnf->autodetect_chg ? "yes" : "no",DEFAULT_STR(autodetect_chg));
-
-}
-
 void
 olsrd_print_cnf(struct olsrd_config *cnf)
 {
@@ -563,8 +608,6 @@ olsrd_print_cnf(struct olsrd_config *cnf)
   struct olsr_if *in = cnf->interfaces;
   struct plugin_entry *pe = cnf->plugins;
   struct ip_prefix_list *ie = cnf->ipc_nets;
-  struct olsr_lq_mult *mult;
-  char ipv6_buf[INET6_ADDRSTRLEN];                  /* buffer for IPv6 inet_htop */
 
   printf(" *** olsrd configuration ***\n");
 
@@ -632,11 +675,6 @@ olsrd_print_cnf(struct olsrd_config *cnf)
         printf(" dev: \"%s\"\n", in->name);
 
         olsrd_print_interface_cnf(in->cnf, in->cnfi, false);
-
-        for (mult = in->cnf->lq_mult; mult != NULL; mult = mult->next) {
-          printf("\tLinkQualityMult          : %s %0.2f\n", inet_ntop(cnf->ip_version, &mult->addr, ipv6_buf, sizeof(ipv6_buf)),
-             (float)(mult->value) / 65536.0);
-        }
       }
       in = in->next;
     }