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