1 /*
2  * The olsr.org Optimized Link-State Routing daemon (olsrd)
3  *
4  * (c) by the OLSR project
5  *
6  * See our Git repository to find out who worked on this file
7  * and thus is a copyright holder on it.
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * * Redistributions of source code must retain the above copyright
16  *   notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above copyright
18  *   notice, this list of conditions and the following disclaimer in
19  *   the documentation and/or other materials provided with the
20  *   distribution.
21  * * Neither the name of olsr.org, olsrd nor the names of its
22  *   contributors may be used to endorse or promote products derived
23  *   from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  *
38  * Visit http://www.olsr.org for more information.
39  *
40  * If you find this software useful feel free to make a donation
41  * to the project. For more information see the website or contact
42  * the copyright holders.
43  *
44  */
45 
46 #include "olsrd_conf.h"
47 #include "builddata.h"
48 #include "ipcalc.h"
49 #include "net_olsr.h"
50 #include "common/autobuf.h"
51 #include "egressTypes.h"
52 #include "lock_file.h"
53 
54 #include <stdarg.h>
55 #include <stdio.h>
56 #include <string.h>
57 #include <errno.h>
58 #include <sys/types.h>
59 #include <netinet/in.h>
60 #include <arpa/inet.h>
61 
62 #ifdef __linux__
63 #include <linux/rtnetlink.h>
64 #else
65 #define RTPROT_BOOT 3
66 #endif
67 
olsrd_write_cnf(struct olsrd_config * cnf,const char * fname)68 int olsrd_write_cnf(struct olsrd_config *cnf, const char *fname) {
69   FILE *fd;
70   struct autobuf abuf;
71 
72   fd = fopen(fname, "w");
73 
74   if (fd == NULL) {
75     fprintf(stderr, "Could not open file %s for writing\n%s\n", fname, strerror(errno));
76     return -1;
77   }
78 
79   printf("Writing config to file \"%s\".... ", fname);
80   abuf_init(&abuf, AUTOBUFCHUNK);
81   olsrd_write_cnf_autobuf(&abuf, cnf);
82   if (fwrite(abuf.buf, abuf.len, 1, fd) < (size_t)abuf.len) {
83     fprintf(stderr, "Error, could not write the complete config file.\n");
84   }
85   abuf_free(&abuf);
86   fclose(fd);
87 
88   printf("DONE\n");
89 
90   return 1;
91 }
92 
93 static int
94 if_appendf(struct autobuf *autobuf, bool comments, const char *fmt, ...)  __attribute__ ((format(printf, 3, 4)));
95 
96 static int
if_appendf(struct autobuf * autobuf,bool comments,const char * fmt,...)97 if_appendf(struct autobuf *autobuf, bool comments, const char *fmt, ...)
98 {
99   int rv;
100   va_list ap;
101   char *first;
102 
103   if (!comments) {
104     va_start(ap, fmt);
105     first = va_arg(ap, char*);
106     va_end(ap);
107     if (*first) {
108       return 0;
109     }
110   }
111 
112   va_start(ap, fmt);
113   rv = abuf_vappendf(autobuf, fmt, ap);
114   va_end(ap);
115   return rv;
116 }
117 
olsrd_write_hna_autobuf(int ip_version,struct ip_prefix_list * hna,struct autobuf * out,struct olsrd_config * cnf)118 static void olsrd_write_hna_autobuf(int ip_version, struct ip_prefix_list *hna, struct autobuf *out, struct olsrd_config *cnf) {
119   struct ip_prefix_list *hna1 = (cnf->ip_version == ip_version) ? hna : NULL;
120 
121   abuf_appendf(out, "Hna%u\n"
122     "{\n",
123     ip_version == AF_INET ? 4 : 6);
124 
125   if (!hna1) {
126     if (ip_version == AF_INET)
127       abuf_puts(out,
128           "# Internet gateway\n"
129           "# 0.0.0.0   0.0.0.0\n"
130           "# specific small networks reachable through this node\n"
131           "# 15.15.0.0 255.255.255.0\n");
132     else
133       abuf_puts(out,
134           "# Internet gateway\n"
135           "#   0::                     0\n"
136           "# specific small networks reachable through this node\n"
137           "#   fec0:2200:106:0:0:0:0:0 48\n");
138   } else
139     while (hna1) {
140       struct ipaddr_str strbuf;
141       abuf_appendf(out, "    %s\n", olsr_ip_prefix_to_string(&hna1->net));
142       hna1 = hna1->next;
143     }
144   abuf_appendf(out, "}\n");
145 }
146 
olsrd_write_if_autobuf(struct autobuf * out,struct olsrd_config * cnf,struct if_config_options * cnfi,bool comments)147 static void olsrd_write_if_autobuf(struct autobuf *out, struct olsrd_config *cnf, struct if_config_options *cnfi, bool comments) {
148   struct ipaddr_str ipbuf;
149   struct olsr_lq_mult *mult;
150 
151   abuf_puts(out, "{\n");
152   if (comments) abuf_appendf(out,
153     "    # Interface Mode is used to prevent unnecessary\n"
154     "    # packet forwarding on switched ethernet interfaces\n"
155     "    # valid Modes are \"mesh\" and \"ether\"\n"
156     "    # (default is \"%s\")\n"
157     "\n", OLSR_IF_MODE[DEF_IF_MODE]);
158   if_appendf(out, comments, "    %sMode \"%s\"\n",
159       cnfi->mode == DEF_IF_MODE ? "# " : "",
160       OLSR_IF_MODE[cnfi->mode]);
161   if (comments) abuf_puts(out,
162     "\n"
163     "    # IPv4 broadcast address for outgoing OLSR packets.\n"
164     "    # One useful example would be 255.255.255.255\n"
165     "    # The second useful value would be to\n"
166     "    # specify the peer address of an ptp-tunnel.\n"
167     "    # another name of this parameter is \"IPv4Multicast\"\n"
168     "    # (default is 0.0.0.0, which triggers the usage of the\n"
169     "    # interface broadcast IP)\n"
170     "\n");
171   if_appendf(out, comments, "    %sIp4Broadcast      %s\n",
172       cnfi->ipv4_multicast.v4.s_addr == 0 ? "# " : "",
173       inet_ntop(AF_INET, &cnfi->ipv4_multicast, ipbuf.buf, sizeof(ipbuf)));
174   if (comments) abuf_appendf(out,
175     "\n"
176     "    # IPv6 multicast address\n"
177     "    # (default is %s, the manet-router linklocal multicast)\n"
178     "\n", inet_ntop(AF_INET6, &ipv6_def_multicast, ipbuf.buf, sizeof(ipbuf)));
179   if_appendf(out, comments, "    %sIPv6Multicast %s\n",
180       memcmp(&cnfi->ipv6_multicast, &ipv6_def_multicast, sizeof(ipv6_def_multicast)) == 0 ? "# " : "",
181       inet_ntop(AF_INET6, &cnfi->ipv6_multicast, ipbuf.buf, sizeof(ipbuf)));
182   if (comments) abuf_puts(out,
183     "\n"
184     "    # IPv4 src address for outgoing OLSR packages\n"
185     "    # (default is 0.0.0.0, which triggers usage of the interface IP)\n"
186     "\n");
187   if_appendf(out, comments, "    %sIPv4Src %s\n",
188       cnfi->ipv4_src.v4.s_addr == 0 ? "# " : "",
189       inet_ntop(AF_INET, &cnfi->ipv4_src, ipbuf.buf, sizeof(ipbuf)));
190   if (comments) abuf_puts(out,
191     "\n"
192     "    # IPv6 src prefix. OLSRd will choose one of the interface IPs\n"
193     "    # which matches the prefix of this parameter.\n"
194     "    # (default is 0::/0, which triggers the usage\n"
195     "    # of a not-linklocal interface IP)\n"
196     "\n");
197   {
198     int saved = cnf->ip_version;
199     cnf->ip_version = AF_INET6;
200     if_appendf(out, comments, "    %sIPv6Src %s\n",
201       cnfi->ipv6_src.prefix_len == 0 ? "# " : "",
202           olsr_ip_prefix_to_string(&cnfi->ipv6_src));
203     cnf->ip_version = saved;
204   }
205   if (comments) abuf_appendf(out,
206     "\n"
207     "    # Emission intervals in seconds.\n"
208     "    # If not defined, Freifunk network defaults are used.\n"
209     "    # (defaults: Hello = %.1f/%.1f,  TC  = %.1f/%.1f,\n"
210     "    #            MID   = %.1f/%.1f, HNA = %.1f/%.1f)\n"
211     "\n",
212     (double)HELLO_INTERVAL, (double)NEIGHB_HOLD_TIME,
213     (double)TC_INTERVAL,    (double)TOP_HOLD_TIME,
214     (double)MID_INTERVAL,   (double)MID_HOLD_TIME,
215     (double)HNA_INTERVAL,   (double)HNA_HOLD_TIME
216     );
217   if_appendf(out, comments, "    %sHelloInterval       %3.1f\n",
218       cnfi->hello_params.emission_interval == HELLO_INTERVAL ? "# " : "",
219       (double)cnfi->hello_params.emission_interval);
220   if_appendf(out, comments, "    %sHelloValidityTime   %3.1f\n",
221       cnfi->hello_params.validity_time == NEIGHB_HOLD_TIME ? "# " : "",
222       (double)cnfi->hello_params.validity_time);
223   if_appendf(out, comments, "    %sTcInterval          %3.1f\n",
224       cnfi->tc_params.emission_interval == TC_INTERVAL ? "# " : "",
225       (double)cnfi->tc_params.emission_interval);
226   if_appendf(out, comments, "    %sTcValidityTime      %3.1f\n",
227       cnfi->tc_params.validity_time == TOP_HOLD_TIME ? "# " : "",
228       (double)cnfi->tc_params.validity_time);
229   if_appendf(out, comments, "    %sMidInterval         %3.1f\n",
230       cnfi->mid_params.emission_interval == MID_INTERVAL ? "# " : "",
231       (double)cnfi->mid_params.emission_interval);
232   if_appendf(out, comments, "    %sMidValidityTime     %3.1f\n",
233       cnfi->mid_params.validity_time == MID_HOLD_TIME ? "# " : "",
234       (double)cnfi->mid_params.validity_time);
235   if_appendf(out, comments, "    %sHnaInterval         %3.1f\n",
236       cnfi->hna_params.emission_interval == HNA_INTERVAL ? "# " : "",
237       (double)cnfi->hna_params.emission_interval);
238   if_appendf(out, comments, "    %sHnaValidityTime     %3.1f\n",
239       cnfi->hna_params.validity_time == HNA_HOLD_TIME ? "# " : "",
240       (double)cnfi->hna_params.validity_time);
241   if (comments) abuf_puts(out,
242     "\n"
243     "    # When multiple links exist between hosts\n"
244     "    # the weight of interface is used to determine\n"
245     "    # the link to use. Normally the weight is\n"
246     "    # automatically calculated by olsrd based\n"
247     "    # on the characteristics of the interface,\n"
248     "    # but here you can specify a fixed value.\n"
249     "    # Olsrd will choose links with the lowest value.\n"
250     "    # Note:\n"
251     "    # Interface weight is used only when LinkQualityLevel is set to 0.\n"
252     "    # For any other value of LinkQualityLevel, the interface ETX\n"
253     "    # value is used instead.\n");
254   if_appendf(out, comments, "    %sWeight %d\n",
255       !cnfi->weight.fixed ? "# " : "",
256       cnfi->weight.value);
257   if (comments) abuf_puts(out,
258     "\n"
259     "    # If a certain route should be preferred\n"
260     "    # or ignored by the mesh, the Link Quality\n"
261     "    # value of a node can be multiplied with a factor\n"
262     "    # entered here. In the example the route\n"
263     "    # using 192.168.0.1 would rather be ignored.\n"
264     "    # A multiplier of 0.5 will result in a small\n"
265     "    # (bad) LinkQuality value and a high (bad)\n"
266     "    # ETX value.\n"
267     "    # Note:\n"
268     "    # Link quality multiplier is used only when\n"
269     "    # LinkQualityLevel is greater than 0.\n"
270     "\n");
271   mult = cnfi->lq_mult;
272 
273   if (mult == NULL) {
274     if (comments) {
275       abuf_puts(out, "    # example 1: reduce LQ to 192.168.0.1 by half\n");
276       abuf_puts(out, "    # LinkQualityMult 192.168.0.1 0.5\n");
277       abuf_puts(out, "\n");
278       abuf_puts(out, "    # example 2: reduce LQ to all nodes on this interface by 20%\n");
279       abuf_puts(out, "    # LinkQualityMult default 0.8\n");
280     }
281   } else {
282     while (mult != NULL) {
283       if_appendf(out, comments, "    LinkQualityMult    %s %0.2f\n",
284           olsr_ip_to_string(&ipbuf, &mult->addr),
285           (double)((float)(mult->value) / 65536.0f));
286       mult = mult->next;
287     }
288   }
289   abuf_puts(out, "}\n");
290 }
291 
292 static struct autobuf config_cache;
293 
olsrd_cfgfile_init(void)294 void olsrd_cfgfile_init(void) {
295   abuf_init(&config_cache, AUTOBUFCHUNK);
296 }
297 
olsrd_cfgfile_cleanup(void)298 void olsrd_cfgfile_cleanup(void) {
299   abuf_free(&config_cache);
300 }
301 
olsrd_write_cnf_autobuf(struct autobuf * out,struct olsrd_config * cnf)302 void olsrd_write_cnf_autobuf(struct autobuf *out, struct olsrd_config *cnf) {
303   if (!config_cache.len) {
304     olsrd_write_cnf_autobuf_uncached(&config_cache, cnf);
305   }
306 
307   abuf_concat(out, &config_cache);
308 }
309 
olsrd_write_cnf_autobuf_uncached(struct autobuf * out,struct olsrd_config * cnf)310 void olsrd_write_cnf_autobuf_uncached(struct autobuf *out, struct olsrd_config *cnf) {
311   struct ip_prefix_list *hna = cnf->hna_entries;
312   struct olsr_if *interf = cnf->interfaces;
313   struct plugin_entry *plugins = cnf->plugins;
314   struct plugin_param *pl_param;
315   struct ip_prefix_list *ipc_nets = cnf->ipc_nets;
316 
317   struct ipaddr_str ipbuf;
318   bool first;
319 
320   abuf_appendf(out, "#\n"
321       "# Configuration file for %s\n"
322       "# automatically generated by olsrd-cnf parser v. %s\n"
323       "#\n"
324       "\n",
325       olsrd_version, PARSER_VERSION);
326   abuf_appendf(out,
327     "# OLSR.org routing daemon config file\n"
328     "# This file contains ALL available options and explanations about them\n"
329     "#\n"
330     "# Lines starting with a # are discarded\n"
331     "#\n"
332     "\n"
333     "#### ATTENTION for IPv6 users ####\n"
334     "# Because of limitations in the parser IPv6 addresses must NOT\n"
335     "# begin with a \":\", so please add a \"0\" as a prefix.\n"
336     "\n"
337     "###########################\n"
338     "### Basic configuration ###\n"
339     "###########################\n"
340     "# keep this settings at the beginning of your first configuration file\n"
341     "\n"
342     "# Debug level (0-9)\n"
343     "# If set to 0 the daemon runs in the background, unless \"NoFork\" is set to true\n"
344     "# (default is %u)\n"
345     "\n", DEF_DEBUGLVL);
346   abuf_appendf(out, "%sDebugLevel  %d\n",
347       cnf->debug_level == DEF_DEBUGLVL ? "# " : "",
348       cnf->debug_level);
349   abuf_appendf(out,
350     "\n"
351     "# IP version to use (4 or 6)\n"
352     "# (default is %u)\n"
353     "\n", (DEF_IP_VERSION == AF_INET) ? 4 : 6);
354   abuf_appendf(out, "%sIpVersion %d\n",
355       cnf->ip_version == DEF_IP_VERSION ? "# " : "",
356       cnf->ip_version == AF_INET ? 4 : 6);
357   abuf_appendf(out,
358     "\n"
359     "#################################\n"
360     "### OLSRd agent configuration ###\n"
361     "#################################\n"
362     "# this parameters control the settings of the routing agent which are not\n"
363     "# related to the OLSR protocol and it's extensions\n"
364     "\n"
365     "# Clear the screen each time the internal state changes\n"
366     "# (default is %s)\n"
367     "\n", DEF_CLEAR_SCREEN ? "yes" : "no");
368   abuf_appendf(out, "%sClearScreen     %s\n",
369       cnf->clear_screen == DEF_CLEAR_SCREEN ? "# " : "",
370       cnf->clear_screen ? "yes" : "no");
371   abuf_appendf(out,
372     "\n"
373     "# Should olsrd keep on running even if there are\n"
374     "# no interfaces available? This is a good idea\n"
375     "# for a PCMCIA/USB hotswap environment.\n"
376     "# (default is %s)\n"
377     "\n", DEF_ALLOW_NO_INTS ? "yes" : "no");
378   abuf_appendf(out, "%sAllowNoInt  %s\n",
379       cnf->allow_no_interfaces == DEF_ALLOW_NO_INTS ? "# " : "",
380       cnf->allow_no_interfaces ? "yes" : "no");
381   abuf_puts(out,
382     "\n"
383     "# LockFile\n"
384     "# The lockfile is used to prevent multiple OLSR instances running at the same\n"
385     "# time.\n"
386     "# (Linux/BSD default is \"/var/run/olsrd-ipv(4/6).lock\")\n"
387     "# (Win32     default is \"[configfile]-ipv(4/6).lock\")\n"
388     "\n");
389   {
390     char * lockfile_default = olsrd_get_default_lockfile(cnf);
391     abuf_appendf(out, "%sLockFile \"%s\"\n",
392         !strcmp(cnf->lock_file, lockfile_default) ? "# " : "",
393         cnf->lock_file);
394     free(lockfile_default);
395   }
396   abuf_appendf(out,
397     "\n"
398     "# Polling rate for OLSR sockets in seconds (float).\n"
399     "# (default is %.2f)\n"
400     "\n", (double)DEF_POLLRATE);
401   abuf_appendf(out, "%sPollrate  %.2f\n",
402       cnf->pollrate == (float)DEF_POLLRATE ? "# " : "",
403       (double)cnf->pollrate);
404   abuf_appendf(out,
405     "\n"
406     "# Interval to poll network interfaces for configuration changes (in seconds).\n"
407     "# Linux systems can detect interface statechange via netlink sockets.\n"
408     "# (default is %.1f)\n"
409     "\n", (double)DEF_NICCHGPOLLRT);
410   abuf_appendf(out, "%sNicChgsPollInt  %.1f\n",
411       cnf->nic_chgs_pollrate == (float)DEF_NICCHGPOLLRT ? "# " : "",
412       (double)cnf->nic_chgs_pollrate);
413   abuf_appendf(out,
414     "\n"
415     "# TOS(type of service) value for the IP header of control traffic.\n"
416     "# (default is %u)\n"
417     "\n", DEF_TOS);
418   abuf_appendf(out, "%sTosValue %u\n",
419       cnf->tos == DEF_TOS ? "# " : "",
420       cnf->tos);
421   abuf_appendf(out,
422     "\n"
423     "# FIBMetric controls the metric value of the host-routes OLSRd sets.\n"
424     "# - \"flat\" means that the metric value is always 2 (or as configured\n"
425     "#   with FIBMetricDefault). This is the preferred value because it helps\n"
426     "#   the linux kernel routing to clean up older routes\n"
427     "# - \"correct\" use the hopcount as the metric value.\n"
428     "# - \"approx\" use the hopcount as the metric value too, but does only update the\n"
429     "#   hopcount if the nexthop changes too\n"
430     "# (default is \"%s\")\n"
431     "\n", FIB_METRIC_TXT[DEF_FIB_METRIC]);
432   abuf_appendf(out, "%sFIBMetric \"%s\"\n",
433       cnf->fib_metric == DEF_FIB_METRIC ? "# " : "",
434       FIB_METRIC_TXT[cnf->fib_metric]);
435   abuf_appendf(out,
436     "\n"
437     "# Default FIB metric.\n"
438     "# The kernel FIB does not need to know the metric of a route.\n"
439     "# This saves us from enqueuing/dequeueing hopcount only changes.\n"
440     "# (default is %u)\n"
441     "\n", DEF_FIB_METRIC_DEFAULT);
442   abuf_appendf(out, "%sFIBMetricDefault %u\n",
443       cnf->fib_metric_default == DEF_FIB_METRIC_DEFAULT? "# " : "",
444       cnf->fib_metric_default);
445   abuf_appendf(out,
446     "\n"
447     "#######################################\n"
448     "### Linux specific OLSRd extensions ###\n"
449     "#######################################\n"
450     "# these parameters are only working on linux at the moment, but might become\n"
451     "# useful on BSD in the future\n"
452     "\n"
453     "# SrcIpRoutes tells OLSRd to set the Src flag of host routes to the originator-ip\n"
454     "# of the node. In addition to this an additional localhost device is created\n"
455     "# to make sure the returning traffic can be received.\n"
456     "# (default is \"%s\")\n"
457     "\n", DEF_USE_SRCIP_ROUTES ? "yes" : "no");
458   abuf_appendf(out, "%sSrcIpRoutes %s\n",
459       cnf->use_src_ip_routes == DEF_USE_SRCIP_ROUTES ? "# " : "",
460       cnf->use_src_ip_routes ? "yes" : "no");
461   abuf_appendf(out,
462     "\n"
463     "# Specify the proto tag to be used for routes olsr inserts into kernel\n"
464     "# currently only implemented for linux\n"
465     "# valid values under linux are 1 .. 254\n"
466     "# 1 gets remapped by olsrd to 0 UNSPECIFIED (1 is reserved for ICMP redirects)\n"
467     "# 2 KERNEL routes (not very wise to use)\n"
468     "# 3 BOOT (should in fact not be used by routing daemons)\n"
469     "# 4 STATIC\n"
470     "# 8 .. 15 various routing daemons (gated, zebra, bird, & co)\n"
471     "# (default is %u which gets replaced by an OS-specific default value;\n"
472     "# %u (BOOT) under linux (for backward compatibility)\n"
473     "\n", DEF_RTPROTO, RTPROT_BOOT);
474   {
475     int expected = DEF_RTPROTO;
476 #ifdef __linux__
477     expected = RTPROT_BOOT;
478 #endif
479     abuf_appendf(out, "%sRtProto %u\n",
480         cnf->rt_proto == expected ? "# " : "",
481         cnf->rt_proto == expected ? DEF_RTPROTO : cnf->rt_proto);
482   }
483   abuf_appendf(out,
484     "\n"
485     "# Specifies the routing Table olsr uses\n"
486     "# RtTable is for host routes, RtTableDefault for the route to the default\n"
487     "# internet gateway (2 in case of IPv6+NIIT) and RtTableTunnel is for\n"
488     "# routes to the ipip tunnels, valid values are 1 to 254\n"
489     "# There is a special parameter \"auto\" (choose default below)\n"
490     "# (with    smartgw: default is %u/%u/%u)\n"
491     "# (without smartgw: default is %u/%u/%u, linux main table)\n"
492     "\n",
493     DEF_SGW_RT_TABLE_NR, DEF_SGW_RT_TABLE_DEFAULT_NR, DEF_SGW_RT_TABLE_TUNNEL_NR,
494     DEF_RT_TABLE_NR, DEF_RT_TABLE_DEFAULT_NR, DEF_RT_TABLE_TUNNEL_NR);
495   if (!cnf->smart_gw_active) {
496     if (cnf->rt_table == DEF_RT_TABLE_NR)
497       abuf_appendf(out, "%sRtTable        %s\n",
498           "# ",
499           "auto");
500     else
501       abuf_appendf(out, "%sRtTable        %u\n",
502           "",
503           cnf->rt_table);
504     if (cnf->rt_table_default == DEF_RT_TABLE_DEFAULT_NR)
505       abuf_appendf(out, "%sRtTableDefault %s\n",
506           "# ",
507           "auto");
508     else
509       abuf_appendf(out, "%sRtTableDefault %u\n",
510           "",
511           cnf->rt_table_default);
512     if (cnf->rt_table_tunnel == DEF_RT_TABLE_TUNNEL_NR)
513       abuf_appendf(out, "%sRtTableTunnel  %s\n",
514           "# ",
515           "auto");
516     else
517       abuf_appendf(out, "%sRtTableTunnel  %u\n",
518           "",
519           cnf->rt_table_tunnel);
520   } else {
521     if (cnf->rt_table == DEF_SGW_RT_TABLE_NR)
522       abuf_appendf(out, "%sRtTable        %s\n",
523           "# ",
524           "auto");
525     else
526       abuf_appendf(out, "%sRtTable        %u\n",
527           "",
528           cnf->rt_table);
529     if (cnf->rt_table_default == DEF_SGW_RT_TABLE_DEFAULT_NR)
530       abuf_appendf(out, "%sRtTableDefault %s\n",
531           "# ",
532           "auto");
533     else
534       abuf_appendf(out, "%sRtTableDefault %u\n",
535           "",
536           cnf->rt_table_default);
537     if (cnf->rt_table_tunnel == DEF_SGW_RT_TABLE_TUNNEL_NR)
538       abuf_appendf(out, "%sRtTableTunnel  %s\n",
539           "# ",
540           "auto");
541     else
542       abuf_appendf(out, "%sRtTableTunnel  %u\n",
543           "",
544           cnf->rt_table_tunnel);
545   }
546   abuf_appendf(out,
547     "\n"
548     "# Specifies the policy rule priorities for the three routing tables and\n"
549     "# a special rule for smartgateway routing (see README-Olsr-Extensions)\n"
550     "# Priorities can only be set if three different routing tables are set.\n"
551     "# if set the values must obey to condition\n"
552     "# RtTablePriority less than RtTableDefaultOlsrPriority\n"
553     "# less than RtTableTunnelPriority less than RtTableDefaultPriority\n"
554     "# There are two special parameters, \"auto\" (choose fitting to SmartGW\n"
555     "# mode) and \"none\" (do not set policy rule)\n");
556 
557   abuf_puts(out, "# (with    smartgw: default is ");
558   if (cnf->rt_table_pri > 0)
559     abuf_appendf(out,
560       "%5d/",
561       DEF_SGW_RT_TABLE_PRI);
562   else
563     abuf_appendf(out,
564       "%5s/",
565       "none");
566   abuf_appendf(out,
567     "%-5u/%-5u/%-5u)\n",
568     DEF_SGW_RT_TABLE_PRI_BASE + DEF_SGW_RT_TABLE_DEFAULTOLSR_PRI_ADDER,
569     DEF_SGW_RT_TABLE_PRI_BASE + DEF_SGW_RT_TABLE_DEFAULTOLSR_PRI_ADDER + DEF_SGW_RT_TABLE_TUNNEL_PRI_ADDER,
570     DEF_SGW_RT_TABLE_PRI_BASE + DEF_SGW_RT_TABLE_DEFAULTOLSR_PRI_ADDER + DEF_SGW_RT_TABLE_TUNNEL_PRI_ADDER + DEF_SGW_RT_TABLE_DEFAULT_PRI_ADDER);
571 
572   abuf_puts(out, "# (without smartgw: default is ");
573   if (cnf->rt_table_pri == DEF_RT_AUTO || cnf->rt_table_pri == DEF_RT_TABLE_PRI)
574     abuf_appendf(out,
575       "%5s/",
576       "auto");
577   else
578     abuf_appendf(out,
579       "%5d/",
580       DEF_RT_TABLE_PRI);
581   if (cnf->rt_table_defaultolsr_pri == DEF_RT_AUTO || cnf->rt_table_defaultolsr_pri == DEF_RT_TABLE_DEFAULTOLSR_PRI)
582     abuf_appendf(out,
583       "%-5s/",
584       "auto");
585   else
586     abuf_appendf(out,
587       "%-5d/",
588       DEF_RT_TABLE_DEFAULTOLSR_PRI);
589   if (cnf->rt_table_tunnel_pri == DEF_RT_AUTO || cnf->rt_table_tunnel_pri == DEF_RT_TABLE_TUNNEL_PRI)
590     abuf_appendf(out,
591       "%-5s/",
592       "auto");
593   else
594     abuf_appendf(out,
595       "%-5d/",
596       DEF_RT_TABLE_TUNNEL_PRI);
597   if (cnf->rt_table_default_pri == DEF_RT_AUTO || cnf->rt_table_default_pri == DEF_RT_TABLE_DEFAULT_PRI)
598     abuf_appendf(out,
599       "%-5s",
600       "auto");
601   else
602     abuf_appendf(out,
603       "%-5d",
604       DEF_RT_TABLE_DEFAULT_PRI);
605   abuf_puts(out, ")\n");
606 
607   abuf_puts(out, "\n");
608 
609   if (!cnf->smart_gw_active) {
610     if (cnf->rt_table_pri == DEF_RT_AUTO || cnf->rt_table_pri == DEF_RT_TABLE_PRI)
611       abuf_appendf(out, "# RtTablePriority            %s\n",
612           "auto");
613     else
614       abuf_appendf(out, "RtTablePriority              %u\n",
615           cnf->rt_table_pri);
616 
617     if (cnf->rt_table_defaultolsr_pri == DEF_RT_AUTO || cnf->rt_table_defaultolsr_pri == DEF_RT_TABLE_DEFAULTOLSR_PRI)
618       abuf_appendf(out, "# RtTableDefaultOlsrPriority %s\n",
619           "auto");
620     else
621       abuf_appendf(out, "RtTableDefaultOlsrPriority   %u\n",
622           cnf->rt_table_defaultolsr_pri);
623 
624     if (cnf->rt_table_tunnel_pri == DEF_RT_AUTO || cnf->rt_table_tunnel_pri == DEF_RT_TABLE_TUNNEL_PRI)
625       abuf_appendf(out, "# RtTableTunnelPriority      %s\n",
626           "auto");
627     else
628       abuf_appendf(out, "RtTableTunnelPriority        %u\n",
629           cnf->rt_table_tunnel_pri);
630 
631     if (cnf->rt_table_default_pri == DEF_RT_AUTO || cnf->rt_table_default_pri == DEF_RT_TABLE_DEFAULT_PRI)
632       abuf_appendf(out, "# RtTableDefaultPriority     %s\n",
633           "auto");
634     else
635       abuf_appendf(out, "RtTableDefaultPriority       %u\n",
636           cnf->rt_table_default_pri);
637   } else {
638     if (cnf->rt_table_pri > 0)
639       abuf_appendf(out, "RtTablePriority              %u\n",
640           cnf->rt_table_pri);
641     else
642       abuf_appendf(out, "# RtTablePriority            %s\n",
643           "none");
644 
645     abuf_appendf(out, "%sRtTableDefaultOlsrPriority %u\n",
646         cnf->rt_table_defaultolsr_pri == (DEF_SGW_RT_TABLE_PRI_BASE + DEF_SGW_RT_TABLE_DEFAULTOLSR_PRI_ADDER) ? "# " : "",
647         cnf->rt_table_defaultolsr_pri);
648 
649     abuf_appendf(out, "%sRtTableTunnelPriority      %u\n",
650         cnf->rt_table_tunnel_pri == (DEF_SGW_RT_TABLE_PRI_BASE + DEF_SGW_RT_TABLE_DEFAULTOLSR_PRI_ADDER + DEF_SGW_RT_TABLE_TUNNEL_PRI_ADDER) ? "# " : "",
651         cnf->rt_table_tunnel_pri);
652 
653     abuf_appendf(out, "%sRtTableDefaultPriority     %u\n",
654         cnf->rt_table_default_pri == (DEF_SGW_RT_TABLE_PRI_BASE + DEF_SGW_RT_TABLE_DEFAULTOLSR_PRI_ADDER + DEF_SGW_RT_TABLE_TUNNEL_PRI_ADDER + DEF_SGW_RT_TABLE_DEFAULT_PRI_ADDER) ? "# " : "",
655         cnf->rt_table_default_pri);
656   }
657   {
658     bool expected = cnf->ip_version == AF_INET ? false : DEF_USE_NIIT;
659     abuf_appendf(out,
660       "\n"
661       "# Activates (in IPv6 mode) the automatic use of NIIT\n"
662       "# (see README-Olsr-Extensions)\n"
663       "# (default is \"%s\" in IPv4 mode, \"%s\" in IPv6 mode)\n"
664       "\n", expected ? "yes" : "no", DEF_USE_NIIT ? "yes" : "no");
665     abuf_appendf(out, "%sUseNiit %s\n",
666         cnf->use_niit == expected ? "# " : "",
667         cnf->use_niit ? "yes" : "no");
668   }
669   abuf_appendf(out,
670     "\n"
671     "# Activates the smartgateway ipip tunnel feature.\n"
672     "# See README-Olsr-Extensions for a description of smartgateways.\n"
673     "# (default is \"%s\")\n"
674     "\n", DEF_SMART_GW ? "yes" : "no");
675   abuf_appendf(out, "%sSmartGateway %s\n",
676       cnf->smart_gw_active == DEF_SMART_GW ? "# " : "",
677       cnf->smart_gw_active ? "yes" : "no");
678   abuf_appendf(out,
679     "\n"
680     "# Signals that the server tunnel must always be removed on shutdown,\n"
681     "# irrespective of the interface up/down state during startup.\n"
682     "# (default is \"%s\")\n"
683     "\n", DEF_SMART_GW_ALWAYS_REMOVE_SERVER_TUNNEL ? "yes" : "no");
684   abuf_appendf(out, "%sSmartGatewayAlwaysRemoveServerTunnel %s\n",
685       cnf->smart_gw_always_remove_server_tunnel == DEF_SMART_GW_ALWAYS_REMOVE_SERVER_TUNNEL ? "# " : "",
686       cnf->smart_gw_always_remove_server_tunnel ? "yes" : "no");
687   abuf_appendf(out,
688     "\n"
689     "# Determines the maximum number of gateways that can be in use at any given\n"
690     "# time. This setting is used to mitigate the effects of breaking connections\n"
691     "# (due to the selection of a new gateway) on a dynamic network.\n"
692     "# (default is %u)\n"
693     "\n", DEF_GW_USE_COUNT);
694   abuf_appendf(out, "%sSmartGatewayUseCount %d\n",
695       cnf->smart_gw_use_count == DEF_GW_USE_COUNT ? "# " : "",
696       cnf->smart_gw_use_count);
697   abuf_appendf(out,
698     "\n"
699     "# Determines the take-down percentage for a non-current smart gateway tunnel.\n"
700     "# If the cost of the current smart gateway tunnel is less than this percentage\n"
701     "# of the cost of the non-current smart gateway tunnel, then the non-current smart\n"
702     "# gateway tunnel is taken down because it is then presumed to be 'too expensive'.\n"
703     "# This setting is only relevant when SmartGatewayUseCount is larger than 1;\n"
704     "# a value of 0 will result in the tunnels not being taken down proactively.\n"
705     "# (default is %u)\n"
706     "\n", DEF_GW_TAKEDOWN_PERCENTAGE);
707   abuf_appendf(out, "%sSmartGatewayTakeDownPercentage %d\n",
708       cnf->smart_gw_takedown_percentage == DEF_GW_TAKEDOWN_PERCENTAGE ? "# " : "",
709       cnf->smart_gw_takedown_percentage);
710   abuf_puts(out,
711     "\n"
712     "# Determines the olsrd instance id, which is needed for proper cleanup\n"
713     "# of multi-gateway iptables and ip rules when running multiple olsrd\n"
714     "# instances on a node. This setting MUST be configured when the\n"
715     "# multi-gateway mode is enabled and must be unique between the olsrd\n"
716     "# instances running on the node. It may not contain whitespace and may\n"
717     "# not be empty.\n"
718     "# (default is <not set>)\n"
719     "\n");
720   abuf_appendf(out, "%sSmartGatewayInstanceId %s%s%s\n",
721       !cnf->smart_gw_instance_id ? "# " : "",
722       !cnf->smart_gw_instance_id ? "" : "\"",
723       !cnf->smart_gw_instance_id ? "<not set>" : cnf->smart_gw_instance_id,
724       !cnf->smart_gw_instance_id ? "" : "\"");
725   abuf_puts(out,
726     "\n"
727     "# Determines the policy routing script that is executed during startup and\n"
728     "# shutdown of olsrd. The script is only executed when SmartGatewayUseCount\n"
729     "# is set to a value larger than 1. The script must setup policy routing\n"
730     "# rules such that multi-gateway mode works. A sample script is included.\n"
731     "# (default is <not set>)\n"
732     "\n");
733   abuf_appendf(out, "%sSmartGatewayPolicyRoutingScript %s%s%s\n",
734       !cnf->smart_gw_policyrouting_script ? "# " : "",
735       !cnf->smart_gw_policyrouting_script ? "" : "\"",
736       !cnf->smart_gw_policyrouting_script ? "<not set>" : cnf->smart_gw_policyrouting_script,
737       !cnf->smart_gw_policyrouting_script ? "" : "\"");
738   abuf_puts(out,
739     "\n"
740     "# Determines the egress interfaces that are part of the multi-gateway setup and\n"
741     "# therefore only relevant when SmartGatewayUseCount is larger than 1 (in which\n"
742     "# case it must be explicitly set).\n"
743     "# (default is not set)\n"
744     "\n");
745   abuf_appendf(out, "%sSmartGatewayEgressInterfaces",
746       !cnf->smart_gw_egress_interfaces ? "# " : "");
747   {
748     struct sgw_egress_if * sgwegressif = olsr_cnf->smart_gw_egress_interfaces;
749     if (!sgwegressif)
750       abuf_puts(out, " \"\"");
751     else
752       while (sgwegressif) {
753         abuf_appendf(out, " \"%s\"", sgwegressif->name);
754         sgwegressif = sgwegressif->next;
755       }
756     abuf_puts(out, "\n");
757   }
758   abuf_appendf(out,
759     "\n"
760     "# SmartGatewayEgressFile declares the file that contains the bandwidth\n"
761     "# parameters of the egress interfaces declared by SmartGatewayEgressInterfaces.\n"
762     "# Every line in the file declares bandwidth parameters of an egress interface,\n"
763     "# with the format:\n"
764     "#   # this is a comment\n"
765     "#   interface=upstream,downstream,pathcost,network/prefix,gateway\n"
766     "# Only the upstream and downstream fields are mandatory, the other fields are\n"
767     "# optional. An empty field signifies that its default should be used.\n"
768     "# The field defaults are:\n"
769     "#   upstream           = 0 (Kbps)\n"
770     "#   downstream         = 0 (Kbps)\n"
771     "#   pathcost           = 0 (dimensionless, 1024 is equivalent to 1 hop)\n"
772     "#   network/prefix     = no default / not set\n"
773     "#                        - network is an IP address\n"
774     "#                        - prefix is a number in the range [0, 24] for IPv4\n"
775     "#                          and in the range [0, 128] for IPv6\n"
776     "#   gateway            = no default / not set (IP address)\n"
777     "# (default is %s)\n"
778     "\n", DEF_GW_EGRESS_FILE);
779   {
780     bool def = !cnf->smart_gw_egress_file || !strcmp(cnf->smart_gw_egress_file, DEF_GW_EGRESS_FILE);
781     abuf_appendf(out, "%sSmartGatewayEgressFile \"%s\"\n",
782       def ? "# " : "", def ? DEF_GW_EGRESS_FILE : cnf->smart_gw_egress_file);
783   }
784   abuf_appendf(out,
785     "\n"
786     "# Determines the period (in milliseconds) on which the SmartGatewayEgressFile\n"
787     "# is checked for changes and processed if changed.\n"
788     "# (default is %u)\n"
789     "\n", DEF_GW_EGRESS_FILE_PERIOD);
790   abuf_appendf(out, "%sSmartGatewayEgressFilePeriod %u\n",
791       cnf->smart_gw_egress_file_period == DEF_GW_EGRESS_FILE_PERIOD ? "# " : "",
792       cnf->smart_gw_egress_file_period);
793   abuf_appendf(out,
794     "\n"
795     "# Declares the file that is written by olsrd to contain the status of the smart\n"
796     "# gateways and is only relevant when SmartGatewayUseCount is larger than 1.\n"
797     "# (default is %s)\n"
798       "\n", "<not set>");
799     {
800       bool def = !cnf->smart_gw_status_file || !strlen(cnf->smart_gw_status_file);
801       abuf_appendf(out, "%sSmartGatewayStatusFile %s%s%s\n",
802         def ? "# " : "",
803         def ? "" : "\"",
804         def ? "<not set>" : cnf->smart_gw_status_file,
805         def ? "" : "\"");
806     }
807   abuf_appendf(out,
808     "\n"
809     "# Determines the routing tables offset for multi-gateway policy routing tables\n"
810     "# See the policy routing script for an explanation.\n"
811     "# (default is %u)\n"
812     "\n", DEF_GW_OFFSET_TABLES);
813   abuf_appendf(out, "%sSmartGatewayTablesOffset %u\n",
814       cnf->smart_gw_offset_tables == DEF_GW_OFFSET_TABLES ? "# " : "",
815       cnf->smart_gw_offset_tables);
816   abuf_appendf(out,
817     "\n"
818     "# Determines the policy routing rules offset for multi-gateway policy routing\n"
819     "# rules. See the policy routing script for an explanation.\n"
820     "# (default is %u, which indicates that the rules and tables should be aligned and\n"
821     "# puts this value at SmartGatewayTablesOffset - # egress interfaces -\n"
822     "# # olsr interfaces)\n"
823     "\n", DEF_GW_OFFSET_RULES);
824   abuf_appendf(out, "%sSmartGatewayRulesOffset %u\n",
825       cnf->smart_gw_offset_rules == DEF_GW_OFFSET_RULES ? "# " : "",
826       cnf->smart_gw_offset_rules);
827   abuf_appendf(out,
828     "\n"
829     "# Allows the selection of a smartgateway with NAT (only for IPv4)\n"
830     "# (default is \"%s\")\n"
831     "\n", DEF_GW_ALLOW_NAT ? "yes" : "no");
832   abuf_appendf(out, "%sSmartGatewayAllowNAT %s\n",
833       cnf->smart_gw_allow_nat == DEF_GW_ALLOW_NAT ? "# " : "",
834       cnf->smart_gw_allow_nat ? "yes" : "no");
835   abuf_appendf(out,
836     "\n"
837     "# Determines the period (in milliseconds) on which a new smart gateway\n"
838     "# selection is performed.\n"
839     "# (default is %u milliseconds)\n"
840     "\n", DEF_GW_PERIOD);
841   abuf_appendf(out, "%sSmartGatewayPeriod %d\n",
842       cnf->smart_gw_period == DEF_GW_PERIOD ? "# " : "",
843       cnf->smart_gw_period);
844   abuf_appendf(out,
845     "\n"
846     "# Determines the number of times the link state database must be stable\n"
847     "# before a new smart gateway is selected.\n"
848     "# (default is %u)\n"
849     "\n", DEF_GW_STABLE_COUNT);
850   abuf_appendf(out, "%sSmartGatewayStableCount %d\n",
851       cnf->smart_gw_stablecount == DEF_GW_STABLE_COUNT ? "# " : "",
852       cnf->smart_gw_stablecount);
853   abuf_appendf(out,
854     "\n"
855     "# When another gateway than the current one has a cost of less than the cost\n"
856     "# of the current gateway multiplied by SmartGatewayThreshold then the smart\n"
857     "# gateway is switched to the other gateway. The unit is percentage.\n"
858     "# (default is %u)\n"
859     "\n", DEF_GW_THRESH);
860   abuf_appendf(out, "%sSmartGatewayThreshold %d\n",
861       cnf->smart_gw_thresh == DEF_GW_THRESH ? "# " : "",
862       cnf->smart_gw_thresh);
863   abuf_appendf(out,
864     "\n"
865     "# The weighing factor for the gateway uplink bandwidth (exit link, uplink).\n"
866     "# See README-Olsr-Extensions for a description of smart gateways.\n"
867     "# (default is %lu)\n"
868     "\n", (long unsigned int)DEF_GW_WEIGHT_EXITLINK_UP);
869   abuf_appendf(out, "%sSmartGatewayWeightExitLinkUp %d\n",
870       cnf->smart_gw_weight_exitlink_up == DEF_GW_WEIGHT_EXITLINK_UP ? "# " : "",
871       cnf->smart_gw_weight_exitlink_up);
872   abuf_appendf(out,
873     "\n"
874     "# The weighing factor for the gateway downlink bandwidth (exit link, downlink).\n"
875     "# See README-Olsr-Extensions for a description of smart gateways.\n"
876     "# (default is %lu)\n"
877     "\n", (long unsigned int)DEF_GW_WEIGHT_EXITLINK_DOWN);
878   abuf_appendf(out, "%sSmartGatewayWeightExitLinkDown %d\n",
879       cnf->smart_gw_weight_exitlink_down == DEF_GW_WEIGHT_EXITLINK_DOWN ? "# " : "",
880       cnf->smart_gw_weight_exitlink_down);
881   abuf_appendf(out,
882     "\n"
883     "# The weighing factor for the ETX costs.\n"
884     "# See README-Olsr-Extensions for a description of smart gateways.\n"
885     "# (default is %u)\n"
886     "\n", DEF_GW_WEIGHT_ETX);
887   abuf_appendf(out, "%sSmartGatewayWeightEtx %d\n",
888       cnf->smart_gw_weight_etx == DEF_GW_WEIGHT_ETX ? "# " : "",
889       cnf->smart_gw_weight_etx);
890   abuf_appendf(out,
891     "\n"
892     "# The divider for the ETX costs.\n"
893     "# See README-Olsr-Extensions for a description of smart gateways.\n"
894     "# (default is %u)\n"
895     "\n", DEF_GW_DIVIDER_ETX);
896   abuf_appendf(out, "%sSmartGatewayDividerEtx %d\n",
897       cnf->smart_gw_divider_etx == DEF_GW_DIVIDER_ETX ? "# " : "",
898       cnf->smart_gw_divider_etx);
899   abuf_appendf(out,
900       "\n"
901       "# When a node advertises the maximum bandwidth and its ETX\n"
902       "# is below the value of this setting then the resulting gateway\n"
903       "# costs are equal to the ETX, otherwise the normal calculation\n"
904       "# of the gateway costs applies.\n"
905       "# (default is %u)\n"
906       "\n", DEF_GW_MAX_COST_MAX_ETX);
907   abuf_appendf(out, "%sSmartGatewayMaxCostMaxEtx %d\n",
908         cnf->smart_gw_path_max_cost_etx_max == DEF_GW_MAX_COST_MAX_ETX ? "# " : "",
909         cnf->smart_gw_path_max_cost_etx_max);
910   abuf_appendf(out,
911     "\n"
912     "# Defines what kind of Uplink this node will publish as a\n"
913     "# smartgateway. The existence of the uplink is detected by\n"
914     "# a route to 0.0.0.0/0, ::ffff:0:0/96 and/or 2000::/3.\n"
915     "# possible values are \"none\", \"ipv4\", \"ipv6\", \"both\"\n"
916     "# (default is \"%s\")\n"
917     "\n", GW_UPLINK_TXT[DEF_GW_TYPE]);
918   abuf_appendf(out, "%sSmartGatewayUplink \"%s\"\n",
919       cnf->smart_gw_type == DEF_GW_TYPE ? "# " : "",
920       GW_UPLINK_TXT[cnf->smart_gw_type]);
921   abuf_appendf(out,
922     "\n"
923     "# Specifies if the local ipv4 uplink use NAT\n"
924     "# (default is \"%s\")\n"
925     "\n", DEF_GW_UPLINK_NAT ? "yes" : "no");
926   abuf_appendf(out, "%sSmartGatewayUplinkNAT %s\n",
927       cnf->smart_gw_uplink_nat == DEF_GW_UPLINK_NAT ? "# " : "",
928       cnf->smart_gw_uplink_nat ? "yes" : "no");
929   abuf_appendf(out,
930     "\n"
931     "# Specifies the speed of the uplink in kilobit/s.\n"
932     "# First parameter is upstream, second parameter is downstream\n"
933     "# (default is %u/%u)\n"
934     "\n", DEF_UPLINK_SPEED, DEF_DOWNLINK_SPEED);
935   abuf_appendf(out, "%sSmartGatewaySpeed %d %d\n",
936       cnf->smart_gw_uplink == DEF_UPLINK_SPEED && cnf->smart_gw_downlink == DEF_DOWNLINK_SPEED ? "# " : "",
937       cnf->smart_gw_uplink, cnf->smart_gw_downlink);
938   abuf_puts(out,
939     "\n"
940     "# Specifies the EXTERNAL ipv6 prefix of the uplink. A prefix\n"
941     "# length of more than 64 is not allowed.\n"
942     "# Only relevant when running in IPv6 mode.\n"
943     "# (default is 0::/0)\n"
944     "\n");
945   {
946     int saved = cnf->ip_version;
947     cnf->ip_version = AF_INET6;
948     abuf_appendf(out, "%sSmartGatewayPrefix %s\n",
949         cnf->smart_gw_prefix.prefix_len == 0 ? "# " : "",
950         olsr_ip_prefix_to_string(&cnf->smart_gw_prefix));
951     cnf->ip_version = saved;
952   }
953   abuf_appendf(out,
954     "\n"
955     "##############################\n"
956     "### OLSR protocol settings ###\n"
957     "##############################\n"
958     "\n"
959     "# For testing purposes it may be nice to use another port for olsrd\n"
960     "# for using another port than the IANA assigned one\n"
961     "# for a production network, there should be a good reason!!\n"
962     "# valid values are integers greater than 1, please be careful with\n"
963     "# using reserved port numbers\n"
964     "# (default is %u, the IANA assigned olsr-port)\n"
965     "\n", DEF_OLSRPORT);
966   abuf_appendf(out, "%sOlsrPort %u\n",
967       cnf->olsrport == DEF_OLSRPORT ? "# " : "",
968       cnf->olsrport);
969   abuf_puts(out,
970     "\n"
971     "# Sets the main IP (originator ip) of the router. This IP will NEVER\n"
972     "# change during the uptime of olsrd.\n"
973     "# (default is 0.0.0.0, which triggers usage of the IP of the first interface)\n"
974     "\n");
975   {
976     union olsr_ip_addr main_addr;
977     memset(&main_addr, 0, sizeof(main_addr));
978 
979     abuf_appendf(out, "%sMainIp %s\n",
980         !memcmp(&main_addr, &cnf->main_addr, (cnf->ip_version == AF_INET) ? sizeof(main_addr.v4) : sizeof(main_addr.v6)) ? "# " : "",
981         olsr_ip_to_string(&ipbuf, &cnf->main_addr));
982   }
983   abuf_appendf(out,
984     "\n"
985     "# The fixed willingness to use (0-7)\n"
986     "# If not set willingness will be calculated\n"
987     "# dynamically based on battery/power status\n"
988     "# (default is %u)\n"
989     "\n", DEF_WILLINGNESS);
990   abuf_appendf(out, "%sWillingness     %u\n",
991       cnf->willingness == DEF_WILLINGNESS ? "# " : "",
992       cnf->willingness);
993   abuf_puts(out,
994     "\n"
995     "# HNA (Host network association) allows the OLSR to announce\n"
996     "# additional IPs or IP subnets to the net that are reachable\n"
997     "# through this node.\n"
998     "# Syntax for HNA4 is \"network-address    network-mask\"\n"
999     "# Syntax for HNA6 is \"network-address    prefix-length\"\n"
1000     "# (default is no HNA)\n");
1001   olsrd_write_hna_autobuf(AF_INET, hna, out, cnf);
1002   olsrd_write_hna_autobuf(AF_INET6, hna, out, cnf);
1003   abuf_appendf(out,
1004     "\n"
1005     "# Hysteresis for link sensing (only for hopcount metric)\n"
1006     "# Hysteresis adds more robustness to the link sensing\n"
1007     "# but delays neighbor registration.\n"
1008     "# (default is %s)\n"
1009     "\n", DEF_USE_HYST ? "yes" : "no");
1010   abuf_appendf(out, "%sUseHysteresis %s\n",
1011       cnf->use_hysteresis == DEF_USE_HYST ? "# " : "",
1012       cnf->use_hysteresis ? "yes" : "no");
1013   abuf_appendf(out,
1014     "\n"
1015     "# Hysteresis parameters (only for hopcount metric)\n"
1016     "# Do not alter these unless you know what you are doing!\n"
1017     "# Set to auto by default. Allowed values are floating point\n"
1018     "# values in the interval 0,1\n"
1019     "# THR_LOW must always be lower than THR_HIGH!!\n"
1020     "# (default is %.2f/%.2f/%.2f)\n"
1021     "\n", (double)HYST_SCALING, (double)HYST_THRESHOLD_HIGH, (double)HYST_THRESHOLD_LOW);
1022   abuf_appendf(out, "%sHystScaling  %.2f\n",
1023       cnf->hysteresis_param.scaling == (float)HYST_SCALING ? "# " : "",
1024       (double)cnf->hysteresis_param.scaling);
1025   abuf_appendf(out, "%sHystThrHigh  %.2f\n",
1026       cnf->hysteresis_param.thr_high == (float)HYST_THRESHOLD_HIGH ? "# " : "",
1027       (double)cnf->hysteresis_param.thr_high);
1028   abuf_appendf(out, "%sHystThrLow   %.2f\n",
1029       cnf->hysteresis_param.thr_low == (float)HYST_THRESHOLD_LOW ? "# " : "",
1030       (double)cnf->hysteresis_param.thr_low);
1031   abuf_appendf(out,
1032     "\n"
1033     "# TC redundancy\n"
1034     "# Specifies how much neighbor info should be sent in\n"
1035     "# TC messages. Because of a design problem in the 0.5.x\n"
1036     "# dijkstra implementation this value must be set to 2.\n"
1037     "# 2 - send all neighbors\n"
1038     "# (default is %u)\n"
1039     "\n", TC_REDUNDANCY);
1040   abuf_appendf(out, "%sTcRedundancy  %d\n",
1041       cnf->tc_redundancy == TC_REDUNDANCY ? "# " : "",
1042       cnf->tc_redundancy);
1043   abuf_appendf(out,
1044     "\n"
1045     "# MPR coverage specifies how many MPRs a node should\n"
1046     "# try select to reach every 2 hop neighbor. Because of\n"
1047     "# a design problem in the 0.5.x dijkstra algorithm this\n"
1048     "# value should be set to 7.\n"
1049     "# (default is %u)\n"
1050     "\n", MPR_COVERAGE);
1051   abuf_appendf(out, "%sMprCoverage %d\n",
1052       cnf->mpr_coverage == MPR_COVERAGE ? "# " : "",
1053       cnf->mpr_coverage);
1054   abuf_appendf(out,
1055     "\n"
1056     "################################\n"
1057     "### OLSR protocol extensions ###\n"
1058     "################################\n"
1059     "\n"
1060     "# Link quality level switch between hopcount and\n"
1061     "# cost-based (mostly ETX) routing. Because of\n"
1062     "# a design problem in the 0.5.x dijkstra algorithm this\n"
1063     "# value should not be set to 1.\n"
1064     "# 0 = do not use link quality\n"
1065     "# 2 = use link quality for MPR selection and routing\n"
1066     "# (default is %u)\n"
1067     "\n", DEF_LQ_LEVEL);
1068   abuf_appendf(out, "%sLinkQualityLevel %d\n",
1069       cnf->lq_level == DEF_LQ_LEVEL ? "# " : "",
1070       cnf->lq_level);
1071   abuf_appendf(out,
1072     "\n"
1073     "# Link quality algorithm (only for lq level 2)\n"
1074     "# (see README-Olsr-Extensions)\n"
1075     "# - \"etx_float\", a floating point  ETX with exponential aging\n"
1076     "# - \"etx_fpm\", same as ext_float, but with integer arithmetic\n"
1077     "# - \"etx_ff\" (ETX freifunk), an etx variant which use all OLSR\n"
1078     "#   traffic (instead of only hellos) for ETX calculation\n"
1079     "# - \"etx_ffeth\", an incompatible variant of etx_ff that allows\n"
1080     "#   ethernet links with ETX 0.1.\n"
1081     "# (default is \"%s\")\n"
1082     "\n", DEF_LQ_ALGORITHM);
1083   abuf_appendf(out, "%sLinkQualityAlgorithm    \"%s\"\n",
1084       cnf->lq_algorithm == NULL ? "# " : "",
1085       cnf->lq_algorithm == NULL ? DEF_LQ_ALGORITHM : cnf->lq_algorithm);
1086   abuf_appendf(out,
1087     "\n"
1088     "# Link quality aging factor (only for lq level 2)\n"
1089     "# Tuning parameter for etx_float and etx_fpm, smaller values\n"
1090     "# mean slower changes of ETX value. (allowed values are\n"
1091     "# between 0.01 and 1.0)\n"
1092     "# (default is %.2f)\n"
1093     "\n", (double)DEF_LQ_AGING);
1094   abuf_appendf(out, "%sLinkQualityAging %.2f\n",
1095       cnf->lq_aging == (float)DEF_LQ_AGING ? "# " : "",
1096       (double)cnf->lq_aging);
1097   abuf_appendf(out,
1098     "\n"
1099     "# Fisheye mechanism for TCs (0 meansoff, 1 means on)\n"
1100     "# (default is %u)\n"
1101     "\n", DEF_LQ_FISH);
1102   abuf_appendf(out, "%sLinkQualityFishEye  %d\n",
1103       cnf->lq_fish == DEF_LQ_FISH ? "# " : "",
1104       cnf->lq_fish);
1105   abuf_appendf(out,
1106     "\n"
1107     "#\n"
1108     "# NatThreshold\n"
1109     "#\n"
1110     "# (currently this is only in the freifunk firmware)\n"
1111     "# If the NAT-Endpoint (the preferred 0/0 HNA emitting node)\n"
1112     "# is to be changed, the ETX value of the current 0/0 is\n"
1113     "# multiplied with the NatThreshold value before being\n"
1114     "# compared to the new one.\n"
1115     "# The parameter can be a value between 0.1 and 1.0, but\n"
1116     "# should be close to 1.0 if changed.\n"
1117     "# WARNING: This parameter should not be used together with\n"
1118     "# the etx_ffeth metric !!\n"
1119     "# (default is %.1f)\n"
1120     "\n", (double)DEF_LQ_NAT_THRESH);
1121   abuf_appendf(out, "%sNatThreshold  %.1f\n",
1122       cnf->lq_nat_thresh == (float)DEF_LQ_NAT_THRESH ? "# " : "",
1123       (double)cnf->lq_nat_thresh);
1124 
1125   abuf_puts(out,
1126     "\n"
1127     "#############################################################\n"
1128     "### Configuration of the IPC to the windows GUI interface ###\n"
1129     "#############################################################\n"
1130     "\n"
1131     "IpcConnect\n"
1132     "{\n"
1133     "     # Determines how many simultaneously\n"
1134     "     # IPC connections that will be allowed\n"
1135     "     # Setting this to 0 disables IPC\n"
1136     "\n");
1137   abuf_appendf(out, "     %sMaxConnections  %d\n",
1138       cnf->ipc_connections == DEF_IPC_CONNECTIONS ? "# " : "",
1139       cnf->ipc_connections);
1140   abuf_puts(out,
1141     "\n"
1142     "     # By default only 127.0.0.1 is allowed\n"
1143     "     # to connect. Here allowed hosts and networks can\n"
1144     "     # be added\n"
1145     "\n");
1146   if (!ipc_nets)
1147     abuf_puts(out,
1148       "     # Host            127.0.0.1\n"
1149       "     # Host            10.0.0.5\n"
1150       "     # Net             192.168.1.0 255.255.255.0\n");
1151   else
1152     while (ipc_nets) {
1153       if (ipc_nets->net.prefix_len == olsr_cnf->maxplen) {
1154         abuf_appendf(out, "    Host %s\n", olsr_ip_to_string(&ipbuf, &ipc_nets->net.prefix));
1155       } else {
1156         abuf_appendf(out, "    Net  %s\n", olsr_ip_prefix_to_string(&ipc_nets->net));
1157       }
1158       ipc_nets = ipc_nets->next;
1159     }
1160   abuf_puts(out,
1161     "}\n"
1162     "\n"
1163     "#####################################\n"
1164     "### Example plugin configurations ###\n"
1165     "#####################################\n"
1166     "# Olsrd plugins to load\n"
1167     "# This must be the absolute path to the file\n"
1168     "# or the loader will use the following scheme:\n"
1169     "# - Try the paths in the LD_LIBRARY_PATH\n"
1170     "#   environment variable.\n"
1171     "# - The list of libraries cached in /etc/ld.so.cache\n"
1172     "# - /lib, followed by /usr/lib\n"
1173     "#\n"
1174     "\n"
1175     "# Check whether a plugin is available for your operating system.\n"
1176     "# Each plugin should have a README file in it's lib subfolder.\n"
1177     "\n");
1178 
1179   while (plugins) {
1180     abuf_appendf(out, "LoadPlugin \"%s\" {\n", plugins->name);
1181     pl_param = plugins->params;
1182     while (pl_param) {
1183       abuf_appendf(out, "    PlParam \"%s\" \"%s\"\n", pl_param->key, pl_param->value);
1184       pl_param = pl_param->next;
1185     }
1186     abuf_puts(out, "}\n"
1187         "\n");
1188     plugins = plugins->next;
1189   }
1190 
1191   abuf_puts(out,
1192     "#############################################\n"
1193     "### OLSRD default interface configuration ###\n"
1194     "#############################################\n"
1195     "# the default interface section can have the same values as the following\n"
1196     "# interface configuration. It will allow you so set common options for all\n"
1197     "# interfaces.\n"
1198     "\n"
1199     "InterfaceDefaults\n");
1200   olsrd_write_if_autobuf(out, cnf, cnf->interface_defaults, false);
1201   abuf_puts(out,
1202     "\n"
1203     "######################################\n"
1204     "### OLSRd Interfaces configuration ###\n"
1205     "######################################\n"
1206     "# Multiple interfaces can be specified for a single configuration block, format:\n"
1207     "#   Interface \"<OLSRd-Interface1>\" \"<OLSRd-Interface2>\"\n"
1208     "#\n"
1209     "# Multiple configuration blocks can be specified.\n"
1210     "\n");
1211   first = true;
1212   while (interf) {
1213     abuf_appendf(out, "Interface \"%s\"\n", interf->name);
1214     olsrd_write_if_autobuf(out, cnf, interf->cnf, first);
1215 
1216     first = false;
1217     interf = interf->next;
1218   }
1219 
1220   abuf_puts(out,
1221       "\n"
1222       "# END AUTOGENERATED CONFIG\n");
1223 }
1224 /*
1225  * Local Variables:
1226  * c-basic-offset: 2
1227  * indent-tabs-mode: nil
1228  * End:
1229  */
1230