Support "InterfaceDefaults" section in olsrd.conf
authorHenning Rogge <hrogge@googlemail.com>
Sat, 26 Dec 2009 10:05:47 +0000 (11:05 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Sat, 26 Dec 2009 10:05:47 +0000 (11:05 +0100)
src/cfgparser/olsrd_conf.c
src/cfgparser/oparse.y
src/cfgparser/oscan.lex
src/main.c
src/olsr_cfg.h

index d71e2a1..6e19cc7 100644 (file)
@@ -46,6 +46,7 @@
 #include "net_olsr.h"
 #include "olsr.h"
 
+#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
@@ -287,15 +288,37 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
          fprintf(stderr, "Warning, you are using the min_tc_vtime hack. We hope you know what you are doing... contact olsr.org otherwise.\n");
   }
 
+  if (cnf->interface_defaults == NULL) {
+    /* get a default configuration if the user did not specify one */
+    cnf->interface_defaults = get_default_if_config();
+  }
+
   /* Interfaces */
   while (in) {
     struct olsr_lq_mult *mult;
 
     io = in->cnf;
 
-    if (in->name == NULL || !strlen(in->name)) {
-      fprintf(stderr, "Interface has no name!\n");
-      return -1;
+    /*apply defaults (if this is not the default interface stub)*/
+    if (in->cnf != cnf->interface_defaults)
+    {
+      size_t pos;
+      uint8_t *cnfptr = (uint8_t*)in->cnf;
+      uint8_t *cnfiptr = (uint8_t*)in->cnfi;
+      uint8_t *defptr = (uint8_t*)cnf->interface_defaults;
+
+      assert(in->cnf);
+      assert(in->cnfi);
+      for (pos = 0; pos < sizeof(*in->cnf); pos++) {
+        if (cnfptr[pos] != cnfiptr[pos]) {
+          cnfptr[pos] = defptr[pos]; cnfiptr[pos]=0x00;
+        }
+      }
+
+      if (in->name == NULL || !strlen(in->name)) {
+        fprintf(stderr, "Interface has no name!\n");
+        return -1;
+      }
     }
 
     if (io == NULL) {
@@ -314,14 +337,15 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
     }
 
     if (io->hello_params.emission_interval < cnf->pollrate || io->hello_params.emission_interval > io->hello_params.validity_time) {
-      fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f)\n", io->hello_params.emission_interval,
-              io->hello_params.validity_time);
+      fprintf(stderr, "Bad HELLO parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", io->hello_params.emission_interval,
+              io->hello_params.validity_time, in->name);
       return -1;
     }
 
     /* TC interval */
     if (io->tc_params.emission_interval < cnf->pollrate || io->tc_params.emission_interval > io->tc_params.validity_time) {
-      fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f)\n", io->tc_params.emission_interval, io->tc_params.validity_time);
+      fprintf(stderr, "Bad TC parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", io->tc_params.emission_interval,
+          io->tc_params.validity_time, in->name);
       return -1;
     }
 
@@ -331,15 +355,15 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
     }
     /* MID interval */
     if (io->mid_params.emission_interval < cnf->pollrate || io->mid_params.emission_interval > io->mid_params.validity_time) {
-      fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f)\n", io->mid_params.emission_interval,
-              io->mid_params.validity_time);
+      fprintf(stderr, "Bad MID parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", io->mid_params.emission_interval,
+              io->mid_params.validity_time, in->name);
       return -1;
     }
 
     /* HNA interval */
     if (io->hna_params.emission_interval < cnf->pollrate || io->hna_params.emission_interval > io->hna_params.validity_time) {
-      fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f)\n", io->hna_params.emission_interval,
-              io->hna_params.validity_time);
+      fprintf(stderr, "Bad HNA parameters! (em: %0.2f, vt: %0.2f) for dev %s\n", io->hna_params.emission_interval,
+              io->hna_params.validity_time, in->name);
       return -1;
     }
 
@@ -379,10 +403,11 @@ olsrd_free_cnf(struct olsrd_config *cnf)
     }
 
     free(in->cnf);
+    free(in->cnfi);
+
     ind = in;
     in = in->next;
-    free(ind->name);
-    free(ind->config);
+
     free(ind);
   }
 
