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