Makefile: WARNINGS: add -Wdouble-promotion
[olsrd.git] / src / cfgparser / oparse.y
1 %{
2
3 /*
4  * The olsr.org Optimized Link-State Routing daemon(olsrd)
5  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without 
9  * modification, are permitted provided that the following conditions 
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright 
13  *   notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  *   notice, this list of conditions and the following disclaimer in 
16  *   the documentation and/or other materials provided with the 
17  *   distribution.
18  * * Neither the name of olsr.org, olsrd nor the names of its 
19  *   contributors may be used to endorse or promote products derived 
20  *   from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Visit http://www.olsr.org for more information.
36  *
37  * If you find this software useful feel free to make a donation
38  * to the project. For more information see the website or contact
39  * the copyright holders.
40  *
41  */
42
43
44 #include "olsrd_conf.h"
45 #include "../defs.h"
46 #include "../ipcalc.h"
47 #include "../net_olsr.h"
48 #include "../link_set.h"
49 #include "../olsr.h"
50
51 #include <stddef.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <sys/types.h>
55 #include <sys/socket.h>
56 #include <netinet/in.h>
57 #include <arpa/inet.h>
58 #include <string.h>
59
60 #define PARSER_DEBUG 1
61
62 #if PARSER_DEBUG
63 #define PARSER_DEBUG_PRINTF(x, args...)   printf(x, ##args)
64 #else
65 #define PARSER_DEBUG_PRINTF(x, args...)   do { } while (0)
66 #endif
67
68 #define SET_IFS_CONF(ifs, ifcnt, field, value) do { \
69         for (; ifcnt>0; ifs=ifs->next, ifcnt--) { \
70     ifs->cnfi->field = (value); \
71     ifs->cnf->field = (value); \
72         } \
73 } while (0)
74
75 #define YYSTYPE struct conf_token *
76
77 void yyerror(const char *);
78 int yylex(void);
79
80 static int ifs_in_curr_cfg = 0;
81
82 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg);
83
84 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
85 {
86   union olsr_ip_addr addr;
87   int i;
88   struct olsr_if *walker;
89
90 #if PARSER_DEBUG > 0
91   printf("\tLinkQualityMult %s %0.2f\n",
92          (ip_addr_arg != NULL) ? ip_addr_arg->string : "any",
93          (double)mult_arg->floating);
94 #endif
95
96   memset(&addr, 0, sizeof(addr));
97
98   if (ip_addr_arg != NULL &&
99      inet_pton(olsr_cnf->ip_version, ip_addr_arg->string, &addr) <= 0) {
100     fprintf(stderr, "Cannot parse IP address %s.\n", ip_addr_arg->string);
101     return -1;
102   }
103
104   walker = olsr_cnf->interfaces;
105
106   for (i = 0; i < ifs_in_curr_cfg; i++) {
107     struct olsr_lq_mult *mult = malloc(sizeof(*mult));
108     if (mult == NULL) {
109       fprintf(stderr, "Out of memory (LQ multiplier).\n");
110       return -1;
111     }
112
113     mult->addr = addr;
114     mult->value = (uint32_t)(mult_arg->floating * LINK_LOSS_MULTIPLIER);
115
116     mult->next = walker->cnf->lq_mult;
117     walker->cnfi->lq_mult = walker->cnf->lq_mult = mult;
118     walker->cnf->orig_lq_mult_cnt++;
119     walker->cnfi->orig_lq_mult_cnt=walker->cnf->orig_lq_mult_cnt;
120
121     walker = walker->next;
122   }
123
124   if (ip_addr_arg != NULL) {
125     free(ip_addr_arg->string);
126     free(ip_addr_arg);
127   }
128
129   free(mult_arg);
130
131   return 0;
132 }
133
134 static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
135 {
136   union olsr_ip_addr ipaddr;
137   PARSER_DEBUG_PRINTF("HNA IPv6 entry: %s/%d\n", ipaddr_arg->string, prefixlen_arg->integer);
138
139   if (olsr_cnf->ip_version != AF_INET6) {
140     fprintf(stderr, "IPv6 addresses can only be used if \"IpVersion\" == 6, skipping HNA6.\n");
141     olsr_startup_sleep(3);
142   }
143         else {
144           if(inet_pton(AF_INET6, ipaddr_arg->string, &ipaddr) <= 0) {
145       fprintf(stderr, "ihna6entry: Failed converting IP address %s\n", ipaddr_arg->string);
146       return 1;
147     }
148
149                 if (prefixlen_arg->integer > 128) {
150                         fprintf(stderr, "ihna6entry: Illegal IPv6 prefix length %d\n", prefixlen_arg->integer);
151                         return 1;
152                 }
153
154                 /* Queue */
155                 ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, prefixlen_arg->integer);
156         }
157   free(ipaddr_arg->string);
158   free(ipaddr_arg);
159   free(prefixlen_arg);
160
161   return 0;
162 }
163
164 %}
165
166 %token TOK_SLASH
167 %token TOK_OPEN
168 %token TOK_CLOSE
169
170 %token TOK_STRING
171 %token TOK_INTEGER
172 %token TOK_FLOAT
173 %token TOK_BOOLEAN
174
175 %token TOK_IPV6TYPE
176
177 %token TOK_DEBUGLEVEL
178 %token TOK_IPVERSION
179 %token TOK_HNA4
180 %token TOK_HNA6
181 %token TOK_PLUGIN
182 %token TOK_INTERFACE_DEFAULTS
183 %token TOK_INTERFACE
184 %token TOK_NOINT
185 %token TOK_TOS
186 %token TOK_OLSRPORT
187 %token TOK_RTPROTO
188 %token TOK_RTTABLE
189 %token TOK_RTTABLE_DEFAULT
190 %token TOK_RTTABLE_TUNNEL
191 %token TOK_RTTABLE_PRIORITY
192 %token TOK_RTTABLE_DEFAULTOLSR_PRIORITY
193 %token TOK_RTTABLE_TUNNEL_PRIORITY
194 %token TOK_RTTABLE_DEFAULT_PRIORITY
195 %token TOK_WILLINGNESS
196 %token TOK_IPCCON
197 %token TOK_FIBMETRIC
198 %token TOK_USEHYST
199 %token TOK_HYSTSCALE
200 %token TOK_HYSTUPPER
201 %token TOK_HYSTLOWER
202 %token TOK_POLLRATE
203 %token TOK_NICCHGSPOLLRT
204 %token TOK_TCREDUNDANCY
205 %token TOK_MPRCOVERAGE
206 %token TOK_LQ_LEVEL
207 %token TOK_LQ_FISH
208 %token TOK_LQ_AGING
209 %token TOK_LQ_PLUGIN
210 %token TOK_LQ_NAT_THRESH
211 %token TOK_LQ_MULT
212 %token TOK_CLEAR_SCREEN
213 %token TOK_PLPARAM
214 %token TOK_MIN_TC_VTIME
215 %token TOK_LOCK_FILE
216 %token TOK_USE_NIIT
217 %token TOK_SMART_GW
218 %token TOK_SMART_GW_ALLOW_NAT
219 %token TOK_SMART_GW_PERIOD
220 %token TOK_SMART_GW_STABLECOUNT
221 %token TOK_SMART_GW_THRESH
222 %token TOK_SMART_GW_UPLINK
223 %token TOK_SMART_GW_UPLINK_NAT
224 %token TOK_SMART_GW_SPEED
225 %token TOK_SMART_GW_PREFIX
226 %token TOK_SRC_IP_ROUTES
227 %token TOK_MAIN_IP
228 %token TOK_SET_IPFORWARD
229
230 %token TOK_HOSTLABEL
231 %token TOK_NETLABEL
232 %token TOK_MAXIPC
233
234 %token TOK_IFMODE
235 %token TOK_IPV4MULTICAST
236 %token TOK_IP4BROADCAST
237 %token TOK_IPV4BROADCAST
238 %token TOK_IPV6MULTICAST
239 %token TOK_IPV4SRC
240 %token TOK_IPV6SRC
241 %token TOK_IFWEIGHT
242 %token TOK_HELLOINT
243 %token TOK_HELLOVAL
244 %token TOK_TCINT
245 %token TOK_TCVAL
246 %token TOK_MIDINT
247 %token TOK_MIDVAL
248 %token TOK_HNAINT
249 %token TOK_HNAVAL
250 %token TOK_AUTODETCHG
251
252 %token TOK_IPV4_ADDR
253 %token TOK_IPV6_ADDR
254 %token TOK_DEFAULT
255 %token TOK_AUTO
256 %token TOK_NONE
257
258 %token TOK_COMMENT
259
260 %%
261
262 conf:
263           | conf block
264           | conf stmt
265 ;
266
267 stmt:       idebug
268           | iipversion
269           | fibmetric
270           | bnoint
271           | atos
272           | aolsrport
273           | irtproto
274           | irttable
275           | irttable_default
276           | irttable_tunnel
277           | irttable_priority
278           | irttable_defaultolsr_priority
279           | irttable_tunnel_priority
280           | irttable_default_priority
281           | awillingness
282           | busehyst
283           | fhystscale
284           | fhystupper
285           | fhystlower
286           | fpollrate
287           | fnicchgspollrt
288           | atcredundancy
289           | amprcoverage
290           | alq_level
291           | alq_plugin
292           | alq_fish
293           | anat_thresh
294           | alq_aging
295           | bclear_screen
296           | vcomment
297           | amin_tc_vtime
298           | alock_file
299           | suse_niit
300           | bsmart_gw
301           | bsmart_gw_allow_nat
302           | ismart_gw_period
303           | asmart_gw_stablecount
304           | asmart_gw_thresh
305           | ssmart_gw_uplink
306           | bsmart_gw_uplink_nat
307           | ismart_gw_speed
308           | ismart_gw_prefix
309           | bsrc_ip_routes
310           | amain_ip
311           | bset_ipforward
312 ;
313
314 block:      TOK_HNA4 hna4body
315           | TOK_HNA6 hna6body
316           | TOK_IPCCON ipcbody
317           | ifdblock ifdbody
318           | ifblock ifbody
319           | plblock plbody
320 ;
321
322 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
323 ;
324
325 hna4stmts: | hna4stmts hna4stmt
326 ;
327
328 hna4stmt:  vcomment
329          | ihna4entry
330 ;
331
332 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
333 ;
334
335 hna6stmts: | hna6stmts hna6stmt
336 ;
337
338 hna6stmt:  vcomment
339          | ihna6entry
340 ;
341
342 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
343 ;
344
345 ipcstmts: | ipcstmts ipcstmt
346 ;
347
348 ipcstmt:  vcomment
349           | imaxipc
350           | ipchost
351           | ipcnet
352 ;
353
354 ifblock:   ifstart ifnicks
355 ;
356
357 ifnicks:   | ifnicks ifnick
358 ;
359
360 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
361 ;
362
363 ifdbody:     TOK_OPEN ifstmts TOK_CLOSE
364 {
365   struct olsr_if *in = olsr_cnf->interfaces;
366   printf("\nInterface Defaults");
367   /*remove Interface Defaults from Interface list as they are no interface!*/
368   olsr_cnf->interfaces = in->next;
369   ifs_in_curr_cfg=0;
370   /*free interface but keep its config intact?*/
371   free(in->cnfi);
372   free(in);
373
374 }
375 ;
376
377 ifstmts:   | ifstmts ifstmt
378 ;
379
380 ifstmt:      vcomment
381              | iifweight
382              | isetifmode
383              | TOK_IP4BROADCAST isetipv4mc
384              | TOK_IPV4BROADCAST isetipv4mc
385              | TOK_IPV4MULTICAST isetipv4mc
386              | isetipv6mc
387              | isetipv4src
388              | isetipv6src
389              | isethelloint
390              | isethelloval
391              | isettcint
392              | isettcval
393              | isetmidint
394              | isetmidval
395              | isethnaint
396              | isethnaval
397              | isetautodetchg
398              | isetlqmult
399 ;
400
401 plbody:     TOK_OPEN plstmts TOK_CLOSE
402 ;
403
404 plstmts:   | plstmts plstmt
405 ;
406
407 plstmt:     plparam
408           | vcomment
409 ;
410
411 ifdblock: TOK_INTERFACE_DEFAULTS
412 {
413   struct olsr_if *in = malloc(sizeof(*in));
414
415   if (in == NULL) {
416     fprintf(stderr, "Out of memory(ADD IF)\n");
417     YYABORT;
418   }
419
420   in->cnf = get_default_if_config();
421   in->cnfi = get_default_if_config();
422
423   if (in->cnf == NULL || in->cnfi == NULL) {
424     fprintf(stderr, "Out of memory(ADD DEFIFRULE)\n");
425     YYABORT;
426   }
427
428   //should not need a name any more, as we free it on "}" again
429   //in->name = strdup(interface_defaults_name);
430
431   olsr_cnf->interface_defaults = in->cnf;
432
433   /* Queue */
434   in->next = olsr_cnf->interfaces;
435   olsr_cnf->interfaces = in;
436   ifs_in_curr_cfg=1;
437   
438   fflush(stdout);
439 }
440 ;
441
442 imaxipc: TOK_MAXIPC TOK_INTEGER
443 {
444   olsr_cnf->ipc_connections = $2->integer;
445   free($2);
446 }
447 ;
448
449 ipchost: TOK_HOSTLABEL TOK_IPV4_ADDR
450 {
451   union olsr_ip_addr ipaddr;
452   PARSER_DEBUG_PRINTF("\tIPC host: %s\n", $2->string);
453   
454   if (inet_aton($2->string, &ipaddr.v4) == 0) {
455     fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
456     YYABORT;
457   }
458
459   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_cnf->maxplen);
460
461   free($2->string);
462   free($2);
463 }
464 ;
465
466 ipcnet: TOK_NETLABEL TOK_IPV4_ADDR TOK_IPV4_ADDR
467 {
468   union olsr_ip_addr ipaddr, netmask;
469
470   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
471   
472   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
473     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
474     YYABORT;
475   }
476
477   if (inet_pton(AF_INET, $3->string, &netmask.v4) == 0) {
478     fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
479     YYABORT;
480   }
481
482   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_netmask_to_prefix(&netmask));
483
484   free($2->string);
485   free($2);
486   free($3->string);
487   free($3);
488 }
489         |       TOK_NETLABEL TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
490 {
491   union olsr_ip_addr ipaddr;
492
493   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
494   
495   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
496     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
497     YYABORT;
498   }
499
500   if ($4->integer > olsr_cnf->maxplen) {
501     fprintf(stderr, "ipcnet: Prefix len %u > %d is not allowed!\n", $4->integer, olsr_cnf->maxplen);
502     YYABORT;
503   }
504
505   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, $4->integer);
506
507   free($2->string);
508   free($2);
509   free($4);
510 }
511 ;
512
513 iifweight:       TOK_IFWEIGHT TOK_INTEGER
514 {
515   int ifcnt = ifs_in_curr_cfg;
516   struct olsr_if *ifs = olsr_cnf->interfaces;
517
518   PARSER_DEBUG_PRINTF("Fixed willingness: %d\n", $2->integer);
519
520   while (ifcnt) {
521     ifs->cnf->weight.value = $2->integer;
522     ifs->cnf->weight.fixed = true;
523     ifs->cnfi->weight.value = $2->integer;
524     ifs->cnfi->weight.fixed = true;
525
526     ifs = ifs->next;
527     ifcnt--;
528   }
529
530   free($2);
531 }
532 ;
533
534 isetifmode: TOK_IFMODE TOK_STRING
535 {
536   int ifcnt = ifs_in_curr_cfg;
537   struct olsr_if *ifs = olsr_cnf->interfaces;
538         int mode = (strcmp($2->string, "ether") == 0)?IF_MODE_ETHER:IF_MODE_MESH;
539
540   PARSER_DEBUG_PRINTF("\tMode: %s\n", $2->string);
541
542         SET_IFS_CONF(ifs, ifcnt, mode, mode);
543         
544   free($2->string);
545   free($2);
546 }
547 ;
548
549 /* called if prepended with TOK_IPV4MULTICAST TOK_IP4BROADCAST TOK_IPV4BROADCAST */
550 isetipv4mc: TOK_IPV4_ADDR
551 {
552   struct in_addr in;
553   int ifcnt = ifs_in_curr_cfg;
554   struct olsr_if *ifs = olsr_cnf->interfaces;
555
556   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $1->string);
557
558   if (inet_aton($1->string, &in) == 0) {
559     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $1->string);
560     YYABORT;
561   }
562
563         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
564
565   free($1->string);
566   free($1);
567 }
568 ;
569
570 isetipv6mc: TOK_IPV6MULTICAST TOK_IPV6_ADDR
571 {
572   struct in6_addr in6;
573   int ifcnt = ifs_in_curr_cfg;
574   struct olsr_if *ifs = olsr_cnf->interfaces;
575
576   PARSER_DEBUG_PRINTF("\tIPv6 multicast: %s\n", $2->string);
577
578   if (inet_pton(AF_INET6, $2->string, &in6) <= 0) {
579     fprintf(stderr, "isetipv6mc: Failed converting IP address %s\n", $2->string);
580     YYABORT;
581   }
582
583         SET_IFS_CONF(ifs, ifcnt, ipv6_multicast.v6, in6);
584
585   free($2->string);
586   free($2);
587 }
588 ;
589
590 isetipv4src: TOK_IPV4SRC TOK_IPV4_ADDR
591 {
592   struct in_addr in;
593   int ifcnt = ifs_in_curr_cfg;
594   struct olsr_if *ifs = olsr_cnf->interfaces;
595
596   PARSER_DEBUG_PRINTF("\tIPv4 src: %s\n", $2->string);
597
598   if (inet_aton($2->string, &in) == 0) {
599     fprintf(stderr, "isetipv4src: Failed converting IP address %s\n", $2->string);
600     YYABORT;
601   }
602
603         SET_IFS_CONF(ifs, ifcnt, ipv4_src.v4, in);
604
605   free($2->string);
606   free($2);
607 }
608 ;
609
610 isetipv6src: TOK_IPV6SRC TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
611 {
612   struct olsr_ip_prefix pr6;
613   int ifcnt = ifs_in_curr_cfg;
614   struct olsr_if *ifs = olsr_cnf->interfaces;
615
616   PARSER_DEBUG_PRINTF("\tIPv6 src prefix: %s/%d\n", $2->string, $4->integer);
617
618   if (inet_pton(AF_INET6, $2->string, &pr6.prefix.v6) <= 0) {
619     fprintf(stderr, "isetipv6src: Failed converting IP address %s\n", $2->string);
620     YYABORT;
621   }
622   if ($4->integer > 128) {
623     fprintf(stderr, "isetipv6src: Illegal Prefixlength %d\n", $4->integer);
624     YYABORT;
625   }
626   pr6.prefix_len = $4->integer;
627
628         SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
629
630   free($2->string);
631   free($2);
632 }
633         | TOK_IPV6SRC TOK_IPV6_ADDR
634 {
635   struct olsr_ip_prefix pr6;
636   int ifcnt = ifs_in_curr_cfg;
637   struct olsr_if *ifs = olsr_cnf->interfaces;
638
639   PARSER_DEBUG_PRINTF("\tIPv6 src prefix: %s/%d\n", $2->string, 128);
640
641   if (inet_pton(AF_INET6, $2->string, &pr6.prefix.v6) <= 0) {
642     fprintf(stderr, "isetipv6src: Failed converting IP address %s\n", $2->string);
643     YYABORT;
644   }
645   pr6.prefix_len = 128;
646
647   SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
648
649   free($2->string);
650   free($2);
651 }
652 ;
653
654 isethelloint: TOK_HELLOINT TOK_FLOAT
655 {
656   int ifcnt = ifs_in_curr_cfg;
657   struct olsr_if *ifs = olsr_cnf->interfaces;
658
659   PARSER_DEBUG_PRINTF("\tHELLO interval: %0.2f\n", (double)$2->floating);
660
661         SET_IFS_CONF(ifs, ifcnt, hello_params.emission_interval, $2->floating);
662
663   free($2);
664 }
665 ;
666 isethelloval: TOK_HELLOVAL TOK_FLOAT
667 {
668   int ifcnt = ifs_in_curr_cfg;
669   struct olsr_if *ifs = olsr_cnf->interfaces;
670
671   PARSER_DEBUG_PRINTF("\tHELLO validity: %0.2f\n", (double)$2->floating);
672
673         SET_IFS_CONF(ifs, ifcnt, hello_params.validity_time, $2->floating);
674
675   free($2);
676 }
677 ;
678 isettcint: TOK_TCINT TOK_FLOAT
679 {
680   int ifcnt = ifs_in_curr_cfg;
681   struct olsr_if *ifs = olsr_cnf->interfaces;
682
683   PARSER_DEBUG_PRINTF("\tTC interval: %0.2f\n", (double)$2->floating);
684
685         SET_IFS_CONF(ifs, ifcnt, tc_params.emission_interval, $2->floating);
686
687   free($2);
688 }
689 ;
690 isettcval: TOK_TCVAL TOK_FLOAT
691 {
692   int ifcnt = ifs_in_curr_cfg;
693   struct olsr_if *ifs = olsr_cnf->interfaces;
694   
695   PARSER_DEBUG_PRINTF("\tTC validity: %0.2f\n", (double)$2->floating);
696   
697  SET_IFS_CONF(ifs, ifcnt, tc_params.validity_time, $2->floating);
698
699   free($2);
700 }
701 ;
702 isetmidint: TOK_MIDINT TOK_FLOAT
703 {
704   int ifcnt = ifs_in_curr_cfg;
705   struct olsr_if *ifs = olsr_cnf->interfaces;
706
707
708   PARSER_DEBUG_PRINTF("\tMID interval: %0.2f\n", (double)$2->floating);
709   
710   SET_IFS_CONF(ifs, ifcnt, mid_params.emission_interval, $2->floating);
711
712   free($2);
713 }
714 ;
715 isetmidval: TOK_MIDVAL TOK_FLOAT
716 {
717   int ifcnt = ifs_in_curr_cfg;
718   struct olsr_if *ifs = olsr_cnf->interfaces;
719
720   PARSER_DEBUG_PRINTF("\tMID validity: %0.2f\n", (double)$2->floating);
721   
722   SET_IFS_CONF(ifs, ifcnt, mid_params.validity_time, $2->floating);
723
724   free($2);
725 }
726 ;
727 isethnaint: TOK_HNAINT TOK_FLOAT
728 {
729   int ifcnt = ifs_in_curr_cfg;
730   struct olsr_if *ifs = olsr_cnf->interfaces;
731   
732   PARSER_DEBUG_PRINTF("\tHNA interval: %0.2f\n", (double)$2->floating);
733
734   SET_IFS_CONF(ifs, ifcnt, hna_params.emission_interval, $2->floating);
735
736   free($2);
737 }
738 ;
739 isethnaval: TOK_HNAVAL TOK_FLOAT
740 {
741   int ifcnt = ifs_in_curr_cfg;
742   struct olsr_if *ifs = olsr_cnf->interfaces;
743
744   PARSER_DEBUG_PRINTF("\tHNA validity: %0.2f\n", (double)$2->floating);
745
746   SET_IFS_CONF(ifs, ifcnt, hna_params.validity_time, $2->floating);
747
748   free($2);
749 }
750 ;
751 isetautodetchg: TOK_AUTODETCHG TOK_BOOLEAN
752 {
753   int ifcnt = ifs_in_curr_cfg;
754   struct olsr_if *ifs = olsr_cnf->interfaces;
755
756   PARSER_DEBUG_PRINTF("\tAutodetect changes: %s\n", $2->boolean ? "YES" : "NO");
757
758   SET_IFS_CONF(ifs, ifcnt, autodetect_chg, $2->boolean);
759
760   free($2);
761 }
762 ;
763
764 isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
765 {
766   if (lq_mult_helper($2, $3) < 0) {
767     YYABORT;
768   }
769 }
770
771           | TOK_LQ_MULT TOK_IPV4_ADDR TOK_FLOAT
772 {
773   if (lq_mult_helper($2, $3) < 0) {
774     YYABORT;
775   }
776 }
777
778           | TOK_LQ_MULT TOK_IPV6_ADDR TOK_FLOAT
779 {
780   if (lq_mult_helper($2, $3) < 0) {
781     YYABORT;
782   }
783 }
784 ;
785
786 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
787 {
788   olsr_cnf->debug_level = $2->integer;
789   PARSER_DEBUG_PRINTF("Debug level: %d\n", olsr_cnf->debug_level);
790   free($2);
791 }
792 ;
793
794
795 iipversion:    TOK_IPVERSION TOK_INTEGER
796 {
797   if ($2->integer == 4) {
798     olsr_cnf->ip_version = AF_INET;
799     olsr_cnf->ipsize = sizeof(struct in_addr);
800     olsr_cnf->maxplen = 32;
801   } else if ($2->integer == 6) {
802     olsr_cnf->ip_version = AF_INET6;
803     olsr_cnf->ipsize = sizeof(struct in6_addr);
804     olsr_cnf->maxplen = 128;
805   } else {
806     fprintf(stderr, "IPversion must be 4 or 6!\n");
807     YYABORT;
808   }
809
810   PARSER_DEBUG_PRINTF("IpVersion: %d\n", $2->integer);
811   free($2);
812 }
813 ;
814
815 fibmetric:    TOK_FIBMETRIC TOK_STRING
816 {
817   int i;
818   PARSER_DEBUG_PRINTF("FIBMetric: %s\n", $2->string);
819   for (i=0; i<FIBM_CNT; i++) {
820     if (strcmp($2->string, FIB_METRIC_TXT[i]) == 0) {
821       olsr_cnf->fib_metric = i;
822       break;
823     }
824   }
825   if (i == FIBM_CNT) {
826     fprintf(stderr, "Bad FIBMetric value: %s\n", $2->string);
827     YYABORT;
828   }
829   free($1);
830   free($2->string);
831   free($2);
832 }
833 ;
834
835 ihna4entry:     TOK_IPV4_ADDR TOK_IPV4_ADDR
836 {
837   union olsr_ip_addr ipaddr, netmask;
838
839   if (olsr_cnf->ip_version == AF_INET6) {
840     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
841     olsr_startup_sleep(3);
842   }
843   else {
844     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
845
846     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
847       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
848       YYABORT;
849     }
850     if (inet_pton(AF_INET, $2->string, &netmask.v4) <= 0) {
851       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
852       YYABORT;
853     }
854
855     /* check that the given IP address is actually a network address */
856     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
857       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
858       YYABORT;
859     }
860
861     /* Queue */
862     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, olsr_netmask_to_prefix(&netmask));
863   }
864   free($1->string);
865   free($1);
866   free($2->string);
867   free($2);
868 }
869         |       TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
870 {
871   union olsr_ip_addr ipaddr, netmask;
872
873   if (olsr_cnf->ip_version == AF_INET6) {
874     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
875     olsr_startup_sleep(3);
876   }
877   else {
878     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%d\n", $1->string, $3->integer);
879
880     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
881       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
882       YYABORT;
883     }
884     if ($3->integer > olsr_cnf->maxplen) {
885       fprintf(stderr, "ihna4entry: Prefix len %u > %d is not allowed!\n", $3->integer, olsr_cnf->maxplen);
886       YYABORT;
887     }
888
889     /* check that the given IP address is actually a network address */
890     olsr_prefix_to_netmask(&netmask, $3->integer);
891     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
892       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
893       YYABORT;
894     }
895
896     /* Queue */
897     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, $3->integer);
898   }
899   free($1->string);
900   free($1);
901   free($3);
902 }
903 ;
904
905 ihna6entry:     TOK_IPV6_ADDR TOK_INTEGER
906 {
907   if (add_ipv6_addr($1, $2)) {
908     YYABORT;
909   }
910 }
911         |       TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
912 {
913   if (add_ipv6_addr($1, $3)) {
914     YYABORT;
915   }
916 }
917 ;
918
919 ifstart: TOK_INTERFACE
920 {
921   PARSER_DEBUG_PRINTF("setting ifs_in_curr_cfg = 0\n");
922   ifs_in_curr_cfg = 0;
923 }
924 ;
925
926 ifnick: TOK_STRING
927 {
928   struct olsr_if *in, *last;
929   in = olsr_cnf->interfaces;
930   last = NULL;
931   while (in != NULL) {
932     if (strcmp(in->name, $1->string) == 0) {
933       free ($1->string);
934       break;
935     }
936     last = in;
937     in = in->next;
938   }
939
940   if (in != NULL) {
941     /* remove old interface from list to add it later at the beginning */
942     if (last) {
943       last->next = in->next;
944     }
945     else {
946       olsr_cnf->interfaces = in->next;
947     }
948   }
949   else {
950     in = malloc(sizeof(*in));
951     if (in == NULL) {
952       fprintf(stderr, "Out of memory(ADD IF)\n");
953       YYABORT;
954     }
955     memset(in, 0, sizeof(*in));
956
957     in->cnf = malloc(sizeof(*in->cnf));
958     if (in->cnf == NULL) {
959       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
960       YYABORT;
961     }
962     memset(in->cnf, 0x00, sizeof(*in->cnf));
963
964     in->cnfi = malloc(sizeof(*in->cnfi));
965     if (in->cnf == NULL) {
966       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
967       YYABORT;
968     }
969     memset(in->cnfi, 0xFF, sizeof(*in->cnfi));
970     in->cnfi->orig_lq_mult_cnt=0;
971
972     in->name = $1->string;
973   }
974   /* Queue */
975   in->next = olsr_cnf->interfaces;
976   olsr_cnf->interfaces = in;
977   ifs_in_curr_cfg++;
978   free($1);
979 }
980 ;
981
982 bnoint: TOK_NOINT TOK_BOOLEAN
983 {
984   PARSER_DEBUG_PRINTF("Noint set to %d\n", $2->boolean);
985   olsr_cnf->allow_no_interfaces = $2->boolean;
986   free($2);
987 }
988 ;
989
990 atos: TOK_TOS TOK_INTEGER
991 {
992   PARSER_DEBUG_PRINTF("TOS: %d\n", $2->integer);
993   olsr_cnf->tos = $2->integer;
994   free($2);
995
996 }
997 ;
998
999 aolsrport: TOK_OLSRPORT TOK_INTEGER
1000 {
1001   PARSER_DEBUG_PRINTF("OlsrPort: %d\n", $2->integer);
1002   olsr_cnf->olsrport = $2->integer;
1003   free($2);
1004 }
1005 ;
1006
1007 irtproto: TOK_RTPROTO TOK_INTEGER
1008 {
1009   PARSER_DEBUG_PRINTF("RtProto: %d\n", $2->integer);
1010   olsr_cnf->rt_proto = $2->integer;
1011   free($2);
1012 }
1013 ;
1014
1015 irttable: TOK_RTTABLE TOK_INTEGER
1016 {
1017   PARSER_DEBUG_PRINTF("RtTable: %d\n", $2->integer);
1018   olsr_cnf->rt_table = $2->integer;
1019   free($2);
1020 }
1021        | TOK_RTTABLE TOK_AUTO
1022 {
1023   PARSER_DEBUG_PRINTF("RtTable: auto\n");
1024   olsr_cnf->rt_table = DEF_RT_AUTO;
1025   free($2);
1026 }
1027 ;
1028
1029 irttable_default: TOK_RTTABLE_DEFAULT TOK_INTEGER
1030 {
1031   PARSER_DEBUG_PRINTF("RtTableDefault: %d\n", $2->integer);
1032   olsr_cnf->rt_table_default = $2->integer;
1033   free($2);
1034 }
1035        | TOK_RTTABLE_DEFAULT TOK_AUTO
1036 {
1037   PARSER_DEBUG_PRINTF("RtTableDefault: auto\n");
1038   olsr_cnf->rt_table_default = DEF_RT_AUTO;
1039   free($2);
1040 }
1041 ;
1042
1043 irttable_tunnel: TOK_RTTABLE_TUNNEL TOK_INTEGER
1044 {
1045   PARSER_DEBUG_PRINTF("RtTableTunnel: %d\n", $2->integer);
1046   olsr_cnf->rt_table_tunnel = $2->integer;
1047   free($2);
1048 }
1049        | TOK_RTTABLE_TUNNEL TOK_AUTO
1050 {
1051   PARSER_DEBUG_PRINTF("RtTableTunnel: auto\n");
1052   olsr_cnf->rt_table_tunnel = DEF_RT_AUTO;
1053   free($2);
1054 }
1055 ;
1056
1057 irttable_priority: TOK_RTTABLE_PRIORITY TOK_INTEGER
1058 {
1059   PARSER_DEBUG_PRINTF("RtTablePriority: %d\n", $2->integer);
1060   olsr_cnf->rt_table_pri = $2->integer;
1061   free($2);
1062 }
1063         | TOK_RTTABLE_PRIORITY TOK_AUTO
1064 {
1065   PARSER_DEBUG_PRINTF("RtTablePriority: auto\n");
1066   olsr_cnf->rt_table_pri = DEF_RT_AUTO;
1067   free($2);
1068 }
1069         | TOK_RTTABLE_PRIORITY TOK_NONE
1070 {
1071   PARSER_DEBUG_PRINTF("RtTablePriority: none\n");
1072   olsr_cnf->rt_table_pri = DEF_RT_NONE;
1073   free($2);
1074 }
1075 ;
1076
1077 irttable_default_priority: TOK_RTTABLE_DEFAULT_PRIORITY TOK_INTEGER
1078 {
1079   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: %d\n", $2->integer);
1080   olsr_cnf->rt_table_default_pri = $2->integer;
1081   free($2);
1082 }
1083         | TOK_RTTABLE_DEFAULT_PRIORITY TOK_AUTO
1084 {
1085   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: auto\n");
1086   olsr_cnf->rt_table_default_pri = DEF_RT_AUTO;
1087   free($2);
1088 }
1089         | TOK_RTTABLE_DEFAULT_PRIORITY TOK_NONE
1090 {
1091   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: none\n");
1092   olsr_cnf->rt_table_default_pri = DEF_RT_NONE;
1093   free($2);
1094 }
1095 ;
1096
1097 irttable_tunnel_priority: TOK_RTTABLE_TUNNEL_PRIORITY TOK_INTEGER
1098 {
1099   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: %d\n", $2->integer);
1100   olsr_cnf->rt_table_tunnel_pri = $2->integer;
1101   free($2);
1102 }
1103         | TOK_RTTABLE_TUNNEL_PRIORITY TOK_AUTO
1104 {
1105   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: auto\n");
1106   olsr_cnf->rt_table_tunnel_pri = DEF_RT_AUTO;
1107   free($2);
1108 }
1109         | TOK_RTTABLE_TUNNEL_PRIORITY TOK_NONE
1110 {
1111   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: none\n");
1112   olsr_cnf->rt_table_tunnel_pri = DEF_RT_NONE;
1113   free($2);
1114 }
1115 ;
1116
1117 irttable_defaultolsr_priority: TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_INTEGER
1118 {
1119   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: %d\n", $2->integer);
1120   olsr_cnf->rt_table_defaultolsr_pri = $2->integer;
1121   free($2);
1122 }
1123         | TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_AUTO
1124 {
1125   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: auto\n");
1126   olsr_cnf->rt_table_defaultolsr_pri = DEF_RT_AUTO;
1127   free($2);
1128 }
1129         | TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_NONE
1130 {
1131   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: none\n");
1132   olsr_cnf->rt_table_defaultolsr_pri = DEF_RT_NONE;
1133   free($2);
1134 }
1135 ;
1136
1137 awillingness: TOK_WILLINGNESS TOK_INTEGER
1138 {
1139   PARSER_DEBUG_PRINTF("Willingness: %d\n", $2->integer);
1140   olsr_cnf->willingness_auto = false;
1141   olsr_cnf->willingness = $2->integer;
1142   free($2);
1143 }
1144 ;
1145
1146 busehyst: TOK_USEHYST TOK_BOOLEAN
1147 {
1148   olsr_cnf->use_hysteresis = $2->boolean;
1149   PARSER_DEBUG_PRINTF("Hysteresis %s\n", olsr_cnf->use_hysteresis ? "enabled" : "disabled");
1150   free($2);
1151 }
1152 ;
1153
1154 fhystscale: TOK_HYSTSCALE TOK_FLOAT
1155 {
1156   olsr_cnf->hysteresis_param.scaling = $2->floating;
1157   PARSER_DEBUG_PRINTF("Hysteresis Scaling: %0.2f\n", (double)$2->floating);
1158   free($2);
1159 }
1160 ;
1161
1162 fhystupper: TOK_HYSTUPPER TOK_FLOAT
1163 {
1164   olsr_cnf->hysteresis_param.thr_high = $2->floating;
1165   PARSER_DEBUG_PRINTF("Hysteresis UpperThr: %0.2f\n", (double)$2->floating);
1166   free($2);
1167 }
1168 ;
1169
1170 fhystlower: TOK_HYSTLOWER TOK_FLOAT
1171 {
1172   olsr_cnf->hysteresis_param.thr_low = $2->floating;
1173   PARSER_DEBUG_PRINTF("Hysteresis LowerThr: %0.2f\n", (double)$2->floating);
1174   free($2);
1175 }
1176 ;
1177
1178 fpollrate: TOK_POLLRATE TOK_FLOAT
1179 {
1180   PARSER_DEBUG_PRINTF("Pollrate %0.2f\n", (double)$2->floating);
1181   olsr_cnf->pollrate = $2->floating;
1182   free($2);
1183 }
1184 ;
1185
1186 fnicchgspollrt: TOK_NICCHGSPOLLRT TOK_FLOAT
1187 {
1188   PARSER_DEBUG_PRINTF("NIC Changes Pollrate %0.2f\n", (double)$2->floating);
1189   olsr_cnf->nic_chgs_pollrate = $2->floating;
1190   free($2);
1191 }
1192 ;
1193
1194 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
1195 {
1196   PARSER_DEBUG_PRINTF("TC redundancy %d\n", $2->integer);
1197   olsr_cnf->tc_redundancy = $2->integer;
1198   free($2);
1199 }
1200 ;
1201
1202 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
1203 {
1204   PARSER_DEBUG_PRINTF("MPR coverage %d\n", $2->integer);
1205   olsr_cnf->mpr_coverage = $2->integer;
1206   free($2);
1207 }
1208 ;
1209
1210 alq_level: TOK_LQ_LEVEL TOK_INTEGER
1211 {
1212   PARSER_DEBUG_PRINTF("Link quality level %d\n", $2->integer);
1213   olsr_cnf->lq_level = $2->integer;
1214   free($2);
1215 }
1216 ;
1217
1218 alq_fish: TOK_LQ_FISH TOK_INTEGER
1219 {
1220   PARSER_DEBUG_PRINTF("Link quality fish eye %d\n", $2->integer);
1221   olsr_cnf->lq_fish = $2->integer;
1222   free($2);
1223 }
1224 ;
1225
1226 alq_aging: TOK_LQ_AGING TOK_FLOAT
1227 {
1228   PARSER_DEBUG_PRINTF("Link quality aging factor %f\n", (double)$2->floating);
1229   olsr_cnf->lq_aging = $2->floating;
1230   free($2);
1231 }
1232 ;
1233
1234 amin_tc_vtime: TOK_MIN_TC_VTIME TOK_FLOAT
1235 {
1236   PARSER_DEBUG_PRINTF("Minimum TC validity time %f\n", (double)$2->floating);
1237   olsr_cnf->min_tc_vtime = $2->floating;
1238   free($2);
1239 }
1240 ;
1241
1242 alock_file: TOK_LOCK_FILE TOK_STRING
1243 {
1244   PARSER_DEBUG_PRINTF("Lock file %s\n", $2->string);
1245   olsr_cnf->lock_file = $2->string;
1246   free($2);
1247 }
1248 ;
1249 alq_plugin: TOK_LQ_PLUGIN TOK_STRING
1250 {
1251   olsr_cnf->lq_algorithm = $2->string;
1252   PARSER_DEBUG_PRINTF("LQ Algorithm: %s\n", $2->string);
1253   free($2);
1254 }
1255 ;
1256
1257 anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
1258 {
1259   PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", (double)$2->floating);
1260   olsr_cnf->lq_nat_thresh = $2->floating;
1261   free($2);
1262 }
1263 ;
1264
1265 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
1266 {
1267   PARSER_DEBUG_PRINTF("Clear screen %s\n", $2->boolean ? "enabled" : "disabled");
1268   olsr_cnf->clear_screen = $2->boolean;
1269   free($2);
1270 }
1271 ;
1272
1273 suse_niit: TOK_USE_NIIT TOK_BOOLEAN
1274 {
1275   PARSER_DEBUG_PRINTF("Use NIIT ip translation: %s\n", $2->boolean ? "enabled" : "disabled");
1276   olsr_cnf->use_niit = $2->boolean;
1277   free($2);
1278 }
1279 ;
1280
1281 bsmart_gw: TOK_SMART_GW TOK_BOOLEAN
1282 {
1283         PARSER_DEBUG_PRINTF("Smart gateway system: %s\n", $2->boolean ? "enabled" : "disabled");
1284         olsr_cnf->smart_gw_active = $2->boolean;
1285         free($2);
1286 }
1287 ;
1288
1289 bsmart_gw_allow_nat: TOK_SMART_GW_ALLOW_NAT TOK_BOOLEAN
1290 {
1291         PARSER_DEBUG_PRINTF("Smart gateway allow client nat: %s\n", $2->boolean ? "yes" : "no");
1292         olsr_cnf->smart_gw_allow_nat = $2->boolean;
1293         free($2);
1294 }
1295 ;
1296
1297 ismart_gw_period: TOK_SMART_GW_PERIOD TOK_INTEGER
1298 {
1299   PARSER_DEBUG_PRINTF("Smart gateway period: %d\n", $2->integer);
1300   olsr_cnf->smart_gw_period = $2->integer;
1301   free($2);
1302 }
1303 ;
1304
1305 asmart_gw_stablecount: TOK_SMART_GW_STABLECOUNT TOK_INTEGER
1306 {
1307   PARSER_DEBUG_PRINTF("Smart gateway stablecount: %d\n", $2->integer);
1308   olsr_cnf->smart_gw_stablecount = $2->integer;
1309   free($2);
1310 }
1311 ;
1312
1313 asmart_gw_thresh: TOK_SMART_GW_THRESH TOK_INTEGER
1314 {
1315   PARSER_DEBUG_PRINTF("Smart gateway threshold: %d\n", $2->integer);
1316   olsr_cnf->smart_gw_thresh = $2->integer;
1317   free($2);
1318 }
1319 ;
1320
1321 ssmart_gw_uplink: TOK_SMART_GW_UPLINK TOK_STRING
1322 {
1323         PARSER_DEBUG_PRINTF("Smart gateway uplink: %s\n", $2->string);
1324         if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_NONE]) == 0) {
1325                 olsr_cnf->smart_gw_type = GW_UPLINK_NONE;
1326         }
1327         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV4]) == 0) {
1328                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV4;
1329         }
1330         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV6]) == 0) {
1331                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV6;
1332         }
1333         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV46]) == 0) {
1334                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV46;
1335         }
1336         else {
1337                 fprintf(stderr, "Bad gateway uplink type: %s\n", $2->string);
1338                 YYABORT;
1339         }
1340         free($2);
1341 }
1342 ;
1343
1344 ismart_gw_speed: TOK_SMART_GW_SPEED TOK_INTEGER TOK_INTEGER
1345 {
1346         PARSER_DEBUG_PRINTF("Smart gateway speed: %u uplink/%u downlink kbit/s\n", $2->integer, $3->integer);
1347         olsr_cnf->smart_gw_uplink = $2->integer;
1348         olsr_cnf->smart_gw_downlink = $3->integer;
1349         free($2);
1350         free($3);
1351 }
1352 ;
1353
1354 bsmart_gw_uplink_nat: TOK_SMART_GW_UPLINK_NAT TOK_BOOLEAN
1355 {
1356         PARSER_DEBUG_PRINTF("Smart gateway uplink nat: %s\n", $2->boolean ? "yes" : "no");
1357         olsr_cnf->smart_gw_uplink_nat = $2->boolean;
1358         free($2);
1359 }
1360 ;
1361
1362 ismart_gw_prefix: TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_INTEGER
1363 {
1364   PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $3->integer);
1365         if (inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->smart_gw_prefix.prefix) == 0) {
1366           fprintf(stderr, "Bad IP part of gateway prefix: %s\n", $2->string);
1367     YYABORT;
1368   }
1369         olsr_cnf->smart_gw_prefix.prefix_len = (uint8_t)$3->integer;
1370         
1371         free($2);
1372         free($3);
1373 }
1374         |       TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
1375 {
1376         PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $4->integer);
1377         if (inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->smart_gw_prefix.prefix) == 0) {
1378           fprintf(stderr, "Bad IP part of gateway prefix: %s\n", $2->string);
1379     YYABORT;
1380   }
1381         olsr_cnf->smart_gw_prefix.prefix_len = (uint8_t)$4->integer;
1382         
1383         free($2);
1384         free($4);
1385 }
1386 ;
1387
1388 bsrc_ip_routes: TOK_SRC_IP_ROUTES TOK_BOOLEAN
1389 {
1390         PARSER_DEBUG_PRINTF("Use originator for routes src-ip: %s\n", $2->boolean ? "yes" : "no");
1391         if (olsr_cnf->ip_version != AF_INET) {
1392           fprintf(stderr, "Source ip routes not possible with IPV6\n");
1393           YYABORT;
1394         }
1395         else olsr_cnf->use_src_ip_routes = $2->boolean;
1396         free($2);
1397 }
1398 ;
1399
1400 amain_ip: TOK_MAIN_IP TOK_IPV4_ADDR
1401 {
1402   PARSER_DEBUG_PRINTF("Fixed Main IP: %s\n", $2->string);
1403   
1404   if (olsr_cnf->ip_version != AF_INET
1405       || inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->main_addr) != 1) {
1406     fprintf(stderr, "Bad main IP: %s\n", $2->string);
1407     YYABORT;
1408   }
1409   else olsr_cnf->unicast_src_ip = olsr_cnf->main_addr;
1410   free($2);
1411 }
1412         |       TOK_MAIN_IP TOK_IPV6_ADDR
1413 {
1414   PARSER_DEBUG_PRINTF("Fixed Main IP: %s\n", $2->string);
1415   
1416   if (olsr_cnf->ip_version != AF_INET6
1417       || inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->main_addr) != 1) {
1418     fprintf(stderr, "Bad main IP: %s\n", $2->string);
1419     YYABORT;
1420   }
1421   free($2);
1422 }
1423 ;
1424
1425 bset_ipforward: TOK_SET_IPFORWARD TOK_BOOLEAN
1426 {
1427   PARSER_DEBUG_PRINTF("Set IP-Forward procfile variable: %s\n", $2->boolean ? "yes" : "no");
1428   olsr_cnf->set_ip_forward = $2->boolean;
1429   free($2);
1430 }
1431 ;
1432
1433
1434 plblock: TOK_PLUGIN TOK_STRING
1435 {
1436   struct plugin_entry *pe, *last;
1437   
1438   pe = olsr_cnf->plugins;
1439   last = NULL;
1440   while (pe != NULL) {
1441     if (strcmp(pe->name, $2->string) == 0) {
1442       free ($2->string);
1443       break;
1444     }
1445     last = pe;
1446     pe = pe->next;
1447   }
1448
1449   if (pe != NULL) {
1450     /* remove old plugin from list to add it later at the beginning */
1451     if (last) {
1452       last->next = pe->next;
1453     }
1454     else {
1455       olsr_cnf->plugins = pe->next;
1456     }
1457   }
1458   else {
1459     pe = malloc(sizeof(*pe));
1460
1461     if (pe == NULL) {
1462       fprintf(stderr, "Out of memory(ADD PL)\n");
1463       YYABORT;
1464     }
1465
1466     pe->name = $2->string;
1467     pe->params = NULL;
1468
1469     PARSER_DEBUG_PRINTF("Plugin: %s\n", $2->string);
1470   }
1471   
1472   /* Queue */
1473   pe->next = olsr_cnf->plugins;
1474   olsr_cnf->plugins = pe;
1475
1476   free($2);
1477 }
1478 ;
1479
1480 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
1481 {
1482   struct plugin_param *pp = malloc(sizeof(*pp));
1483   
1484   if (pp == NULL) {
1485     fprintf(stderr, "Out of memory(ADD PP)\n");
1486     YYABORT;
1487   }
1488   
1489   PARSER_DEBUG_PRINTF("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
1490   
1491   pp->key = $2->string;
1492   pp->value = $3->string;
1493
1494   /* Queue */
1495   pp->next = olsr_cnf->plugins->params;
1496   olsr_cnf->plugins->params = pp;
1497
1498   free($2);
1499   free($3);
1500 }
1501 ;
1502
1503 vcomment:       TOK_COMMENT
1504 {
1505     //PARSER_DEBUG_PRINTF("Comment\n");
1506 }
1507 ;
1508
1509
1510
1511 %%
1512
1513 void yyerror (const char *string)
1514 {
1515   fprintf(stderr, "Config line %d: %s\n", current_line, string);
1516 }