www.usr.com/support/gpl/USR9108_release1.5.tar.gz
[bcm963xx.git] / userapps / opensource / zebra / zebra / main.c
1 /*
2  * zebra daemon main routine.
3  * Copyright (C) 1997, 98 Kunihiro Ishiguro
4  *
5  * This file is part of GNU Zebra.
6  *
7  * GNU Zebra is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2, or (at your option) any
10  * later version.
11  *
12  * GNU Zebra is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
19  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20  * 02111-1307, USA.  
21  */
22
23 #include <zebra.h>
24
25 #include "version.h"
26 #include "getopt.h"
27 #include "command.h"
28 #include "thread.h"
29 #include "filter.h"
30 #include "memory.h"
31 #include "prefix.h"
32 #ifdef BRCM_RIP_DEBUG
33 #include "log.h"
34 #endif
35 #include "zebra/rib.h"
36 #include "zebra/zserv.h"
37 #ifdef BRCM_RIP_DEBUG
38 #include "zebra/debug.h"
39 #endif
40 #include "zebra/rib.h"
41
42 /* Master of threads. */
43 struct thread_master *master;
44
45 /* process id. */
46 pid_t old_pid;
47 pid_t pid;
48
49 /* Route retain mode flag. */
50 int retain_mode = 0;
51
52 /* Don't delete kernel route. */
53 int keep_kernel_mode = 0;
54
55 /* Command line options. */
56 struct option longopts[] = 
57 {
58   { "batch",       no_argument,       NULL, 'b'},
59   { "daemon",      no_argument,       NULL, 'd'},
60   { "keep_kernel", no_argument,       NULL, 'k'},
61   { "log_mode",    no_argument,       NULL, 'l'},
62   { "config_file", required_argument, NULL, 'f'},
63   { "pid_file",    required_argument, NULL, 'i'},
64   { "help",        no_argument,       NULL, 'h'},
65   { "vty_addr",    required_argument, NULL, 'A'},
66   { "vty_port",    required_argument, NULL, 'P'},
67   { "retain",      no_argument,       NULL, 'r'},
68   { "version",     no_argument,       NULL, 'v'},
69   { 0 }
70 };
71
72 /* Default configuration file path. */
73 char config_current[] = DEFAULT_CONFIG_FILE;
74 char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
75
76 /* Process ID saved for use by init system */
77 char *pid_file = PATH_ZEBRA_PID;
78
79 /* Help information display. */
80 static void
81 usage (char *progname, int status)
82 {
83   if (status != 0)
84     fprintf (stderr, "Try `%s --help' for more information.\n", progname);
85   else
86     {    
87       printf ("Usage : %s [OPTION...]\n\n\
88 Daemon which manages kernel routing table management and \
89 redistribution between different routing protocols.\n\n\
90 -b, --batch        Runs in batch mode\n\
91 -d, --daemon       Runs in daemon mode\n\
92 -f, --config_file  Set configuration file name\n\
93 -i, --pid_file     Set process identifier file name\n\
94 -k, --keep_kernel  Don't delete old routes which installed by zebra.\n\
95 -l, --log_mode     Set verbose log mode flag\n\
96 -A, --vty_addr     Set vty's bind address\n\
97 -P, --vty_port     Set vty's port number\n\
98 -r, --retain       When program terminates, retain added route by zebra.\n\
99 -v, --version      Print program version\n\
100 -h, --help         Display this help and exit\n\
101 \n\
102 Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
103     }
104
105   exit (status);
106 }
107 \f
108
109 /* SIGHUP handler. */
110 void 
111 sighup (int sig)
112 {
113 #ifdef BRCM_RIP_DEBUG
114   zlog_info ("SIGHUP received");
115 #endif
116   /* Reload of config file. */
117   ;
118 }
119
120 /* SIGINT handler. */
121 void
122 sigint (int sig)
123 {
124   /* Decrared in rib.c */
125   void rib_close ();
126 #ifdef BRCM_RIP_DEBUG
127   zlog_info ("Terminating on signal");
128 #endif
129   if (!retain_mode)
130     rib_close ();
131
132   exit (0);
133 }
134
135 /* SIGUSR1 handler. */
136 void
137 sigusr1 (int sig)
138 {
139 #ifdef BRCM_RIP_DEBUG
140   zlog_rotate (NULL);
141 #endif
142 }
143
144 /* Signale wrapper. */
145 RETSIGTYPE *
146 signal_set (int signo, void (*func)(int))
147 {
148   int ret;
149   struct sigaction sig;
150   struct sigaction osig;
151
152   sig.sa_handler = func;
153   sigemptyset (&sig.sa_mask);
154   sig.sa_flags = 0;
155 #ifdef SA_RESTART
156   sig.sa_flags |= SA_RESTART;
157 #endif /* SA_RESTART */
158
159   ret = sigaction (signo, &sig, &osig);
160
161   if (ret < 0) 
162     return (SIG_ERR);
163   else
164     return (osig.sa_handler);
165 }
166
167 /* Initialization of signal handles. */
168 void
169 signal_init ()
170 {
171   signal_set (SIGHUP, sighup);
172   signal_set (SIGINT, sigint);
173   signal_set (SIGTERM, sigint);
174   signal_set (SIGPIPE, SIG_IGN);
175   signal_set (SIGUSR1, sigusr1);
176 }
177 \f
178 /* Main startup routine. */
179 #ifdef BUILD_STATIC
180 int
181 zebra_main (int argc, char **argv)
182 #else
183 int
184 main (int argc, char **argv)
185 #endif
186 {
187   char *p;
188   char *vty_addr = NULL;
189   int vty_port = 0;
190   int batch_mode = 0;
191   int daemon_mode = 0;
192   char *config_file = NULL;
193   char *progname;
194   struct thread thread;
195   void rib_weed_tables ();
196
197   /* Set umask before anything for security */
198   umask (0027);
199
200   /* preserve my name */
201   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
202
203 #ifdef BRCM_RIP_DEBUG
204   zlog_default = openzlog (progname, ZLOG_STDOUT, ZLOG_ZEBRA,
205                            LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
206 #endif
207   while (1) 
208     {
209       int opt;
210   
211       opt = getopt_long (argc, argv, "bdklf:hA:P:rv", longopts, 0);
212
213       if (opt == EOF)
214         break;
215
216       switch (opt) 
217         {
218         case 0:
219           break;
220         case 'b':
221           batch_mode = 1;
222         case 'd':
223           daemon_mode = 1;
224           break;
225         case 'k':
226           keep_kernel_mode = 1;
227           break;
228         case 'l':
229           /* log_mode = 1; */
230           break;
231         case 'f':
232           config_file = optarg;
233           break;
234         case 'A':
235           vty_addr = optarg;
236           break;
237         case 'i':
238           pid_file = optarg;
239           break;
240         case 'P':
241           vty_port = atoi (optarg);
242           break;
243         case 'r':
244           retain_mode = 1;
245           break;
246         case 'v':
247 #ifdef BRCM_CMD_SUPPORT
248           print_version (progname);
249 #endif
250           exit (0);
251           break;
252         case 'h':
253           usage (progname, 0);
254           break;
255         default:
256           usage (progname, 1);
257           break;
258         }
259     }
260
261   /* Make master thread emulator. */
262   master = thread_master_create ();
263
264   /* Vty related initialize. */
265   signal_init ();
266   cmd_init (1);
267   vty_init ();
268
269 #ifdef BRCM_CMD_SUPPORT
270   memory_init ();
271 #endif
272
273   /* Zebra related initialize. */
274   zebra_init ();
275   rib_init ();
276   zebra_if_init ();
277
278 #ifdef BRCM_RIP_DEBUG
279   zebra_debug_init ();
280 #endif
281
282 #ifdef BRCM_LIST_SUPPORT
283   access_list_init ();
284 #endif
285
286 #ifdef RTADV
287   rtadv_init ();
288 #endif
289
290   /* For debug purpose. */
291   /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
292
293   /* Make kernel routing socket. */
294   kernel_init ();
295   interface_list ();
296   route_read ();
297
298   /* Sort VTY commands. */
299   sort_node ();
300
301 #ifdef HAVE_SNMP
302   zebra_snmp_init ();
303 #endif /* HAVE_SNMP */
304
305   /* Clean up self inserted route. */
306   if (! keep_kernel_mode)
307     rib_sweep_route ();
308
309   /* Configuration file read*/
310   vty_read_config (config_file, config_current, config_default);
311
312   /* Clean up rib. */
313   rib_weed_tables ();
314
315   /* Exit when zebra is working in batch mode. */
316   if (batch_mode)
317     exit (0);
318
319   /* Needed for BSD routing socket. */
320   old_pid = getpid ();
321
322   /* Daemonize. */
323   if (daemon_mode)
324     daemon (0, 0);
325
326   /* Output pid of zebra. */
327   pid_output (pid_file);
328
329   /* Needed for BSD routing socket. */
330   pid = getpid ();
331
332 #ifdef BRCM_CMD_SUPPORT
333   /* Make vty server socket. */
334   vty_serv_sock (vty_addr,
335                  vty_port ? vty_port : ZEBRA_VTY_PORT, ZEBRA_VTYSH_PATH);
336 #endif
337
338   while (thread_fetch (master, &thread))
339     thread_call (&thread);
340
341   /* Not reached... */
342   exit (0);
343 }