index fbfb4db..0bc0b1f 100644 (file)
 #define PARSER_DEBUG_PRINTF(x, ...)   do { } while (0)
 #endif
 
+static char interface_defaults_name[] = "[InterfaceDefaults]";
+
+#define SET_IFS_CONF(ifs, ifcnt, field, value) do { \
+       for (; ifcnt>0; ifs=ifs->next, ifcnt--) { \
+    ifs->cnfi->field = (value); \
+    ifs->cnf->field = (value); \
+       } \
+} while (0)
+
 #define YYSTYPE struct conf_token *
 
 void yyerror(const char *);
@@ -71,7 +80,6 @@ int yylex(void);
 
 static int ifs_in_curr_cfg = 0;
 
-static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg);
 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg);
 
 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
@@ -107,7 +115,7 @@ static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
     mult->value = (uint32_t)(mult_arg->floating * LINK_LOSS_MULTIPLIER);
 
     mult->next = walker->cnf->lq_mult;
-    walker->cnf->lq_mult = mult;
+    walker->cnf->lq_mult = walker->cnf->lq_mult = mult;
 
     walker = walker->next;
   }
@@ -170,6 +178,7 @@ static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
 %token TOK_HNA4
 %token TOK_HNA6
 %token TOK_PLUGIN
+%token TOK_INTERFACE_DEFAULTS
 %token TOK_INTERFACE
 %token TOK_NOINT
 %token TOK_TOS
@@ -269,6 +278,7 @@ stmt:       idebug
 block:      TOK_HNA4 hna4body
           | TOK_HNA6 hna6body
           | TOK_IPCCON ipcbody
+          | ifdblock ifbody
           | ifblock ifbody
           | plblock plbody
 ;
@@ -347,6 +357,34 @@ plstmt:     plparam
           | vcomment
 ;
 
+ifdblock: TOK_INTERFACE_DEFAULTS
+{
+  struct olsr_if *in = malloc(sizeof(*in));
+
+  if (in == NULL) {
+    fprintf(stderr, "Out of memory(ADD IF)\n");
+    YYABORT;
+  }
+
+  in->cnf = get_default_if_config();
+  in->cnfi = get_default_if_config();
+
+  if (in->cnf == NULL || in->cnfi == NULL) {
+    fprintf(stderr, "Out of memory(ADD DEFIFRULE)\n");
+    YYABORT;
+  }
+
+  in->name = strdup(interface_defaults_name);
+
+  olsr_cnf->interface_defaults = in->cnf;
+
+  /* Queue */
+  in->next = olsr_cnf->interfaces;
+  olsr_cnf->interfaces = in;
+  ifs_in_curr_cfg=1;
+}
+;
+
 imaxipc: TOK_MAXIPC TOK_INTEGER
 {
   olsr_cnf->ipc_connections = $2->integer;
@@ -428,6 +466,8 @@ iifweight:       TOK_IFWEIGHT TOK_INTEGER
   while (ifcnt) {
     ifs->cnf->weight.value = $2->integer;
     ifs->cnf->weight.fixed = true;
+    ifs->cnfi->weight.value = $2->integer;
+    ifs->cnfi->weight.fixed = true;
 
     ifs = ifs->next;
     ifcnt--;
@@ -441,15 +481,12 @@ isetifmode: TOK_IFMODE TOK_STRING
 {
   int ifcnt = ifs_in_curr_cfg;
   struct olsr_if *ifs = olsr_cnf->interfaces;
+       int mode = (strcmp($2->string, "ether") == 0)?IF_MODE_ETHER:IF_MODE_MESH;
 
   PARSER_DEBUG_PRINTF("\tMode: %d\n", $2->string);
-    while (ifcnt) {
-      ifs->cnf->mode = (strcmp($2->string, "ether") == 0)?IF_MODE_ETHER:IF_MODE_MESH;
-
-      ifs = ifs->next;
-      ifcnt--;
-    }
 
+       SET_IFS_CONF(ifs, ifcnt, mode, mode);
+       
   free($2->string);
   free($2);
 }
@@ -468,12 +505,7 @@ isetipv4br: TOK_IPV4BROADCAST TOK_IPV4_ADDR
     YYABORT;
   }
 
-  while (ifcnt) {
-    ifs->cnf->ipv4_multicast.v4 = in;
-
-    ifs = ifs->next;
-    ifcnt--;
-  }
+       SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
 
   free($2->string);
   free($2);
@@ -493,12 +525,7 @@ isetipv4mc: TOK_IPV4MULTICAST TOK_IPV4_ADDR
     YYABORT;
   }
 
