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