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