-  while (ifcnt) {
-    ifs->cnf->ipv4_multicast.v4 = in;
-
-    ifs = ifs->next;
-    ifcnt--;
-  }
+       SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
 
   free($2->string);
   free($2);
@@ -518,12 +545,7 @@ isetipv6mc: TOK_IPV6MULTICAST TOK_IPV6_ADDR
     YYABORT;
   }
 
-  while (ifcnt) {
-    ifs->cnf->ipv6_multicast.v6 = in6;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+       SET_IFS_CONF(ifs, ifcnt, ipv6_multicast.v6, in6);
 
   free($2->string);
   free($2);
@@ -543,12 +565,7 @@ isetipv4src: TOK_IPV4SRC TOK_IPV4_ADDR
     YYABORT;
   }
 
-  while (ifcnt) {
-    ifs->cnf->ipv4_src.v4 = in;
-
-    ifs = ifs->next;
-    ifcnt--;
-  }
+       SET_IFS_CONF(ifs, ifcnt, ipv4_src.v4, in);
 
   free($2->string);
   free($2);
@@ -568,12 +585,7 @@ isetipv6src: TOK_IPV6SRC TOK_IPV6_ADDR
     YYABORT;
   }
 
-  while (ifcnt) {
-    ifs->cnf->ipv6_src = pr6;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+       SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
 
   free($2->string);
   free($2);
@@ -587,12 +599,7 @@ isethelloint: TOK_HELLOINT TOK_FLOAT
 
   PARSER_DEBUG_PRINTF("\tHELLO interval: %0.2f\n", $2->floating);
 
-  while (ifcnt) {
-    ifs->cnf->hello_params.emission_interval = $2->floating;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+       SET_IFS_CONF(ifs, ifcnt, hello_params.emission_interval, $2->floating);
 
   free($2);
 }
@@ -604,12 +611,7 @@ isethelloval: TOK_HELLOVAL TOK_FLOAT
 
   PARSER_DEBUG_PRINTF("\tHELLO validity: %0.2f\n", $2->floating);
 
-  while (ifcnt) {
-    ifs->cnf->hello_params.validity_time = $2->floating;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+       SET_IFS_CONF(ifs, ifcnt, hello_params.validity_time, $2->floating);
 
   free($2);
 }
@@ -621,12 +623,8 @@ isettcint: TOK_TCINT TOK_FLOAT
 
   PARSER_DEBUG_PRINTF("\tTC interval: %0.2f\n", $2->floating);
 
-  while (ifcnt) {
-    ifs->cnf->tc_params.emission_interval = $2->floating;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+       SET_IFS_CONF(ifs, ifcnt, tc_params.emission_interval, $2->floating);
+
   free($2);
 }
 ;
@@ -636,12 +634,8 @@ isettcval: TOK_TCVAL TOK_FLOAT
   struct olsr_if *ifs = olsr_cnf->interfaces;
   
   PARSER_DEBUG_PRINTF("\tTC validity: %0.2f\n", $2->floating);
-  while (ifcnt) {
-    ifs->cnf->tc_params.validity_time = $2->floating;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+  
+ SET_IFS_CONF(ifs, ifcnt, tc_params.validity_time, $2->floating);
 
   free($2);
 }
@@ -653,12 +647,8 @@ isetmidint: TOK_MIDINT TOK_FLOAT
 
 
   PARSER_DEBUG_PRINTF("\tMID interval: %0.2f\n", $2->floating);
-  while (ifcnt) {
-    ifs->cnf->mid_params.emission_interval = $2->floating;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+  
+  SET_IFS_CONF(ifs, ifcnt, mid_params.emission_interval, $2->floating);
 
   free($2);
 }
@@ -669,12 +659,8 @@ isetmidval: TOK_MIDVAL TOK_FLOAT
   struct olsr_if *ifs = olsr_cnf->interfaces;
 
   PARSER_DEBUG_PRINTF("\tMID validity: %0.2f\n", $2->floating);
-  while (ifcnt) {
-    ifs->cnf->mid_params.validity_time = $2->floating;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+  
+  SET_IFS_CONF(ifs, ifcnt, mid_params.validity_time, $2->floating);
 
   free($2);
 }
@@ -685,12 +671,8 @@ isethnaint: TOK_HNAINT TOK_FLOAT
   struct olsr_if *ifs = olsr_cnf->interfaces;
   
   PARSER_DEBUG_PRINTF("\tHNA interval: %0.2f\n", $2->floating);
-  while (ifcnt) {
-    ifs->cnf->hna_params.emission_interval = $2->floating;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+
+  SET_IFS_CONF(ifs, ifcnt, hna_params.emission_interval, $2->floating);
 
   free($2);
 }
@@ -701,12 +683,8 @@ isethnaval: TOK_HNAVAL TOK_FLOAT
   struct olsr_if *ifs = olsr_cnf->interfaces;
 
   PARSER_DEBUG_PRINTF("\tHNA validity: %0.2f\n", $2->floating);
-  while (ifcnt) {
-    ifs->cnf->hna_params.validity_time = $2->floating;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+
+  SET_IFS_CONF(ifs, ifcnt, hna_params.validity_time, $2->floating);
 
   free($2);
 }
@@ -717,12 +695,8 @@ isetautodetchg: TOK_AUTODETCHG TOK_BOOLEAN
   struct olsr_if *ifs = olsr_cnf->interfaces;
 
   PARSER_DEBUG_PRINTF("\tAutodetect changes: %s\n", $2->boolean ? "YES" : "NO");
-  while (ifcnt) {
-    ifs->cnf->autodetect_chg = $2->boolean;
-      
-    ifs = ifs->next;
-    ifcnt--;
-  }
+
+  SET_IFS_CONF(ifs, ifcnt, autodetect_chg, $2->boolean);
 
   free($2);
 }
