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