main: initialise sgw system after the tables
[olsrd.git] / src / main.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in
14  *   the documentation and/or other materials provided with the
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include <arpa/inet.h>
42 #include <unistd.h>
43 #include <signal.h>
44 #include <sys/stat.h>
45 #include <assert.h>
46 #include <fcntl.h>
47 #if defined(__linux__) && !defined(__ANDROID__)
48   #ifdef __GLIBC__
49     #include <execinfo.h>
50   #endif
51 #include <syslog.h>
52 #endif /* defined(__linux__) && !defined(__ANDROID__) */
53
54 #include "cfgparser/olsrd_conf.h"
55 #include "ipcalc.h"
56 #include "defs.h"
57 #include "builddata.h"
58 #include "olsr.h"
59 #include "log.h"
60 #include "scheduler.h"
61 #include "parser.h"
62 #include "generate_msg.h"
63 #include "plugin_loader.h"
64 #include "apm.h"
65 #include "net_os.h"
66 #include "build_msg.h"
67 #include "net_olsr.h"
68 #include "mid_set.h"
69 #include "mpr_selector_set.h"
70 #include "gateway.h"
71 #include "olsr_niit.h"
72 #include "olsr_random.h"
73 #include "pid_file.h"
74 #include "lock_file.h"
75 #include "cli.h"
76
77 #ifdef __linux__
78 #include <linux/types.h>
79 #include <linux/rtnetlink.h>
80 #include "kernel_routes.h"
81
82 #endif /* __linux__ */
83
84 #ifdef _WIN32
85 #include <process.h>
86 #include <winbase.h>
87 #define olsr_shutdown(x) SignalHandler(x)
88 #define close(x) closesocket(x)
89 int __stdcall SignalHandler(unsigned long signo) __attribute__ ((noreturn));
90 void DisableIcmpRedirects(void);
91 #endif /* _WIN32 */
92
93 struct timer_entry * heartBeatTimer = NULL;
94
95 static char **olsr_argv = NULL;
96
97 struct olsr_cookie_info *def_timer_ci = NULL;
98
99 static void printStacktrace(const char * message) {
100 #ifdef __GLIBC__
101   void *bt_array[64];
102   size_t bt_size;
103   size_t bt_index=0;
104   char ** bt_syms;
105
106   bt_size = backtrace(bt_array, 64);
107   bt_syms = backtrace_symbols(bt_array, bt_size);
108
109   olsr_syslog(OLSR_LOG_ERR, "%s", message);
110   while (bt_index < bt_size) {
111     olsr_syslog(OLSR_LOG_ERR, "%s", bt_syms[bt_index++]);
112   }
113 #else
114   olsr_syslog(OLSR_LOG_ERR, "%s (logging a stack trace is not supported on this platform)", message);
115 #endif
116 }
117
118 #ifndef _WIN32
119 /**
120  * Reconfigure olsrd. Currently kind of a hack...
121  *
122  *@param signo the signal that triggered this callback
123  */
124 __attribute__ ((noreturn))
125 static void olsr_reconfigure(int signo __attribute__ ((unused))) {
126 #ifndef _WIN32
127   int errNr = errno;
128 #endif
129   /* if we are started with -nofork, we do not want to go into the
130    * background here. So we can simply stop on -HUP
131    */
132   olsr_syslog(OLSR_LOG_INFO, "sot: olsr_reconfigure()\n");
133   if (!olsr_cnf->no_fork) {
134     if (!fork()) {
135       int i;
136       sigset_t sigs;
137
138       /* New process, wait a bit to let the old process exit */
139       sleep(3);
140       sigemptyset(&sigs);
141       sigaddset(&sigs, SIGHUP);
142       sigprocmask(SIG_UNBLOCK, &sigs, NULL);
143       for (i = sysconf(_SC_OPEN_MAX); --i > STDERR_FILENO;) {
144         close(i);
145       }
146       printf("Restarting %s", olsr_argv[0]);
147       olsr_syslog(OLSR_LOG_INFO, "Restarting %s", olsr_argv[0]);
148       execv(olsr_argv[0], olsr_argv);
149       olsr_syslog(OLSR_LOG_ERR, "execv(%s) failed: %s", olsr_argv[0], strerror(errno));
150     } else {
151       olsr_syslog(OLSR_LOG_INFO, "RECONFIGURING");
152     }
153   }
154 #ifndef _WIN32
155   errno = errNr;
156 #endif
157   olsr_exit(NULL, EXIT_SUCCESS);
158 }
159 #endif /* _WIN32 */
160
161 static void olsr_shutdown_messages(void) {
162   struct interface_olsr *ifn;
163
164   /* send TC reset */
165   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
166     /* clean output buffer */
167     net_output(ifn);
168
169     /* send 'I'm gone' messages */
170     if (olsr_cnf->lq_level > 0) {
171       olsr_output_lq_tc(ifn);
172       olsr_output_lq_hello(ifn);
173     } else {
174       generate_tc(ifn);
175       generate_hello(ifn);
176     }
177     net_output(ifn);
178   }
179 }
180
181 /**
182  *Function called at shutdown. Signal handler
183  *
184  * @param signo the signal that triggered this call
185  */
186 __attribute__ ((noreturn))
187 #ifdef _WIN32
188 int __stdcall
189 SignalHandler(unsigned long signo)
190 #else /* _WIN32 */
191 static void olsr_shutdown(int signo __attribute__ ((unused)))
192 #endif /* _WIN32 */
193 {
194   static volatile bool inShutdown = false;
195 #ifndef _WIN32
196   int errNr = errno;
197 #endif
198   struct interface_olsr *ifn;
199   int exit_value;
200
201 #ifdef __linux__
202   OLSR_PRINTF(1, "Received signal %s - shutting down\n", strsignal(signo));
203 #else
204   OLSR_PRINTF(1, "Received signal %d - shutting down\n", (int)signo);
205 #endif
206
207   if (inShutdown) {
208     /* already in shutdown, do not allow nested shutdown */
209     printStacktrace("nested shutdown: exiting immediately");
210     exit(olsr_cnf->exit_value);
211   }
212   inShutdown = true;
213
214   /* instruct the scheduler to stop */
215   olsr_scheduler_stop();
216
217 #ifdef __linux__
218   /* trigger gateway selection */
219   if (olsr_cnf->smart_gw_active) {
220     olsr_shutdown_gateways();
221     olsr_cleanup_gateways();
222   }
223 #endif
224
225   /* clear all links and send empty hellos/tcs */
226   olsr_reset_all_links();
227
228   /* deactivate fisheye and immediate TCs */
229   olsr_cnf->lq_fish = 0;
230   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
231     ifn->immediate_send_tc = false;
232   }
233   increase_local_ansn();
234
235   /* send first shutdown message burst */
236   olsr_shutdown_messages();
237
238   /* delete all routes */
239   olsr_delete_all_kernel_routes();
240
241   /* send second shutdown message burst */
242   olsr_shutdown_messages();
243
244   /* now try to cleanup the rest of the mess */
245   olsr_delete_all_tc_entries();
246
247   olsr_delete_all_mid_entries();
248
249 #ifdef __linux__
250   /* trigger niit static route cleanup */
251   if (olsr_cnf->use_niit) {
252     olsr_cleanup_niit_routes();
253   }
254
255   /* cleanup lo:olsr interface */
256   if (olsr_cnf->use_src_ip_routes) {
257     olsr_os_localhost_if(&olsr_cnf->main_addr, false);
258   }
259 #endif /* __linux__ */
260
261   olsr_destroy_parser();
262
263   olsrd_cfgfile_cleanup();
264
265   OLSR_PRINTF(1, "Closing sockets...\n");
266
267   /* front-end IPC socket */
268   if (olsr_cnf->ipc_connections > 0) {
269     shutdown_ipc();
270   }
271
272   /* OLSR sockets */
273   for (ifn = ifnet; ifn; ifn = ifn->int_next) {
274     close(ifn->olsr_socket);
275     close(ifn->send_socket);
276
277 #ifdef __linux__
278     if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
279       olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default,
280           olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, false);
281     }
282 #endif /* __linux__ */
283   }
284
285   /* stop and cleanup any remaining timers */
286   olsr_flush_timers();
287
288   /* Closing plug-ins */
289   olsr_close_plugins();
290
291   /* Reset network settings */
292   net_os_restore_ifoptions();
293
294   /* ioctl socket */
295   close(olsr_cnf->ioctl_s);
296
297 #ifdef __linux__
298   if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
299     olsr_os_policy_rule(olsr_cnf->ip_version,
300         olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, false);
301   }
302   if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
303     olsr_os_policy_rule(olsr_cnf->ip_version,
304         olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, false);
305   }
306   if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
307     olsr_os_policy_rule(olsr_cnf->ip_version,
308         olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, false);
309   }
310   close(olsr_cnf->rtnl_s);
311   close (olsr_cnf->rt_monitor_socket);
312 #endif /* __linux__ */
313
314 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
315   /* routing socket */
316   close(olsr_cnf->rts);
317 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
318
319   /* remove the lock file */
320   olsr_remove_lock_file();
321
322   /* stop heartbeat that is showing on stdout */
323 #if !defined WINCE
324   if (heartBeatTimer) {
325     olsr_stop_timer(heartBeatTimer);
326     heartBeatTimer = NULL;
327   }
328 #endif /* !defined WINCE */
329
330   /* Free cookies and memory pools attached. */
331   OLSR_PRINTF(0, "Free all memory...\n");
332   olsr_delete_all_cookies();
333
334   olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
335
336   OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);
337
338   exit_value = olsr_cnf->exit_value;
339   olsrd_free_cnf(&olsr_cnf);
340
341   /* close the log */
342   olsr_closelog();
343
344 #ifndef _WIN32
345   errno = errNr;
346 #endif
347   exit(exit_value);
348 }
349
350 #if defined(__linux__) && !defined(__ANDROID__)
351 __attribute__((noreturn))
352 static void olsr_segv_handler(int sig) {
353   static bool in_segv = false;
354
355   if (!in_segv) {
356     in_segv = true;
357     printStacktrace("crash");
358     olsr_shutdown(sig);
359
360     /* safety net */
361     exit(123);
362   }
363
364   printStacktrace("nested crash: exiting immediately");
365   exit(olsr_cnf->exit_value);
366 }
367 #endif /* defined(__linux__) && !defined(__ANDROID__) */
368
369 /**
370  * Sets the provided configuration on all unconfigured
371  * interfaces
372  *
373  * @param ifs a linked list of interfaces to check and possible update
374  * @param cnf the default configuration to set on unconfigured interfaces
375  */
376 static int set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf) {
377   int changes = 0;
378
379   while (ifs) {
380     if (ifs->cnf == NULL) {
381       ifs->cnf = olsr_malloc(sizeof(struct if_config_options),
382           "Set default config");
383       *ifs->cnf = *cnf;
384       changes++;
385     }
386     ifs = ifs->next;
387   }
388   return changes;
389 }
390
391 /**
392  * Main entrypoint
393  */
394
395 int main(int argc, char *argv[]) {
396   int argcLocal = argc;
397
398   /* Open syslog */
399   olsr_openlog("olsrd");
400
401   /*
402    * Initialisation
403    */
404
405   /* setup debug printf destination */
406   debug_handle = stdout;
407
408   /* set stdout and stderr to unbuffered output */
409   setbuf(stdout, NULL);
410   setbuf(stderr, NULL);
411
412   /* setup random seed */
413   srandom(time(NULL));
414
415   /* Init widely used statics */
416   memset(&all_zero, 0, sizeof(union olsr_ip_addr));
417
418   /* store the arguments for restart */
419   olsr_argv = argv;
420
421   /*
422    * Start
423    */
424
425   print_version();
426
427   if (argcLocal == 2) {
428     if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "/?")) {
429       /* help */
430       print_usage(false);
431       olsr_exit(NULL, EXIT_SUCCESS);
432     }
433     if (!strcmp(argv[1], "-v")) {
434       /* version */
435       olsr_exit(NULL, EXIT_SUCCESS);
436     }
437   }
438
439   /* Check root Privileges */
440 #ifndef _WIN32
441   if (geteuid()) {
442     olsr_exit("You must be root (uid = 0) to run olsrd", EXIT_FAILURE);
443   }
444 #else /* _WIN32 */
445   DisableIcmpRedirects();
446
447   {
448     WSADATA WsaData;
449     if (WSAStartup(0x0202, &WsaData)) {
450       char buf2[1024];
451       snprintf(buf2, sizeof(buf2), "%s: Could not initialise WinSock", __func__);
452       olsr_exit(buf2, EXIT_FAILURE);
453     }
454   }
455 #endif /* _WIN32 */
456
457   /* load the configuration */
458   if (!loadConfig(&argcLocal, argv)) {
459     olsr_exit(NULL, EXIT_FAILURE);
460   }
461
462   /* Process CLI Arguments */
463   {
464     char * error = NULL;
465     int exitCode = EXIT_FAILURE;
466
467     /* get the default interface config */
468     struct if_config_options *default_ifcnf = get_default_if_config();
469     if (!default_ifcnf) {
470       olsr_exit("No default ifconfig found", EXIT_FAILURE);
471     }
472
473     /* Process olsrd options */
474     exitCode = olsr_process_arguments(argcLocal, argv, olsr_cnf, default_ifcnf, &error);
475     if (exitCode != 0) {
476       free(default_ifcnf);
477       olsr_exit(error, EXIT_FAILURE);
478     }
479
480     /* Set configuration for command-line specified interfaces */
481     set_default_ifcnfs(olsr_cnf->interfaces, default_ifcnf);
482
483     /* free the default ifcnf */
484     free(default_ifcnf);
485   }
486
487   /* Sanity check configuration */
488   if (olsrd_sanity_check_cnf(olsr_cnf) < 0) {
489     char buf2[1024];
490     snprintf(buf2, sizeof(buf2), "%s: Bad configuration", __func__);
491     olsr_exit(buf2, EXIT_FAILURE);
492   }
493
494   /* Setup derived configuration */
495   set_derived_cnf(olsr_cnf);
496
497   olsrd_cfgfile_init();
498
499   /* Print configuration */
500   if (olsr_cnf->debug_level > 1) {
501     olsrd_print_cnf(olsr_cnf);
502   }
503
504   /* configuration loaded and sane */
505
506   /* initialise timers */
507   olsr_init_timers();
508
509   def_timer_ci = olsr_alloc_cookie("Default Timer Cookie", OLSR_COOKIE_TYPE_TIMER);
510
511   /* create a socket for ioctl calls */
512   olsr_cnf->ioctl_s = socket(olsr_cnf->ip_version, SOCK_DGRAM, 0);
513   if (olsr_cnf->ioctl_s < 0) {
514     char buf2[1024];
515     snprintf(buf2, sizeof(buf2), "ioctl socket: %s", strerror(errno));
516     olsr_exit(buf2, EXIT_FAILURE);
517   }
518
519   /* create a socket for netlink calls */
520 #ifdef __linux__
521   olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
522   if (olsr_cnf->rtnl_s < 0) {
523     char buf2[1024];
524     snprintf(buf2, sizeof(buf2), "rtnetlink socket: %s", strerror(errno));
525     olsr_exit(buf2, EXIT_FAILURE);
526   }
527
528   if (fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK)) {
529     olsr_syslog(OLSR_LOG_INFO, "rtnetlink could not be set to nonblocking");
530   }
531
532   if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) {
533     char buf2[1024];
534     snprintf(buf2, sizeof(buf2), "rtmonitor socket: %s", strerror(errno));
535     olsr_exit(buf2, EXIT_FAILURE);
536   }
537 #endif /* __linux__ */
538
539   /* create routing socket */
540 #if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__
541   olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0);
542   if (olsr_cnf->rts < 0) {
543     char buf2[1024];
544     snprintf(buf2, sizeof(buf2), "routing socket: %s", strerror(errno));
545     olsr_exit(buf2, EXIT_FAILURE);
546   }
547 #endif /* defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __APPLE__ || defined __NetBSD__ || defined __OpenBSD__ */
548
549   /* initialise gateway system */
550 #ifdef __linux__
551   if (olsr_cnf->smart_gw_active && olsr_init_gateways()) {
552     olsr_exit("Cannot initialise gateway tunnels", EXIT_FAILURE);
553   }
554 #endif /* __linux__ */
555
556   /* initialise niit if index */
557 #ifdef __linux__
558   if (olsr_cnf->use_niit) {
559     olsr_init_niit();
560   }
561 #endif /* __linux__ */
562
563   /* initialise empty TC timer */
564   set_empty_tc_timer(GET_TIMESTAMP(0));
565
566   /* enable ip forwarding on host and disable redirects globally (not for WIN32) */
567   net_os_set_global_ifoptions();
568
569   /* initialise parser */
570   olsr_init_parser();
571
572   /* initialise route exporter */
573   olsr_init_export_route();
574
575   /* initialise message sequence number */
576   init_msg_seqno();
577
578   /* initialise dynamic willingness calculation */
579   olsr_init_willingness();
580
581   /* Set up willingness/APM */
582   if (olsr_cnf->willingness_auto) {
583     if (apm_init() < 0) {
584       OLSR_PRINTF(1, "Could not read APM info - setting default willingness(%d)\n", WILL_DEFAULT);
585
586       olsr_syslog(OLSR_LOG_ERR, "Could not read APM info - setting default willingness(%d)\n",
587       WILL_DEFAULT);
588
589       olsr_cnf->willingness_auto = 0;
590       olsr_cnf->willingness = WILL_DEFAULT;
591     } else {
592       olsr_cnf->willingness = olsr_calculate_willingness();
593
594       OLSR_PRINTF(1, "Willingness set to %d - next update in %.1f secs\n", olsr_cnf->willingness, (double )olsr_cnf->will_int);
595     }
596   }
597
598   /* initialise net */
599   init_net();
600
601   /* initialise network interfaces */
602   if (!olsr_init_interfacedb()) {
603     if (olsr_cnf->allow_no_interfaces) {
604       fprintf( stderr, "No interfaces detected! This might be intentional, but it also might mean"
605           " that your configuration is fubar.\nI will continue after 5 seconds...\n");
606       olsr_startup_sleep(5);
607     } else {
608       char buf2[1024];
609       snprintf(buf2, sizeof(buf2), "%s: No interfaces detected", __func__);
610       olsr_exit(buf2, EXIT_FAILURE);
611     }
612   }
613
614   /* initialise the IPC socket */
615   if ((olsr_cnf->ipc_connections > 0) && ipc_init()) {
616     olsr_exit("ipc_init failure", EXIT_FAILURE);
617   }
618
619   /* Initialisation of different tables to be used. */
620   olsr_init_tables();
621
622 #ifdef __linux__
623   /* startup gateway system */
624   if (olsr_cnf->smart_gw_active && olsr_startup_gateways()) {
625     olsr_exit("Cannot startup gateway tunnels", EXIT_FAILURE);
626   }
627 #endif /* __linux__ */
628
629   olsr_do_startup_sleep();
630
631   /* start heartbeat that is showing on stdout */
632 #if !defined WINCE
633   if ((olsr_cnf->debug_level > 0) && isatty(STDOUT_FILENO)) {
634     heartBeatTimer = olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC, &generate_stdout_pulse, NULL, 0);
635   }
636 #endif /* !defined WINCE */
637
638   /* daemon mode */
639 #ifndef _WIN32
640   if ((olsr_cnf->debug_level == 0) && !olsr_cnf->no_fork) {
641     printf("%s detaching from the current process...\n", olsrd_version);
642     if (daemon(0, 0) < 0) {
643       char buf2[1024];
644       snprintf(buf2, sizeof(buf2), "daemon(3) failed: %s", strerror(errno));
645       olsr_exit(buf2, EXIT_FAILURE);
646     }
647   }
648 #endif /* _WIN32 */
649
650   if (!writePidFile()) {
651     olsr_exit(NULL, EXIT_FAILURE);
652   }
653
654   /* Create locking file for olsrd, will be cleared after olsrd exits */
655   if (!olsr_create_lock_file()) {
656     char buf2[1024];
657     snprintf(buf2, sizeof(buf2), "Error, cannot create OLSR lock file '%s'", olsr_cnf->lock_file);
658     olsr_exit(buf2, EXIT_FAILURE);
659   }
660
661   /* Load plugins */
662   olsr_load_plugins();
663
664   /* print the main address */
665   {
666     struct ipaddr_str buf;
667     OLSR_PRINTF(1, "Main address: %s\n\n", olsr_ip_to_string(&buf, &olsr_cnf->main_addr));
668   }
669
670   /* create policy routing rules with priorities if necessary */
671 #ifdef __linux__
672   if (DEF_RT_NONE != olsr_cnf->rt_table_pri) {
673     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table, olsr_cnf->rt_table_pri, NULL, true);
674   }
675
676   if (DEF_RT_NONE != olsr_cnf->rt_table_tunnel_pri) {
677     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_tunnel, olsr_cnf->rt_table_tunnel_pri, NULL, true);
678   }
679
680   if (DEF_RT_NONE != olsr_cnf->rt_table_default_pri) {
681     olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_default_pri, NULL, true);
682   }
683
684   /* rule to default table on all olsrd interfaces */
685   if (DEF_RT_NONE != olsr_cnf->rt_table_defaultolsr_pri) {
686     struct interface_olsr *ifn;
687     for (ifn = ifnet; ifn; ifn = ifn->int_next) {
688       olsr_os_policy_rule(olsr_cnf->ip_version, olsr_cnf->rt_table_default, olsr_cnf->rt_table_defaultolsr_pri, ifn->int_name, true);
689     }
690   }
691
692   /* trigger gateway selection */
693   if (olsr_cnf->smart_gw_active) {
694     olsr_trigger_inetgw_startup();
695   }
696
697   /* trigger niit static route setup */
698   if (olsr_cnf->use_niit) {
699     olsr_setup_niit_routes();
700   }
701
702   /* create lo:olsr interface */
703   if (olsr_cnf->use_src_ip_routes) {
704     olsr_os_localhost_if(&olsr_cnf->main_addr, true);
705   }
706 #endif /* __linux__ */
707
708   /* Start syslog entry */
709   olsr_syslog(OLSR_LOG_INFO, "%s successfully started", olsrd_version);
710
711   /* setup signal-handlers */
712 #ifdef _WIN32
713 #ifndef WINCE
714   SetConsoleCtrlHandler(SignalHandler, true);
715 #endif /* WINCE */
716 #else /* _WIN32 */
717   signal(SIGHUP, olsr_reconfigure);
718   signal(SIGINT, olsr_shutdown);
719   signal(SIGQUIT, olsr_shutdown);
720   signal(SIGILL, olsr_shutdown);
721   signal(SIGABRT, olsr_shutdown);
722 #if defined(__linux__) && !defined(__ANDROID__)
723   signal(SIGSEGV, olsr_segv_handler);
724 #endif  /* defined(__linux__) && !defined(__ANDROID__) */
725   signal(SIGTERM, olsr_shutdown);
726   signal(SIGPIPE, SIG_IGN);
727   // Ignoring SIGUSR1 and SIGUSR1 by default to be able to use them in plugins
728   signal(SIGUSR1, SIG_IGN);
729   signal(SIGUSR2, SIG_IGN);
730 #endif /* _WIN32 */
731
732   /* Starting scheduler */
733   olsr_scheduler();
734
735   /* We'll only get here when olsr_shutdown has stopped the scheduler */
736   sleep(30);
737
738   exit(EXIT_FAILURE);
739 } /* main */
740
741 /*
742  * Local Variables:
743  * c-basic-offset: 2
744  * indent-tabs-mode: nil
745  * End:
746  */