fixes for the rt-policy settings, lot's of sanity check changes, new defaults
[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          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_UPLINK
220 %token TOK_SMART_GW_UPLINK_NAT
221 %token TOK_SMART_GW_SPEED
222 %token TOK_SMART_GW_PREFIX
223 %token TOK_SRC_IP_ROUTES
224 %token TOK_MAIN_IP
225
226 %token TOK_HOSTLABEL
227 %token TOK_NETLABEL
228 %token TOK_MAXIPC
229
230 %token TOK_IFMODE
231 %token TOK_IPV4BROADCAST
232 %token TOK_IPV4MULTICAST
233 %token TOK_IPV6MULTICAST
234 %token TOK_IPV4SRC
235 %token TOK_IPV6SRC
236 %token TOK_IFWEIGHT
237 %token TOK_HELLOINT
238 %token TOK_HELLOVAL
239 %token TOK_TCINT
240 %token TOK_TCVAL
241 %token TOK_MIDINT
242 %token TOK_MIDVAL
243 %token TOK_HNAINT
244 %token TOK_HNAVAL
245 %token TOK_AUTODETCHG
246
247 %token TOK_IPV4_ADDR
248 %token TOK_IPV6_ADDR
249 %token TOK_DEFAULT
250 %token TOK_AUTO
251 %token TOK_NONE
252
253 %token TOK_COMMENT
254
255 %%
256
257 conf:
258           | conf block
259           | conf stmt
260 ;
261
262 stmt:       idebug
263           | iipversion
264           | fibmetric
265           | bnoint
266           | atos
267           | aolsrport
268           | irtproto
269           | irttable
270           | irttable_default
271           | irttable_tunnel
272           | irttable_priority
273           | irttable_defaultolsr_priority
274           | irttable_tunnel_priority
275           | irttable_default_priority
276           | awillingness
277           | busehyst
278           | fhystscale
279           | fhystupper
280           | fhystlower
281           | fpollrate
282           | fnicchgspollrt
283           | atcredundancy
284           | amprcoverage
285           | alq_level
286           | alq_plugin
287           | alq_fish
288           | anat_thresh
289           | alq_aging
290           | bclear_screen
291           | vcomment
292           | amin_tc_vtime
293           | alock_file
294           | suse_niit
295           | bsmart_gw
296           | bsmart_gw_allow_nat
297           | ssmart_gw_uplink
298           | bsmart_gw_uplink_nat
299           | ismart_gw_speed
300           | ismart_gw_prefix
301           | bsrc_ip_routes
302           | amain_ip
303 ;
304
305 block:      TOK_HNA4 hna4body
306           | TOK_HNA6 hna6body
307           | TOK_IPCCON ipcbody
308           | ifdblock ifdbody
309           | ifblock ifbody
310           | plblock plbody
311 ;
312
313 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
314 ;
315
316 hna4stmts: | hna4stmts hna4stmt
317 ;
318
319 hna4stmt:  vcomment
320          | ihna4entry
321 ;
322
323 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
324 ;
325
326 hna6stmts: | hna6stmts hna6stmt
327 ;
328
329 hna6stmt:  vcomment
330          | ihna6entry
331 ;
332
333 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
334 ;
335
336 ipcstmts: | ipcstmts ipcstmt
337 ;
338
339 ipcstmt:  vcomment
340           | imaxipc
341           | ipchost
342           | ipcnet
343 ;
344
345 ifblock:   ifstart ifnicks
346 ;
347
348 ifnicks:   | ifnicks ifnick
349 ;
350
351 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
352 ;
353
354 ifdbody:     TOK_OPEN ifstmts TOK_CLOSE
355 {
356   struct olsr_if *in = olsr_cnf->interfaces;
357   printf("\nInterface Defaults");
358   /*remove Interface Defaults from Interface list as they are no interface!*/
359   olsr_cnf->interfaces = in->next;
360   ifs_in_curr_cfg=0;
361   /*free interface but keep its config intact?*/
362   free(in->cnfi);
363   free(in);
364
365 }
366 ;
367
368 ifstmts:   | ifstmts ifstmt
369 ;
370
371 ifstmt:      vcomment
372              | iifweight
373              | isetifmode
374              | isetipv4br
375              | isetipv4mc
376              | isetipv6mc
377              | isetipv4src
378              | isetipv6src
379              | isethelloint
380              | isethelloval
381              | isettcint
382              | isettcval
383              | isetmidint
384              | isetmidval
385              | isethnaint
386              | isethnaval
387              | isetautodetchg
388              | isetlqmult
389 ;
390
391 plbody:     TOK_OPEN plstmts TOK_CLOSE
392 ;
393
394 plstmts:   | plstmts plstmt
395 ;
396
397 plstmt:     plparam
398           | vcomment
399 ;
400
401 ifdblock: TOK_INTERFACE_DEFAULTS
402 {
403   struct olsr_if *in = malloc(sizeof(*in));
404
405   if (in == NULL) {
406     fprintf(stderr, "Out of memory(ADD IF)\n");
407     YYABORT;
408   }
409
410   in->cnf = get_default_if_config();
411   in->cnfi = get_default_if_config();
412
413   if (in->cnf == NULL || in->cnfi == NULL) {
414     fprintf(stderr, "Out of memory(ADD DEFIFRULE)\n");
415     YYABORT;
416   }
417
418   //should not need a name any more, as we free it on "}" again
419   //in->name = strdup(interface_defaults_name);
420
421   olsr_cnf->interface_defaults = in->cnf;
422
423   /* Queue */
424   in->next = olsr_cnf->interfaces;
425   olsr_cnf->interfaces = in;
426   ifs_in_curr_cfg=1;
427   
428   fflush(stdout);
429 }
430 ;
431
432 imaxipc: TOK_MAXIPC TOK_INTEGER
433 {
434   olsr_cnf->ipc_connections = $2->integer;
435   free($2);
436 }
437 ;
438
439 ipchost: TOK_HOSTLABEL TOK_IPV4_ADDR
440 {
441   union olsr_ip_addr ipaddr;
442   PARSER_DEBUG_PRINTF("\tIPC host: %s\n", $2->string);
443   
444   if (inet_aton($2->string, &ipaddr.v4) == 0) {
445     fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
446     YYABORT;
447   }
448
449   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_cnf->maxplen);
450
451   free($2->string);
452   free($2);
453 }
454 ;
455
456 ipcnet: TOK_NETLABEL TOK_IPV4_ADDR TOK_IPV4_ADDR
457 {
458   union olsr_ip_addr ipaddr, netmask;
459
460   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
461   
462   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
463     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
464     YYABORT;
465   }
466
467   if (inet_pton(AF_INET, $3->string, &netmask.v4) == 0) {
468     fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
469     YYABORT;
470   }
471
472   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, olsr_netmask_to_prefix(&netmask));
473
474   free($2->string);
475   free($2);
476   free($3->string);
477   free($3);
478 }
479         |       TOK_NETLABEL TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
480 {
481   union olsr_ip_addr ipaddr;
482
483   PARSER_DEBUG_PRINTF("\tIPC net: %s/%s\n", $2->string, $3->string);
484   
485   if (inet_pton(AF_INET, $2->string, &ipaddr.v4) == 0) {
486     fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
487     YYABORT;
488   }
489
490   if ($4->integer > olsr_cnf->maxplen) {
491     fprintf(stderr, "ipcnet: Prefix len %u > %d is not allowed!\n", $4->integer, olsr_cnf->maxplen);
492     YYABORT;
493   }
494
495   ip_prefix_list_add(&olsr_cnf->ipc_nets, &ipaddr, $4->integer);
496
497   free($2->string);
498   free($2);
499   free($4);
500 }
501 ;
502
503 iifweight:       TOK_IFWEIGHT TOK_INTEGER
504 {
505   int ifcnt = ifs_in_curr_cfg;
506   struct olsr_if *ifs = olsr_cnf->interfaces;
507
508   PARSER_DEBUG_PRINTF("Fixed willingness: %d\n", $2->integer);
509
510   while (ifcnt) {
511     ifs->cnf->weight.value = $2->integer;
512     ifs->cnf->weight.fixed = true;
513     ifs->cnfi->weight.value = $2->integer;
514     ifs->cnfi->weight.fixed = true;
515
516     ifs = ifs->next;
517     ifcnt--;
518   }
519
520   free($2);
521 }
522 ;
523
524 isetifmode: TOK_IFMODE TOK_STRING
525 {
526   int ifcnt = ifs_in_curr_cfg;
527   struct olsr_if *ifs = olsr_cnf->interfaces;
528         int mode = (strcmp($2->string, "ether") == 0)?IF_MODE_ETHER:IF_MODE_MESH;
529
530   PARSER_DEBUG_PRINTF("\tMode: %s\n", $2->string);
531
532         SET_IFS_CONF(ifs, ifcnt, mode, mode);
533         
534   free($2->string);
535   free($2);
536 }
537 ;
538
539 isetipv4br: TOK_IPV4BROADCAST TOK_IPV4_ADDR
540 {
541   struct in_addr in;
542   int ifcnt = ifs_in_curr_cfg;
543   struct olsr_if *ifs = olsr_cnf->interfaces;
544
545   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $2->string);
546
547   if (inet_aton($2->string, &in) == 0) {
548     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $2->string);
549     YYABORT;
550   }
551
552         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
553
554   free($2->string);
555   free($2);
556 }
557 ;
558
559 isetipv4mc: TOK_IPV4MULTICAST TOK_IPV4_ADDR
560 {
561   struct in_addr in;
562   int ifcnt = ifs_in_curr_cfg;
563   struct olsr_if *ifs = olsr_cnf->interfaces;
564
565   PARSER_DEBUG_PRINTF("\tIPv4 broadcast: %s\n", $2->string);
566
567   if (inet_aton($2->string, &in) == 0) {
568     fprintf(stderr, "isetipv4br: Failed converting IP address %s\n", $2->string);
569     YYABORT;
570   }
571
572         SET_IFS_CONF(ifs, ifcnt, ipv4_multicast.v4, in);
573
574   free($2->string);
575   free($2);
576 }
577 ;
578
579 isetipv6mc: TOK_IPV6MULTICAST TOK_IPV6_ADDR
580 {
581   struct in6_addr in6;
582   int ifcnt = ifs_in_curr_cfg;
583   struct olsr_if *ifs = olsr_cnf->interfaces;
584
585   PARSER_DEBUG_PRINTF("\tIPv6 multicast: %s\n", $2->string);
586
587   if (inet_pton(AF_INET6, $2->string, &in6) <= 0) {
588     fprintf(stderr, "isetipv6mc: Failed converting IP address %s\n", $2->string);
589     YYABORT;
590   }
591
592         SET_IFS_CONF(ifs, ifcnt, ipv6_multicast.v6, in6);
593
594   free($2->string);
595   free($2);
596 }
597 ;
598
599 isetipv4src: TOK_IPV4SRC TOK_IPV4_ADDR
600 {
601   struct in_addr in;
602   int ifcnt = ifs_in_curr_cfg;
603   struct olsr_if *ifs = olsr_cnf->interfaces;
604
605   PARSER_DEBUG_PRINTF("\tIPv4 src: %s\n", $2->string);
606
607   if (inet_aton($2->string, &in) == 0) {
608     fprintf(stderr, "isetipv4src: Failed converting IP address %s\n", $2->string);
609     YYABORT;
610   }
611
612         SET_IFS_CONF(ifs, ifcnt, ipv4_src.v4, in);
613
614   free($2->string);
615   free($2);
616 }
617 ;
618
619 isetipv6src: TOK_IPV6SRC TOK_IPV6_ADDR
620 {
621   struct olsr_ip_prefix pr6;
622   int ifcnt = ifs_in_curr_cfg;
623   struct olsr_if *ifs = olsr_cnf->interfaces;
624
625   PARSER_DEBUG_PRINTF("\tIPv6 src prefix: %s\n", $2->string);
626
627   if (olsr_string_to_prefix(AF_INET6, &pr6, $2->string) <= 0) {
628     fprintf(stderr, "isetipv6src: Failed converting IP prefix %s\n", $2->string);
629     YYABORT;
630   }
631
632         SET_IFS_CONF(ifs, ifcnt, ipv6_src, pr6);
633
634   free($2->string);
635   free($2);
636 }
637 ;
638
639 isethelloint: TOK_HELLOINT TOK_FLOAT
640 {
641   int ifcnt = ifs_in_curr_cfg;
642   struct olsr_if *ifs = olsr_cnf->interfaces;
643
644   PARSER_DEBUG_PRINTF("\tHELLO interval: %0.2f\n", $2->floating);
645
646         SET_IFS_CONF(ifs, ifcnt, hello_params.emission_interval, $2->floating);
647
648   free($2);
649 }
650 ;
651 isethelloval: TOK_HELLOVAL TOK_FLOAT
652 {
653   int ifcnt = ifs_in_curr_cfg;
654   struct olsr_if *ifs = olsr_cnf->interfaces;
655
656   PARSER_DEBUG_PRINTF("\tHELLO validity: %0.2f\n", $2->floating);
657
658         SET_IFS_CONF(ifs, ifcnt, hello_params.validity_time, $2->floating);
659
660   free($2);
661 }
662 ;
663 isettcint: TOK_TCINT TOK_FLOAT
664 {
665   int ifcnt = ifs_in_curr_cfg;
666   struct olsr_if *ifs = olsr_cnf->interfaces;
667
668   PARSER_DEBUG_PRINTF("\tTC interval: %0.2f\n", $2->floating);
669
670         SET_IFS_CONF(ifs, ifcnt, tc_params.emission_interval, $2->floating);
671
672   free($2);
673 }
674 ;
675 isettcval: TOK_TCVAL TOK_FLOAT
676 {
677   int ifcnt = ifs_in_curr_cfg;
678   struct olsr_if *ifs = olsr_cnf->interfaces;
679   
680   PARSER_DEBUG_PRINTF("\tTC validity: %0.2f\n", $2->floating);
681   
682  SET_IFS_CONF(ifs, ifcnt, tc_params.validity_time, $2->floating);
683
684   free($2);
685 }
686 ;
687 isetmidint: TOK_MIDINT TOK_FLOAT
688 {
689   int ifcnt = ifs_in_curr_cfg;
690   struct olsr_if *ifs = olsr_cnf->interfaces;
691
692
693   PARSER_DEBUG_PRINTF("\tMID interval: %0.2f\n", $2->floating);
694   
695   SET_IFS_CONF(ifs, ifcnt, mid_params.emission_interval, $2->floating);
696
697   free($2);
698 }
699 ;
700 isetmidval: TOK_MIDVAL TOK_FLOAT
701 {
702   int ifcnt = ifs_in_curr_cfg;
703   struct olsr_if *ifs = olsr_cnf->interfaces;
704
705   PARSER_DEBUG_PRINTF("\tMID validity: %0.2f\n", $2->floating);
706   
707   SET_IFS_CONF(ifs, ifcnt, mid_params.validity_time, $2->floating);
708
709   free($2);
710 }
711 ;
712 isethnaint: TOK_HNAINT TOK_FLOAT
713 {
714   int ifcnt = ifs_in_curr_cfg;
715   struct olsr_if *ifs = olsr_cnf->interfaces;
716   
717   PARSER_DEBUG_PRINTF("\tHNA interval: %0.2f\n", $2->floating);
718
719   SET_IFS_CONF(ifs, ifcnt, hna_params.emission_interval, $2->floating);
720
721   free($2);
722 }
723 ;
724 isethnaval: TOK_HNAVAL TOK_FLOAT
725 {
726   int ifcnt = ifs_in_curr_cfg;
727   struct olsr_if *ifs = olsr_cnf->interfaces;
728
729   PARSER_DEBUG_PRINTF("\tHNA validity: %0.2f\n", $2->floating);
730
731   SET_IFS_CONF(ifs, ifcnt, hna_params.validity_time, $2->floating);
732
733   free($2);
734 }
735 ;
736 isetautodetchg: TOK_AUTODETCHG TOK_BOOLEAN
737 {
738   int ifcnt = ifs_in_curr_cfg;
739   struct olsr_if *ifs = olsr_cnf->interfaces;
740
741   PARSER_DEBUG_PRINTF("\tAutodetect changes: %s\n", $2->boolean ? "YES" : "NO");
742
743   SET_IFS_CONF(ifs, ifcnt, autodetect_chg, $2->boolean);
744
745   free($2);
746 }
747 ;
748
749 isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
750 {
751   if (lq_mult_helper($2, $3) < 0) {
752     YYABORT;
753   }
754 }
755
756           | TOK_LQ_MULT TOK_IPV4_ADDR TOK_FLOAT
757 {
758   if (lq_mult_helper($2, $3) < 0) {
759     YYABORT;
760   }
761 }
762
763           | TOK_LQ_MULT TOK_IPV6_ADDR TOK_FLOAT
764 {
765   if (lq_mult_helper($2, $3) < 0) {
766     YYABORT;
767   }
768 }
769 ;
770
771 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
772 {
773   olsr_cnf->debug_level = $2->integer;
774   PARSER_DEBUG_PRINTF("Debug level: %d\n", olsr_cnf->debug_level);
775   free($2);
776 }
777 ;
778
779
780 iipversion:    TOK_IPVERSION TOK_INTEGER
781 {
782   if ($2->integer == 4) {
783     olsr_cnf->ip_version = AF_INET;
784     olsr_cnf->ipsize = sizeof(struct in_addr);
785     olsr_cnf->maxplen = 32;
786   } else if ($2->integer == 6) {
787     olsr_cnf->ip_version = AF_INET6;
788     olsr_cnf->ipsize = sizeof(struct in6_addr);
789     olsr_cnf->maxplen = 128;
790   } else {
791     fprintf(stderr, "IPversion must be 4 or 6!\n");
792     YYABORT;
793   }
794
795   PARSER_DEBUG_PRINTF("IpVersion: %d\n", $2->integer);
796   free($2);
797 }
798 ;
799
800 fibmetric:    TOK_FIBMETRIC TOK_STRING
801 {
802   int i;
803   PARSER_DEBUG_PRINTF("FIBMetric: %s\n", $2->string);
804   for (i=0; i<FIBM_CNT; i++) {
805     if (strcmp($2->string, FIB_METRIC_TXT[i]) == 0) {
806       olsr_cnf->fib_metric = i;
807       break;
808     }
809   }
810   if (i == FIBM_CNT) {
811     fprintf(stderr, "Bad FIBMetric value: %s\n", $2->string);
812     YYABORT;
813   }
814   free($1);
815   free($2->string);
816   free($2);
817 }
818 ;
819
820 ihna4entry:     TOK_IPV4_ADDR TOK_IPV4_ADDR
821 {
822   union olsr_ip_addr ipaddr, netmask;
823
824   if (olsr_cnf->ip_version == AF_INET6) {
825     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
826     olsr_startup_sleep(3);
827   }
828   else {
829     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
830
831     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
832       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
833       YYABORT;
834     }
835     if (inet_pton(AF_INET, $2->string, &netmask.v4) <= 0) {
836       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
837       YYABORT;
838     }
839
840     /* check that the given IP address is actually a network address */
841     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
842       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
843       YYABORT;
844     }
845
846     /* Queue */
847     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, olsr_netmask_to_prefix(&netmask));
848   }
849   free($1->string);
850   free($1);
851   free($2->string);
852   free($2);
853 }
854         |       TOK_IPV4_ADDR TOK_SLASH TOK_INTEGER
855 {
856   union olsr_ip_addr ipaddr, netmask;
857
858   if (olsr_cnf->ip_version == AF_INET6) {
859     fprintf(stderr, "IPv4 addresses can only be used if \"IpVersion\" == 4, skipping HNA.\n");
860     olsr_startup_sleep(3);
861   }
862   else {
863     PARSER_DEBUG_PRINTF("HNA IPv4 entry: %s/%d\n", $1->string, $3->integer);
864
865     if (inet_pton(AF_INET, $1->string, &ipaddr.v4) <= 0) {
866       fprintf(stderr, "ihna4entry: Failed converting IP address %s\n", $1->string);
867       YYABORT;
868     }
869     if ($3->integer > olsr_cnf->maxplen) {
870       fprintf(stderr, "ihna4entry: Prefix len %u > %d is not allowed!\n", $3->integer, olsr_cnf->maxplen);
871       YYABORT;
872     }
873
874     /* check that the given IP address is actually a network address */
875     olsr_prefix_to_netmask(&netmask, $3->integer);
876     if ((ipaddr.v4.s_addr & ~netmask.v4.s_addr) != 0) {
877       fprintf(stderr, "ihna4entry: The ipaddress \"%s\" is not a network address!\n", $1->string);
878       YYABORT;
879     }
880
881     /* Queue */
882     ip_prefix_list_add(&olsr_cnf->hna_entries, &ipaddr, $3->integer);
883   }
884   free($1->string);
885   free($1);
886   free($3);
887 }
888 ;
889
890 ihna6entry:     TOK_IPV6_ADDR TOK_INTEGER
891 {
892   if (add_ipv6_addr($1, $2)) {
893     YYABORT;
894   }
895 }
896         |       TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
897 {
898   if (add_ipv6_addr($1, $3)) {
899     YYABORT;
900   }
901 }
902 ;
903
904 ifstart: TOK_INTERFACE
905 {
906   PARSER_DEBUG_PRINTF("setting ifs_in_curr_cfg = 0\n");
907   ifs_in_curr_cfg = 0;
908 }
909 ;
910
911 ifnick: TOK_STRING
912 {
913   struct olsr_if *in, *last;
914   in = olsr_cnf->interfaces;
915   last = NULL;
916   while (in != NULL) {
917     if (strcmp(in->name, $1->string) == 0) {
918       free ($1->string);
919       break;
920     }
921     last = in;
922     in = in->next;
923   }
924
925   if (in != NULL) {
926     /* remove old interface from list to add it later at the beginning */
927     if (last) {
928       last->next = in->next;
929     }
930     else {
931       olsr_cnf->interfaces = in->next;
932     }
933   }
934   else {
935     in = malloc(sizeof(*in));
936     if (in == NULL) {
937       fprintf(stderr, "Out of memory(ADD IF)\n");
938       YYABORT;
939     }
940     memset(in, 0, sizeof(*in));
941
942     in->cnf = malloc(sizeof(*in->cnf));
943     if (in->cnf == NULL) {
944       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
945       YYABORT;
946     }
947     memset(in->cnf, 0x00, sizeof(*in->cnf));
948
949     in->cnfi = malloc(sizeof(*in->cnfi));
950     if (in->cnf == NULL) {
951       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
952       YYABORT;
953     }
954     memset(in->cnfi, 0xFF, sizeof(*in->cnfi));
955     in->cnfi->orig_lq_mult_cnt=0;
956
957     in->name = $1->string;
958   }
959   /* Queue */
960   in->next = olsr_cnf->interfaces;
961   olsr_cnf->interfaces = in;
962   ifs_in_curr_cfg++;
963   free($1);
964 }
965 ;
966
967 bnoint: TOK_NOINT TOK_BOOLEAN
968 {
969   PARSER_DEBUG_PRINTF("Noint set to %d\n", $2->boolean);
970   olsr_cnf->allow_no_interfaces = $2->boolean;
971   free($2);
972 }
973 ;
974
975 atos: TOK_TOS TOK_INTEGER
976 {
977   PARSER_DEBUG_PRINTF("TOS: %d\n", $2->integer);
978   olsr_cnf->tos = $2->integer;
979   free($2);
980
981 }
982 ;
983
984 aolsrport: TOK_OLSRPORT TOK_INTEGER
985 {
986   PARSER_DEBUG_PRINTF("OlsrPort: %d\n", $2->integer);
987   olsr_cnf->olsrport = $2->integer;
988   free($2);
989 }
990 ;
991
992 irtproto: TOK_RTPROTO TOK_INTEGER
993 {
994   PARSER_DEBUG_PRINTF("RtProto: %d\n", $2->integer);
995   olsr_cnf->rt_proto = $2->integer;
996   free($2);
997 }
998 ;
999
1000 irttable: TOK_RTTABLE TOK_INTEGER
1001 {
1002   PARSER_DEBUG_PRINTF("RtTable: %d\n", $2->integer);
1003   olsr_cnf->rt_table = $2->integer;
1004   free($2);
1005 }
1006        | TOK_RTTABLE TOK_AUTO
1007 {
1008   PARSER_DEBUG_PRINTF("RtTable: auto\n");
1009   olsr_cnf->rt_table = DEF_RT_AUTO;
1010   free($2);
1011 }
1012 ;
1013
1014 irttable_default: TOK_RTTABLE_DEFAULT TOK_INTEGER
1015 {
1016   PARSER_DEBUG_PRINTF("RtTableDefault: %d\n", $2->integer);
1017   olsr_cnf->rt_table_default = $2->integer;
1018   free($2);
1019 }
1020        | TOK_RTTABLE_DEFAULT TOK_AUTO
1021 {
1022   PARSER_DEBUG_PRINTF("RtTableDefault: auto\n");
1023   olsr_cnf->rt_table_default = DEF_RT_AUTO;
1024   free($2);
1025 }
1026 ;
1027
1028 irttable_tunnel: TOK_RTTABLE_TUNNEL TOK_INTEGER
1029 {
1030   PARSER_DEBUG_PRINTF("RtTableTunnel: %d\n", $2->integer);
1031   olsr_cnf->rt_table_tunnel = $2->integer;
1032   free($2);
1033 }
1034        | TOK_RTTABLE_TUNNEL TOK_AUTO
1035 {
1036   PARSER_DEBUG_PRINTF("RtTableTunnel: auto\n");
1037   olsr_cnf->rt_table_tunnel = DEF_RT_AUTO;
1038   free($2);
1039 }
1040 ;
1041
1042 irttable_priority: TOK_RTTABLE_PRIORITY TOK_INTEGER
1043 {
1044   PARSER_DEBUG_PRINTF("RtTablePriority: %d\n", $2->integer);
1045   olsr_cnf->rt_table_pri = $2->integer;
1046   free($2);
1047 }
1048         | TOK_RTTABLE_PRIORITY TOK_AUTO
1049 {
1050   PARSER_DEBUG_PRINTF("RtTablePriority: auto\n");
1051   olsr_cnf->rt_table_pri = DEF_RT_AUTO;
1052   free($2);
1053 }
1054         | TOK_RTTABLE_PRIORITY TOK_NONE
1055 {
1056   PARSER_DEBUG_PRINTF("RtTablePriority: none\n");
1057   olsr_cnf->rt_table_pri = DEF_RT_NONE;
1058   free($2);
1059 }
1060 ;
1061
1062 irttable_default_priority: TOK_RTTABLE_DEFAULT_PRIORITY TOK_INTEGER
1063 {
1064   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: %d\n", $2->integer);
1065   olsr_cnf->rt_table_default_pri = $2->integer;
1066   free($2);
1067 }
1068         | TOK_RTTABLE_DEFAULT_PRIORITY TOK_AUTO
1069 {
1070   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: auto\n");
1071   olsr_cnf->rt_table_default_pri = DEF_RT_AUTO;
1072   free($2);
1073 }
1074         | TOK_RTTABLE_DEFAULT_PRIORITY TOK_NONE
1075 {
1076   PARSER_DEBUG_PRINTF("RtTableDefaultPriority: none\n");
1077   olsr_cnf->rt_table_default_pri = DEF_RT_NONE;
1078   free($2);
1079 }
1080 ;
1081
1082 irttable_tunnel_priority: TOK_RTTABLE_TUNNEL_PRIORITY TOK_INTEGER
1083 {
1084   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: %d\n", $2->integer);
1085   olsr_cnf->rt_table_tunnel_pri = $2->integer;
1086   free($2);
1087 }
1088         | TOK_RTTABLE_TUNNEL_PRIORITY TOK_AUTO
1089 {
1090   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: auto\n");
1091   olsr_cnf->rt_table_tunnel_pri = DEF_RT_AUTO;
1092   free($2);
1093 }
1094         | TOK_RTTABLE_TUNNEL_PRIORITY TOK_NONE
1095 {
1096   PARSER_DEBUG_PRINTF("RtTableTunnelPriority: none\n");
1097   olsr_cnf->rt_table_tunnel_pri = DEF_RT_NONE;
1098   free($2);
1099 }
1100 ;
1101
1102 irttable_defaultolsr_priority: TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_INTEGER
1103 {
1104   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: %d\n", $2->integer);
1105   olsr_cnf->rt_table_defaultolsr_pri = $2->integer;
1106   free($2);
1107 }
1108         | TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_AUTO
1109 {
1110   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: auto\n");
1111   olsr_cnf->rt_table_defaultolsr_pri = DEF_RT_AUTO;
1112   free($2);
1113 }
1114         | TOK_RTTABLE_DEFAULTOLSR_PRIORITY TOK_NONE
1115 {
1116   PARSER_DEBUG_PRINTF("RtTableDefaultOlsrPriority: none\n");
1117   olsr_cnf->rt_table_defaultolsr_pri = DEF_RT_NONE;
1118   free($2);
1119 }
1120 ;
1121
1122 awillingness: TOK_WILLINGNESS TOK_INTEGER
1123 {
1124   PARSER_DEBUG_PRINTF("Willingness: %d\n", $2->integer);
1125   olsr_cnf->willingness_auto = false;
1126   olsr_cnf->willingness = $2->integer;
1127   free($2);
1128 }
1129 ;
1130
1131 busehyst: TOK_USEHYST TOK_BOOLEAN
1132 {
1133   olsr_cnf->use_hysteresis = $2->boolean;
1134   PARSER_DEBUG_PRINTF("Hysteresis %s\n", olsr_cnf->use_hysteresis ? "enabled" : "disabled");
1135   free($2);
1136 }
1137 ;
1138
1139 fhystscale: TOK_HYSTSCALE TOK_FLOAT
1140 {
1141   olsr_cnf->hysteresis_param.scaling = $2->floating;
1142   PARSER_DEBUG_PRINTF("Hysteresis Scaling: %0.2f\n", $2->floating);
1143   free($2);
1144 }
1145 ;
1146
1147 fhystupper: TOK_HYSTUPPER TOK_FLOAT
1148 {
1149   olsr_cnf->hysteresis_param.thr_high = $2->floating;
1150   PARSER_DEBUG_PRINTF("Hysteresis UpperThr: %0.2f\n", $2->floating);
1151   free($2);
1152 }
1153 ;
1154
1155 fhystlower: TOK_HYSTLOWER TOK_FLOAT
1156 {
1157   olsr_cnf->hysteresis_param.thr_low = $2->floating;
1158   PARSER_DEBUG_PRINTF("Hysteresis LowerThr: %0.2f\n", $2->floating);
1159   free($2);
1160 }
1161 ;
1162
1163 fpollrate: TOK_POLLRATE TOK_FLOAT
1164 {
1165   PARSER_DEBUG_PRINTF("Pollrate %0.2f\n", $2->floating);
1166   olsr_cnf->pollrate = $2->floating;
1167   free($2);
1168 }
1169 ;
1170
1171 fnicchgspollrt: TOK_NICCHGSPOLLRT TOK_FLOAT
1172 {
1173   PARSER_DEBUG_PRINTF("NIC Changes Pollrate %0.2f\n", $2->floating);
1174   olsr_cnf->nic_chgs_pollrate = $2->floating;
1175   free($2);
1176 }
1177 ;
1178
1179 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
1180 {
1181   PARSER_DEBUG_PRINTF("TC redundancy %d\n", $2->integer);
1182   olsr_cnf->tc_redundancy = $2->integer;
1183   free($2);
1184 }
1185 ;
1186
1187 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
1188 {
1189   PARSER_DEBUG_PRINTF("MPR coverage %d\n", $2->integer);
1190   olsr_cnf->mpr_coverage = $2->integer;
1191   free($2);
1192 }
1193 ;
1194
1195 alq_level: TOK_LQ_LEVEL TOK_INTEGER
1196 {
1197   PARSER_DEBUG_PRINTF("Link quality level %d\n", $2->integer);
1198   olsr_cnf->lq_level = $2->integer;
1199   free($2);
1200 }
1201 ;
1202
1203 alq_fish: TOK_LQ_FISH TOK_INTEGER
1204 {
1205   PARSER_DEBUG_PRINTF("Link quality fish eye %d\n", $2->integer);
1206   olsr_cnf->lq_fish = $2->integer;
1207   free($2);
1208 }
1209 ;
1210
1211 alq_aging: TOK_LQ_AGING TOK_FLOAT
1212 {
1213   PARSER_DEBUG_PRINTF("Link quality aging factor %f\n", $2->floating);
1214   olsr_cnf->lq_aging = $2->floating;
1215   free($2);
1216 }
1217 ;
1218
1219 amin_tc_vtime: TOK_MIN_TC_VTIME TOK_FLOAT
1220 {
1221   PARSER_DEBUG_PRINTF("Minimum TC validity time %f\n", $2->floating);
1222   olsr_cnf->min_tc_vtime = $2->floating;
1223   free($2);
1224 }
1225 ;
1226
1227 alock_file: TOK_LOCK_FILE TOK_STRING
1228 {
1229   PARSER_DEBUG_PRINTF("Lock file %s\n", $2->string);
1230   olsr_cnf->lock_file = $2->string;
1231   free($2);
1232 }
1233 ;
1234 alq_plugin: TOK_LQ_PLUGIN TOK_STRING
1235 {
1236   olsr_cnf->lq_algorithm = $2->string;
1237   PARSER_DEBUG_PRINTF("LQ Algorithm: %s\n", $2->string);
1238   free($2);
1239 }
1240 ;
1241
1242 anat_thresh: TOK_LQ_NAT_THRESH TOK_FLOAT
1243 {
1244   PARSER_DEBUG_PRINTF("NAT threshold %0.2f\n", $2->floating);
1245   olsr_cnf->lq_nat_thresh = $2->floating;
1246   free($2);
1247 }
1248 ;
1249
1250 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
1251 {
1252   PARSER_DEBUG_PRINTF("Clear screen %s\n", $2->boolean ? "enabled" : "disabled");
1253   olsr_cnf->clear_screen = $2->boolean;
1254   free($2);
1255 }
1256 ;
1257
1258 suse_niit: TOK_USE_NIIT TOK_BOOLEAN
1259 {
1260   PARSER_DEBUG_PRINTF("Use NIIT ip translation: %s\n", $2->boolean ? "enabled" : "disabled");
1261   olsr_cnf->use_niit = $2->boolean;
1262   free($2);
1263 }
1264 ;
1265
1266 bsmart_gw: TOK_SMART_GW TOK_BOOLEAN
1267 {
1268         PARSER_DEBUG_PRINTF("Smart gateway system: %s\n", $2->boolean ? "enabled" : "disabled");
1269         olsr_cnf->smart_gw_active = $2->boolean;
1270         free($2);
1271 }
1272 ;
1273
1274 bsmart_gw_allow_nat: TOK_SMART_GW_ALLOW_NAT TOK_BOOLEAN
1275 {
1276         PARSER_DEBUG_PRINTF("Smart gateway allow client nat: %s\n", $2->boolean ? "yes" : "no");
1277         olsr_cnf->smart_gw_allow_nat = $2->boolean;
1278         free($2);
1279 }
1280 ;
1281
1282 ssmart_gw_uplink: TOK_SMART_GW_UPLINK TOK_STRING
1283 {
1284         PARSER_DEBUG_PRINTF("Smart gateway uplink: %s\n", $2->string);
1285         if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_NONE]) == 0) {
1286                 olsr_cnf->smart_gw_type = GW_UPLINK_NONE;
1287         }
1288         if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV4]) == 0) {
1289                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV4;
1290         }
1291         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV6]) == 0) {
1292                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV6;
1293         }
1294         else if (strcasecmp($2->string, GW_UPLINK_TXT[GW_UPLINK_IPV46]) == 0) {
1295                 olsr_cnf->smart_gw_type = GW_UPLINK_IPV46;
1296         }
1297         else {
1298                 fprintf(stderr, "Bad gateway uplink type: %s\n", $2->string);
1299                 YYABORT;
1300         }
1301         free($2);
1302 }
1303 ;
1304
1305 ismart_gw_speed: TOK_SMART_GW_SPEED TOK_INTEGER TOK_INTEGER
1306 {
1307         PARSER_DEBUG_PRINTF("Smart gateway speed: %u uplink/%u downlink kbit/s\n", $2->integer, $3->integer);
1308         olsr_cnf->smart_gw_uplink = $2->integer;
1309         olsr_cnf->smart_gw_downlink = $3->integer;
1310         free($2);
1311         free($3);
1312 }
1313 ;
1314
1315 bsmart_gw_uplink_nat: TOK_SMART_GW_UPLINK_NAT TOK_BOOLEAN
1316 {
1317         PARSER_DEBUG_PRINTF("Smart gateway uplink nat: %s\n", $2->boolean ? "yes" : "no");
1318         olsr_cnf->smart_gw_uplink_nat = $2->boolean;
1319         free($2);
1320 }
1321 ;
1322
1323 ismart_gw_prefix: TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_INTEGER
1324 {
1325   PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $3->integer);
1326         if (inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->smart_gw_prefix.prefix) == 0) {
1327           fprintf(stderr, "Bad IP part of gateway prefix: %s\n", $2->string);
1328     YYABORT;
1329   }
1330         olsr_cnf->smart_gw_prefix.prefix_len = (uint8_t)$3->integer;
1331         
1332         free($2);
1333         free($3);
1334 }
1335         |       TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_SLASH TOK_INTEGER
1336 {
1337         PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $4->integer);
1338         if (inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->smart_gw_prefix.prefix) == 0) {
1339           fprintf(stderr, "Bad IP part of gateway prefix: %s\n", $2->string);
1340     YYABORT;
1341   }
1342         olsr_cnf->smart_gw_prefix.prefix_len = (uint8_t)$4->integer;
1343         
1344         free($2);
1345         free($4);
1346 }
1347 ;
1348
1349 bsrc_ip_routes: TOK_SRC_IP_ROUTES TOK_BOOLEAN
1350 {
1351         PARSER_DEBUG_PRINTF("Use originator for routes src-ip: %s\n", $2->boolean ? "yes" : "no");
1352         olsr_cnf->use_src_ip_routes = $2->boolean;
1353         free($2);
1354 }
1355 ;
1356
1357 amain_ip: TOK_MAIN_IP TOK_IPV4_ADDR
1358 {
1359   PARSER_DEBUG_PRINTF("Fixed Main IP: %s\n", $2->string);
1360   
1361   if (olsr_cnf->ip_version != AF_INET
1362       || inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->main_addr) != 1) {
1363     fprintf(stderr, "Bad main IP: %s\n", $2->string);
1364     YYABORT;
1365   }
1366   free($2);
1367 }
1368         |       TOK_MAIN_IP TOK_IPV6_ADDR
1369 {
1370   PARSER_DEBUG_PRINTF("Fixed Main IP: %s\n", $2->string);
1371   
1372   if (olsr_cnf->ip_version != AF_INET6
1373       || inet_pton(olsr_cnf->ip_version, $2->string, &olsr_cnf->main_addr) != 1) {
1374     fprintf(stderr, "Bad main IP: %s\n", $2->string);
1375     YYABORT;
1376   }
1377   free($2);
1378 }
1379
1380 plblock: TOK_PLUGIN TOK_STRING
1381 {
1382   struct plugin_entry *pe, *last;
1383   
1384   pe = olsr_cnf->plugins;
1385   last = NULL;
1386   while (pe != NULL) {
1387     if (strcmp(pe->name, $2->string) == 0) {
1388       free ($2->string);
1389       break;
1390     }
1391     last = pe;
1392     pe = pe->next;
1393   }
1394
1395   if (pe != NULL) {
1396     /* remove old plugin from list to add it later at the beginning */
1397     if (last) {
1398       last->next = pe->next;
1399     }
1400     else {
1401       olsr_cnf->plugins = pe->next;
1402     }
1403   }
1404   else {
1405     pe = malloc(sizeof(*pe));
1406
1407     if (pe == NULL) {
1408       fprintf(stderr, "Out of memory(ADD PL)\n");
1409       YYABORT;
1410     }
1411
1412     pe->name = $2->string;
1413     pe->params = NULL;
1414
1415     PARSER_DEBUG_PRINTF("Plugin: %s\n", $2->string);
1416   }
1417   
1418   /* Queue */
1419   pe->next = olsr_cnf->plugins;
1420   olsr_cnf->plugins = pe;
1421
1422   free($2);
1423 }
1424 ;
1425
1426 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
1427 {
1428   struct plugin_param *pp = malloc(sizeof(*pp));
1429   
1430   if (pp == NULL) {
1431     fprintf(stderr, "Out of memory(ADD PP)\n");
1432     YYABORT;
1433   }
1434   
1435   PARSER_DEBUG_PRINTF("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
1436   
1437   pp->key = $2->string;
1438   pp->value = $3->string;
1439
1440   /* Queue */
1441   pp->next = olsr_cnf->plugins->params;
1442   olsr_cnf->plugins->params = pp;
1443
1444   free($2);
1445   free($3);
1446 }
1447 ;
1448
1449 vcomment:       TOK_COMMENT
1450 {
1451     //PARSER_DEBUG_PRINTF("Comment\n");
1452 }
1453 ;
1454
1455
1456
1457 %%
1458
1459 void yyerror (const char *string)
1460 {
1461   fprintf(stderr, "Config line %d: %s\n", current_line, string);
1462 }