Implemented LinkQualityMult per-interface configuration directive.
[olsrd.git] / src / cfgparser / oparse.y
1 %{
2
3 /*
4  * The olsr.org Optimized Link-State Routing daemon(olsrd)
5  * Copyright (c) 2004, Andreas T√łnnesen(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  * $Id: oparse.y,v 1.24 2005/02/15 17:17:46 tlopatic Exp $
42  */
43
44
45 #include <stddef.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <sys/types.h>
49 #include <sys/socket.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
52 #include <string.h>
53
54 #include "olsrd_conf.h"
55
56 #define PARSER_DEBUG 0
57
58 #define YYSTYPE struct conf_token *
59
60 void yyerror(char *);
61 int yylex(void);
62
63 static int ifs_in_curr_cfg = 0;
64
65 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg);
66
67 static int lq_mult_helper(YYSTYPE ip_addr_arg, YYSTYPE mult_arg)
68 {
69   union olsr_ip_addr addr;
70   int i;
71   struct olsr_if *walker;
72   struct olsr_lq_mult *mult;
73
74 #if PARSER_DEBUG > 0
75   printf("\tLinkQualityMult %s %0.2f\n",
76          (ip_addr_arg != NULL) ? ip_addr_arg->string : "any",
77          mult_arg->floating);
78 #endif
79
80   memset(&addr, 0, sizeof (union olsr_ip_addr));
81
82   if(ip_addr_arg != NULL &&
83      inet_pton(cnf->ip_version, ip_addr_arg->string, &addr) < 0)
84   {
85     fprintf(stderr, "Cannot parse IP address %s.\n", ip_addr_arg->string);
86     return -1;
87   }
88
89   walker = cnf->interfaces;
90
91   for (i = 0; i < ifs_in_curr_cfg; i++)
92   {
93     mult = malloc(sizeof (struct olsr_lq_mult));
94
95     if (mult == NULL)
96     {
97       fprintf(stderr, "Out of memory (LQ multiplier).\n");
98       return -1;
99     }
100
101     memcpy(&mult->addr, &addr, sizeof (union olsr_ip_addr));
102     mult->val = mult_arg->floating;
103
104     mult->next = walker->cnf->lq_mult;
105     walker->cnf->lq_mult = mult;
106
107     walker = walker->next;
108   }
109
110   if (ip_addr_arg != NULL)
111   {
112     free(ip_addr_arg->string);
113     free(ip_addr_arg);
114   }
115
116   free(mult_arg);
117
118   return 0;
119 }
120 %}
121
122 %token TOK_OPEN
123 %token TOK_CLOSE
124 %token TOK_SEMI
125
126 %token TOK_STRING
127 %token TOK_INTEGER
128 %token TOK_FLOAT
129 %token TOK_BOOLEAN
130
131 %token TOK_IP6TYPE
132
133 %token TOK_DEBUGLEVEL
134 %token TOK_IPVERSION
135 %token TOK_HNA4
136 %token TOK_HNA6
137 %token TOK_PLUGIN
138 %token TOK_INTERFACE
139 %token TOK_NOINT
140 %token TOK_TOS
141 %token TOK_WILLINGNESS
142 %token TOK_IPCCON
143 %token TOK_USEHYST
144 %token TOK_HYSTSCALE
145 %token TOK_HYSTUPPER
146 %token TOK_HYSTLOWER
147 %token TOK_POLLRATE
148 %token TOK_TCREDUNDANCY
149 %token TOK_MPRCOVERAGE
150 %token TOK_LQ_LEVEL
151 %token TOK_LQ_WSIZE
152 %token TOK_LQ_MULT
153 %token TOK_CLEAR_SCREEN
154 %token TOK_PLNAME
155 %token TOK_PLPARAM
156
157 %token TOK_HOSTLABEL
158 %token TOK_NETLABEL
159 %token TOK_MAXIPC
160
161 %token TOK_IP4BROADCAST
162 %token TOK_IP6ADDRTYPE
163 %token TOK_IP6MULTISITE
164 %token TOK_IP6MULTIGLOBAL
165 %token TOK_HELLOINT
166 %token TOK_HELLOVAL
167 %token TOK_TCINT
168 %token TOK_TCVAL
169 %token TOK_MIDINT
170 %token TOK_MIDVAL
171 %token TOK_HNAINT
172 %token TOK_HNAVAL
173
174 %token TOK_IP4_ADDR
175 %token TOK_IP6_ADDR
176 %token TOK_DEFAULT
177
178 %token TOK_COMMENT
179
180 %%
181
182 conf:
183           | conf block
184           | conf stmt
185 ;
186
187 stmt:       idebug
188           | iipversion
189           | bnoint
190           | atos
191           | awillingness
192           | busehyst
193           | fhystscale
194           | fhystupper
195           | fhystlower
196           | fpollrate
197           | atcredundancy
198           | amprcoverage
199           | alq_level
200           | alq_wsize
201           | bclear_screen
202           | vcomment
203 ;
204
205 block:      TOK_HNA4 hna4body
206           | TOK_HNA6 hna6body
207           | TOK_IPCCON ipcbody
208           | ifblock ifbody
209           | plblock plbody
210 ;
211
212 hna4body:       TOK_OPEN hna4stmts TOK_CLOSE
213 ;
214
215 hna4stmts: | hna4stmts hna4stmt
216 ;
217
218 hna4stmt:  vcomment
219          | ihna4entry
220 ;
221
222 hna6body:       TOK_OPEN hna6stmts TOK_CLOSE
223 ;
224
225 hna6stmts: | hna6stmts hna6stmt
226 ;
227
228 hna6stmt:  vcomment
229          | ihna6entry
230 ;
231
232 ipcbody:    TOK_OPEN ipcstmts TOK_CLOSE
233 ;
234
235 ipcstmts: | ipcstmts ipcstmt
236 ;
237
238 ipcstmt:  vcomment
239           | imaxipc
240           | ipchost
241           | ipcnet
242 ;
243
244 ifblock:   ifstart ifnicks
245 ;
246
247 ifnicks:   | ifnicks ifnick
248 ;
249
250 ifbody:     TOK_OPEN ifstmts TOK_CLOSE
251 ;
252
253 ifstmts:   | ifstmts ifstmt
254 ;
255
256 ifstmt:      vcomment
257              | isetip4br
258              | isetip6addrt
259              | isetip6mults
260              | isetip6multg
261              | isethelloint
262              | isethelloval
263              | isettcint
264              | isettcval
265              | isetmidint
266              | isetmidval
267              | isethnaint
268              | isethnaval
269              | isetlqmult
270 ;
271
272 plbody:     TOK_OPEN plstmts TOK_CLOSE
273 ;
274
275 plstmts:   | plstmts plstmt
276 ;
277
278 plstmt:     plparam
279           | vcomment
280 ;
281
282
283 imaxipc: TOK_MAXIPC TOK_INTEGER
284 {
285   cnf->ipc_connections = $2->integer;
286
287   cnf->open_ipc = cnf->ipc_connections ? OLSR_TRUE : OLSR_FALSE;
288
289   free($2);
290 }
291 ;
292
293
294 ipchost: TOK_HOSTLABEL TOK_IP4_ADDR
295 {
296   struct in_addr in;
297   struct ipc_host *ipch;
298
299   if(PARSER_DEBUG) printf("\tIPC host: %s\n", $2->string);
300   
301   if(inet_aton($2->string, &in) == 0)
302     {
303       fprintf(stderr, "Failed converting IP address IPC %s\n", $2->string);
304       return -1;
305     }
306
307   ipch = malloc(sizeof(struct ipc_host));
308   ipch->host.v4 = in.s_addr;
309
310   ipch->next = cnf->ipc_hosts;
311   cnf->ipc_hosts = ipch;
312
313   free($2->string);
314   free($2);
315
316 }
317 ;
318
319 ipcnet: TOK_NETLABEL TOK_IP4_ADDR TOK_IP4_ADDR
320 {
321   struct in_addr in1, in2;
322   struct ipc_net *ipcn;
323
324   if(PARSER_DEBUG) printf("\tIPC net: %s/%s\n", $2->string, $3->string);
325   
326   if(inet_aton($2->string, &in1) == 0)
327     {
328       fprintf(stderr, "Failed converting IP net IPC %s\n", $2->string);
329       return -1;
330     }
331
332   if(inet_aton($3->string, &in2) == 0)
333     {
334       fprintf(stderr, "Failed converting IP mask IPC %s\n", $3->string);
335       return -1;
336     }
337
338   ipcn = malloc(sizeof(struct ipc_net));
339   ipcn->net.v4 = in1.s_addr;
340   ipcn->mask.v4 = in2.s_addr;
341
342   ipcn->next = cnf->ipc_nets;
343   cnf->ipc_nets = ipcn;
344
345   free($2->string);
346   free($2);
347   free($3->string);
348   free($3);
349
350 }
351 ;
352
353 isetip4br: TOK_IP4BROADCAST TOK_IP4_ADDR
354 {
355   struct in_addr in;
356   int ifcnt = ifs_in_curr_cfg;
357   struct olsr_if *ifs = cnf->interfaces;
358
359   if(PARSER_DEBUG) printf("\tIPv4 broadcast: %s\n", $2->string);
360
361   if(inet_aton($2->string, &in) == 0)
362     {
363       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
364       return -1;
365     }
366
367   while(ifcnt)
368     {
369       ifs->cnf->ipv4_broadcast.v4 = in.s_addr;
370
371       ifs = ifs->next;
372       ifcnt--;
373     }
374
375   free($2->string);
376   free($2);
377 }
378 ;
379
380 isetip6addrt: TOK_IP6ADDRTYPE TOK_IP6TYPE
381 {
382   int ifcnt = ifs_in_curr_cfg;
383   struct olsr_if *ifs = cnf->interfaces;
384
385   if($2->boolean)
386     {
387       while(ifcnt)
388         {
389           ifs->cnf->ipv6_addrtype = IPV6_ADDR_SITELOCAL;
390           
391           ifs = ifs->next;
392           ifcnt--;
393         }
394     }
395   else
396     {
397       while(ifcnt)
398         {
399           ifs->cnf->ipv6_addrtype = 0;
400           
401           ifs = ifs->next;
402           ifcnt--;
403         }
404     }
405
406   free($2);
407 }
408 ;
409
410 isetip6mults: TOK_IP6MULTISITE TOK_IP6_ADDR
411 {
412   struct in6_addr in6;
413   int ifcnt = ifs_in_curr_cfg;
414   struct olsr_if *ifs = cnf->interfaces;
415
416   if(PARSER_DEBUG) printf("\tIPv6 site-local multicast: %s\n", $2->string);
417
418   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
419     {
420       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
421       return -1;
422     }
423
424   while(ifcnt)
425     {
426       memcpy(&ifs->cnf->ipv6_multi_site.v6, &in6, sizeof(struct in6_addr));
427       
428       ifs = ifs->next;
429       ifcnt--;
430     }
431
432
433   free($2->string);
434   free($2);
435 }
436 ;
437
438
439 isetip6multg: TOK_IP6MULTIGLOBAL TOK_IP6_ADDR
440 {
441   struct in6_addr in6;
442   int ifcnt = ifs_in_curr_cfg;
443   struct olsr_if *ifs = cnf->interfaces;
444
445   if(PARSER_DEBUG) printf("\tIPv6 global multicast: %s\n", $2->string);
446
447   if(inet_pton(AF_INET6, $2->string, &in6) < 0)
448     {
449       fprintf(stderr, "Failed converting IP address %s\n", $2->string);
450       return -1;
451     }
452
453   while(ifcnt)
454     {
455       memcpy(&ifs->cnf->ipv6_multi_glbl.v6, &in6, sizeof(struct in6_addr));
456       
457       ifs = ifs->next;
458       ifcnt--;
459     }
460
461
462   free($2->string);
463   free($2);
464 }
465 ;
466 isethelloint: TOK_HELLOINT TOK_FLOAT
467 {
468   int ifcnt = ifs_in_curr_cfg;
469   struct olsr_if *ifs = cnf->interfaces;
470
471   if(PARSER_DEBUG) printf("\tHELLO interval: %0.2f\n", $2->floating);
472
473   while(ifcnt)
474     {
475       ifs->cnf->hello_params.emission_interval = $2->floating;
476       
477       ifs = ifs->next;
478       ifcnt--;
479     }
480
481   free($2);
482 }
483 ;
484 isethelloval: TOK_HELLOVAL TOK_FLOAT
485 {
486   int ifcnt = ifs_in_curr_cfg;
487   struct olsr_if *ifs = cnf->interfaces;
488
489   if(PARSER_DEBUG) printf("\tHELLO validity: %0.2f\n", $2->floating);
490
491   while(ifcnt)
492     {
493       ifs->cnf->hello_params.validity_time = $2->floating;
494       
495       ifs = ifs->next;
496       ifcnt--;
497     }
498
499   free($2);
500 }
501 ;
502 isettcint: TOK_TCINT TOK_FLOAT
503 {
504   int ifcnt = ifs_in_curr_cfg;
505   struct olsr_if *ifs = cnf->interfaces;
506
507   if(PARSER_DEBUG) printf("\tTC interval: %0.2f\n", $2->floating);
508
509   while(ifcnt)
510     {
511       ifs->cnf->tc_params.emission_interval = $2->floating;
512       
513       ifs = ifs->next;
514       ifcnt--;
515     }
516   free($2);
517 }
518 ;
519 isettcval: TOK_TCVAL TOK_FLOAT
520 {
521   int ifcnt = ifs_in_curr_cfg;
522   struct olsr_if *ifs = cnf->interfaces;
523   
524   if(PARSER_DEBUG) printf("\tTC validity: %0.2f\n", $2->floating);
525   while(ifcnt)
526     {
527       ifs->cnf->tc_params.validity_time = $2->floating;
528       
529       ifs = ifs->next;
530       ifcnt--;
531     }
532
533   free($2);
534 }
535 ;
536 isetmidint: TOK_MIDINT TOK_FLOAT
537 {
538   int ifcnt = ifs_in_curr_cfg;
539   struct olsr_if *ifs = cnf->interfaces;
540
541
542   if(PARSER_DEBUG) printf("\tMID interval: %0.2f\n", $2->floating);
543   while(ifcnt)
544     {
545       ifs->cnf->mid_params.emission_interval = $2->floating;
546       
547       ifs = ifs->next;
548       ifcnt--;
549     }
550
551   free($2);
552 }
553 ;
554 isetmidval: TOK_MIDVAL TOK_FLOAT
555 {
556   int ifcnt = ifs_in_curr_cfg;
557   struct olsr_if *ifs = cnf->interfaces;
558
559   if(PARSER_DEBUG) printf("\tMID validity: %0.2f\n", $2->floating);
560   while(ifcnt)
561     {
562       ifs->cnf->mid_params.validity_time = $2->floating;
563       
564       ifs = ifs->next;
565       ifcnt--;
566     }
567
568   free($2);
569 }
570 ;
571 isethnaint: TOK_HNAINT TOK_FLOAT
572 {
573   int ifcnt = ifs_in_curr_cfg;
574   struct olsr_if *ifs = cnf->interfaces;
575   
576   if(PARSER_DEBUG) printf("\tHNA interval: %0.2f\n", $2->floating);
577   while(ifcnt)
578     {
579       ifs->cnf->hna_params.emission_interval = $2->floating;
580       
581       ifs = ifs->next;
582       ifcnt--;
583     }
584
585   free($2);
586 }
587 ;
588 isethnaval: TOK_HNAVAL TOK_FLOAT
589 {
590   int ifcnt = ifs_in_curr_cfg;
591   struct olsr_if *ifs = cnf->interfaces;
592
593   if(PARSER_DEBUG) printf("\tHNA validity: %0.2f\n", $2->floating);
594   while(ifcnt)
595     {
596       ifs->cnf->hna_params.validity_time = $2->floating;
597       
598       ifs = ifs->next;
599       ifcnt--;
600     }
601
602   free($2);
603 }
604 ;
605
606 isetlqmult: TOK_LQ_MULT TOK_DEFAULT TOK_FLOAT
607 {
608   if (lq_mult_helper($2, $3) < 0)
609     YYABORT;
610 }
611
612           | TOK_LQ_MULT TOK_IP4_ADDR TOK_FLOAT
613 {
614   if (lq_mult_helper($2, $3) < 0)
615     YYABORT;
616 }
617
618           | TOK_LQ_MULT TOK_IP6_ADDR TOK_FLOAT
619 {
620   if (lq_mult_helper($2, $3) < 0)
621     YYABORT;
622 }
623
624           ;
625
626 idebug:       TOK_DEBUGLEVEL TOK_INTEGER
627 {
628
629   cnf->debug_level = $2->integer;
630   if(PARSER_DEBUG) printf("Debug level: %d\n", cnf->debug_level);
631   free($2);
632 }
633 ;
634
635
636 iipversion:    TOK_IPVERSION TOK_INTEGER
637 {
638   if($2->integer == 4)
639     cnf->ip_version = AF_INET;
640   else if($2->integer == 6)
641     cnf->ip_version = AF_INET6;
642   else
643     {
644       fprintf(stderr, "IPversion must be 4 or 6!\n");
645       YYABORT;
646     }
647
648   if(PARSER_DEBUG) printf("IpVersion: %d\n", $2->integer);
649   free($2);
650 }
651 ;
652
653
654 ihna4entry:     TOK_IP4_ADDR TOK_IP4_ADDR
655 {
656   struct hna4_entry *h = malloc(sizeof(struct hna4_entry));
657   struct in_addr in;
658
659   if(PARSER_DEBUG) printf("HNA IPv4 entry: %s/%s\n", $1->string, $2->string);
660
661   if(h == NULL)
662     {
663       fprintf(stderr, "Out of memory(HNA4)\n");
664       YYABORT;
665     }
666
667   if(inet_aton($1->string, &in) == 0)
668     {
669       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
670       return -1;
671     }
672   h->net.v4 = in.s_addr;
673   if(inet_aton($2->string, &in) == 0)
674     {
675       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
676       return -1;
677     }
678   h->netmask.v4 = in.s_addr;
679   /* Queue */
680   h->next = cnf->hna4_entries;
681   cnf->hna4_entries = h;
682
683   free($1->string);
684   free($1);
685   free($2->string);
686   free($2);
687
688 }
689 ;
690
691 ihna6entry:     TOK_IP6_ADDR TOK_INTEGER
692 {
693   struct hna6_entry *h = malloc(sizeof(struct hna6_entry));
694   struct in6_addr in6;
695
696   if(PARSER_DEBUG) printf("HNA IPv6 entry: %s/%d\n", $1->string, $2->integer);
697
698   if(h == NULL)
699     {
700       fprintf(stderr, "Out of memory(HNA6)\n");
701       YYABORT;
702     }
703
704   if(inet_pton(AF_INET6, $1->string, &in6) < 0)
705     {
706       fprintf(stderr, "Failed converting IP address %s\n", $1->string);
707       return -1;
708     }
709   memcpy(&h->net, &in6, sizeof(struct in6_addr));
710
711   if(($2->integer < 0) || ($2->integer > 128))
712     {
713       fprintf(stderr, "Illegal IPv6 prefix length %d\n", $2->integer);
714       return -1;
715     }
716
717   h->prefix_len = $2->integer;
718   /* Queue */
719   h->next = cnf->hna6_entries;
720   cnf->hna6_entries = h;
721
722   free($1->string);
723   free($1);
724   free($2);
725
726 }
727 ;
728
729 ifstart: TOK_INTERFACE
730 {
731   printf("setting ifs_in_curr_cfg = 0\n");
732   ifs_in_curr_cfg = 0;
733
734 }
735 ;
736
737 ifnick: TOK_STRING
738 {
739   struct olsr_if *in = malloc(sizeof(struct olsr_if));
740   
741   if(in == NULL)
742     {
743       fprintf(stderr, "Out of memory(ADD IF)\n");
744       YYABORT;
745     }
746
747   in->cnf = get_default_if_config();
748
749   if(in->cnf == NULL)
750     {
751       fprintf(stderr, "Out of memory(ADD IFRULE)\n");
752       YYABORT;
753     }
754
755   in->name = $1->string;
756
757   /* Queue */
758   in->next = cnf->interfaces;
759   cnf->interfaces = in;
760
761   ifs_in_curr_cfg++;
762
763   free($1);
764 }
765 ;
766
767 bnoint: TOK_NOINT TOK_BOOLEAN
768 {
769   if(PARSER_DEBUG) printf("Noint set to %d\n", $2->boolean);
770
771   cnf->allow_no_interfaces = $2->boolean;
772
773   free($2);
774 }
775 ;
776
777 atos: TOK_TOS TOK_INTEGER
778 {
779   if(PARSER_DEBUG) printf("TOS: %d\n", $2->integer);
780   cnf->tos = $2->integer;
781
782   free($2);
783
784 }
785 ;
786
787 awillingness: TOK_WILLINGNESS TOK_INTEGER
788 {
789   cnf->willingness_auto = OLSR_FALSE;
790
791   if(PARSER_DEBUG) printf("Willingness: %d\n", $2->integer);
792   cnf->willingness = $2->integer;
793
794   free($2);
795
796 }
797 ;
798
799
800
801 busehyst: TOK_USEHYST TOK_BOOLEAN
802 {
803   cnf->use_hysteresis = $2->boolean;
804   if(cnf->use_hysteresis)
805     {
806       if(PARSER_DEBUG) printf("Hysteresis enabled\n");
807     }
808   else
809     {
810       if(PARSER_DEBUG) printf("Hysteresis disabled\n");
811     }
812   free($2);
813
814 }
815 ;
816
817
818 fhystscale: TOK_HYSTSCALE TOK_FLOAT
819 {
820   cnf->hysteresis_param.scaling = $2->floating;
821   if(PARSER_DEBUG) printf("Hysteresis Scaling: %0.2f\n", $2->floating);
822   free($2);
823 }
824 ;
825
826
827 fhystupper: TOK_HYSTUPPER TOK_FLOAT
828 {
829   cnf->hysteresis_param.thr_high = $2->floating;
830   if(PARSER_DEBUG) printf("Hysteresis UpperThr: %0.2f\n", $2->floating);
831   free($2);
832 }
833 ;
834
835
836 fhystlower: TOK_HYSTLOWER TOK_FLOAT
837 {
838   cnf->hysteresis_param.thr_low = $2->floating;
839   if(PARSER_DEBUG) printf("Hysteresis LowerThr: %0.2f\n", $2->floating);
840   free($2);
841 }
842 ;
843
844 fpollrate: TOK_POLLRATE TOK_FLOAT
845 {
846   if(PARSER_DEBUG) printf("Pollrate %0.2f\n", $2->floating);
847   cnf->pollrate = $2->floating;
848
849   free($2);
850 }
851 ;
852
853
854 atcredundancy: TOK_TCREDUNDANCY TOK_INTEGER
855 {
856   if(PARSER_DEBUG) printf("TC redundancy %d\n", $2->integer);
857   cnf->tc_redundancy = $2->integer;
858   free($2);
859 }
860 ;
861
862 amprcoverage: TOK_MPRCOVERAGE TOK_INTEGER
863 {
864   if(PARSER_DEBUG) printf("MPR coverage %d\n", $2->integer);
865   cnf->mpr_coverage = $2->integer;
866   free($2);
867 }
868 ;
869
870 alq_level: TOK_LQ_LEVEL TOK_INTEGER
871 {
872   if(PARSER_DEBUG) printf("Link quality level %d\n", $2->integer);
873   cnf->lq_level = $2->integer;
874   free($2);
875 }
876 ;
877
878 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
879 {
880   if(PARSER_DEBUG) printf("Link quality window size %d\n", $2->integer);
881   cnf->lq_wsize = $2->integer;
882   free($2);
883 }
884 ;
885
886 bclear_screen: TOK_CLEAR_SCREEN TOK_BOOLEAN
887 {
888   cnf->clear_screen = $2->boolean;
889
890   if (PARSER_DEBUG)
891     printf("Clear screen %s\n", cnf->clear_screen ? "enabled" : "disabled");
892
893   free($2);
894 }
895 ;
896
897 plblock: TOK_PLUGIN TOK_STRING
898 {
899   struct plugin_entry *pe = malloc(sizeof(struct plugin_entry));
900   
901   if(pe == NULL)
902     {
903       fprintf(stderr, "Out of memory(ADD PL)\n");
904       YYABORT;
905     }
906
907   pe->name = $2->string;
908
909   pe->params = NULL;
910   
911   if(PARSER_DEBUG) printf("Plugin: %s\n", $2->string);
912
913   /* Queue */
914   pe->next = cnf->plugins;
915   cnf->plugins = pe;
916
917   free($2);
918 }
919 ;
920
921 plparam: TOK_PLPARAM TOK_STRING TOK_STRING
922 {
923   struct plugin_param *pp = malloc(sizeof(struct plugin_param));
924   
925   if(pp == NULL)
926     {
927       fprintf(stderr, "Out of memory(ADD PP)\n");
928       YYABORT;
929     }
930   
931   if(PARSER_DEBUG) printf("Plugin param key:\"%s\" val: \"%s\"\n", $2->string, $3->string);
932   
933   pp->key = $2->string;
934   pp->value = $3->string;
935
936   /* Queue */
937   pp->next = cnf->plugins->params;
938   cnf->plugins->params = pp;
939
940   free($2);
941   free($3);
942 }
943 ;
944
945 vcomment:       TOK_COMMENT
946 {
947     //if(PARSER_DEBUG) printf("Comment\n");
948 }
949 ;
950
951
952
953 %%
954
955 void yyerror (char *string)
956 {
957   fprintf(stderr, "Config line %d: %s\n", current_line, string);
958 }