@@ -893,12 +867,19 @@ ifnick: TOK_STRING
     YYABORT;
   }
 
-  in->cnf = get_default_if_config();
-
+  in->cnf = malloc(sizeof(*in->cnf));
+  if (in->cnf == NULL) {
+    fprintf(stderr, "Out of memory(ADD IFRULE)\n");
+    YYABORT;
+  }
+  memset(in->cnf, 0x00, sizeof(*in->cnf));
+  in->cnfi = malloc(sizeof(*in->cnfi));
   if (in->cnf == NULL) {
     fprintf(stderr, "Out of memory(ADD IFRULE)\n");
     YYABORT;
   }
+  memset(in->cnfi, 0xFF, sizeof(*in->cnfi));
 
   in->name = $1->string;
 
index 810b7ff..75a68e0 100644 (file)
@@ -286,6 +286,10 @@ IPV6ADDR {IPV6PAT1}|{IPV6PAT2}|{IPV6PAT3}|{IPV6PAT4}|{IPV6PAT5}|{IPV6PAT6}|{IPV6
     yylval = NULL;
     return TOK_INTERFACE;
 }
+"InterfaceDefaults" {
+    yylval = NULL;
+    return TOK_INTERFACE_DEFAULTS;
+}
 
 "AllowNoInt" {
     yylval = NULL;
index 2ba500d..89fe10f 100644 (file)
@@ -644,7 +644,7 @@ static void olsr_shutdown(int signo __attribute__ ((unused)))
   OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);
 
   exit_value = olsr_cnf->exit_value;
-  free (olsr_cnf);
+  olsrd_free_cnf(olsr_cnf);
 
   exit(exit_value);
 }
index a0ee5c3..d8a2639 100644 (file)
@@ -158,12 +158,11 @@ struct if_config_options {
 
 struct olsr_if {
   char *name;
-  char *config;
   bool configured;
   bool host_emul;
   union olsr_ip_addr hemu_ip;
   struct interface *interf;
-  struct if_config_options *cnf;
+  struct if_config_options *cnf, *cnfi;
   struct olsr_if *next;
 };
 
@@ -220,6 +219,7 @@ struct olsrd_config {
   struct plugin_entry *plugins;
   struct ip_prefix_list *hna_entries;
   struct ip_prefix_list *ipc_nets;
+  struct if_config_options *interface_defaults;
   struct olsr_if *interfaces;
   float pollrate;
   float nic_chgs_pollrate;