blob: 519cde77b559e26a6932f7cb65fc387910db1790 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * Copyright (C) 1999 Yasuhiro Ohara
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23#include "getopt.h"
24#include "thread.h"
25#include "log.h"
26#include "version.h"
27#include "command.h"
28#include "vty.h"
29#include "memory.h"
pauledd7c242003-06-04 13:59:38 +000030#include "privs.h"
paul718e3742002-12-13 20:15:29 +000031
32#include "ospf6d.h"
33#include "ospf6_network.h"
34
35void ospf6_init ();
36void ospf6_terminate ();
37void nexthop_init ();
38int ospf6_receive (struct thread *);
39
40extern int ospf6_sock;
41
42/* Default configuration file name for ospf6d. */
43#define OSPF6_DEFAULT_CONFIG "ospf6d.conf"
44/* Default port values. */
45#define OSPF6_VTY_PORT 2606
46
pauledd7c242003-06-04 13:59:38 +000047/* ospf6d privileges */
48zebra_capabilities_t _caps_p [] =
49{
50 ZCAP_RAW,
51 ZCAP_BIND
52};
53
54struct zebra_privs_t ospf6d_privs =
55{
56#if defined(ZEBRA_USER)
57 .user = ZEBRA_USER,
58#endif
59#if defined ZEBRA_GROUP
60 .group = ZEBRA_GROUP,
61#endif
62 .caps_p = _caps_p,
63 .cap_num_p = 2,
64 .cap_num_i = 0
65};
66
paul718e3742002-12-13 20:15:29 +000067/* ospf6d options, we use GNU getopt library. */
68struct option longopts[] =
69{
70 { "daemon", no_argument, NULL, 'd'},
71 { "config_file", required_argument, NULL, 'f'},
72 { "pid_file", required_argument, NULL, 'i'},
73 { "vty_addr", required_argument, NULL, 'A'},
74 { "vty_port", required_argument, NULL, 'P'},
pauledd7c242003-06-04 13:59:38 +000075 { "user", required_argument, NULL, 'u'},
paul718e3742002-12-13 20:15:29 +000076 { "version", no_argument, NULL, 'v'},
77 { "help", no_argument, NULL, 'h'},
78 { 0 }
79};
80
81/* Configuration file and directory. */
82char config_current[] = OSPF6_DEFAULT_CONFIG;
83char config_default[] = SYSCONFDIR OSPF6_DEFAULT_CONFIG;
84
85/* ospf6d program name. */
86
87/* is daemon? */
88int daemon_mode = 0;
89
90/* Master of threads. */
91struct thread_master *master;
92
93/* Process ID saved for use by init system */
94char *pid_file = PATH_OSPF6D_PID;
95
96/* for reload */
97char _cwd[64];
98char _progpath[64];
99int _argc;
100char **_argv;
101char **_envp;
102
103/* Help information display. */
104static void
105usage (char *progname, int status)
106{
107 if (status != 0)
108 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
109 else
110 {
111 printf ("Usage : %s [OPTION...]\n\n\
112Daemon which manages OSPF version 3.\n\n\
113-d, --daemon Runs in daemon mode\n\
114-f, --config_file Set configuration file name\n\
115-i, --pid_file Set process identifier file name\n\
116-A, --vty_addr Set vty's bind address\n\
117-P, --vty_port Set vty's port number\n\
pauledd7c242003-06-04 13:59:38 +0000118-u, --user User and group to run as\n\
paul718e3742002-12-13 20:15:29 +0000119-v, --version Print program version\n\
120-h, --help Display this help and exit\n\
121\n\
122Report bugs to yasu@sfc.wide.ad.jp\n", progname);
123 }
124
125 exit (status);
126}
127
128
129void
130_reload ()
131{
132 zlog_notice ("OSPF6d (Zebra-%s ospf6d-%s) reloaded",
133 ZEBRA_VERSION, OSPF6_DAEMON_VERSION);
134 ospf6_zebra_finish ();
135 vty_finish ();
136 execve (_progpath, _argv, _envp);
137}
138
139void
140terminate (int i)
141{
142 ospf6_delete (ospf6);
143 unlink (PATH_OSPF6D_PID);
144 zlog_notice ("OSPF6d (Zebra-%s ospf6d-%s) terminated",
145 ZEBRA_VERSION, OSPF6_DAEMON_VERSION);
146 exit (i);
147}
148
149/* SIGHUP handler. */
150void
151sighup (int sig)
152{
153 zlog_info ("SIGHUP received");
154 _reload ();
155}
156
157/* SIGINT handler. */
158void
159sigint (int sig)
160{
161 zlog_info ("SIGINT received");
162 terminate (0);
163}
164
165/* SIGTERM handler. */
166void
167sigterm (int sig)
168{
169 zlog_info ("SIGTERM received");
170 terminate (0);
171}
172
173/* SIGUSR1 handler. */
174void
175sigusr1 (int sig)
176{
177 zlog_info ("SIGUSR1 received");
178 zlog_rotate (NULL);
179}
180
181/* Signale wrapper. */
182RETSIGTYPE *
183signal_set (int signo, void (*func)(int))
184{
185 int ret;
186 struct sigaction sig;
187 struct sigaction osig;
188
189 sig.sa_handler = func;
190 sigemptyset (&sig.sa_mask);
191 sig.sa_flags = 0;
192#ifdef SA_RESTART
193 sig.sa_flags |= SA_RESTART;
194#endif /* SA_RESTART */
195
196 ret = sigaction (signo, &sig, &osig);
197
198 if (ret < 0)
199 return (SIG_ERR);
200 else
201 return (osig.sa_handler);
202}
203
204/* Initialization of signal handles. */
205void
206signal_init ()
207{
208 signal_set (SIGHUP, sighup);
209 signal_set (SIGINT, sigint);
210 signal_set (SIGTERM, sigterm);
211 signal_set (SIGPIPE, SIG_IGN);
212#ifdef SIGTSTP
213 signal_set (SIGTSTP, SIG_IGN);
214#endif
215#ifdef SIGTTIN
216 signal_set (SIGTTIN, SIG_IGN);
217#endif
218#ifdef SIGTTOU
219 signal_set (SIGTTOU, SIG_IGN);
220#endif
221 signal_set (SIGUSR1, sigusr1);
222}
223
224/* Main routine of ospf6d. Treatment of argument and start ospf finite
225 state machine is handled here. */
226int
227main (int argc, char *argv[], char *envp[])
228{
229 char *p;
230 int opt;
231 char *vty_addr = NULL;
paul4fc4e7a2003-01-22 19:47:09 +0000232 int vty_port = OSPF6_VTY_PORT;
paul718e3742002-12-13 20:15:29 +0000233 char *config_file = NULL;
234 char *progname;
235 struct thread thread;
236 int flag;
237
238 /* Set umask before anything for security */
239 umask (0027);
240
241 /* Preserve name of myself. */
242 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
243
244 /* for reload */
245 _argc = argc;
246 _argv = argv;
247 _envp = envp;
248 getcwd (_cwd, sizeof (_cwd));
249 if (*argv[0] == '.')
250 snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]);
251 else
252 snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
253
254 /* Command line argument treatment. */
255 while (1)
256 {
pauledd7c242003-06-04 13:59:38 +0000257 opt = getopt_long (argc, argv, "df:hp:A:P:u:v", longopts, 0);
paul718e3742002-12-13 20:15:29 +0000258
259 if (opt == EOF)
260 break;
261
262 switch (opt)
263 {
264 case 0:
265 break;
266 case 'd':
267 daemon_mode = 1;
268 break;
269 case 'f':
270 config_file = optarg;
271 break;
272 case 'A':
273 vty_addr = optarg;
274 break;
275 case 'i':
276 pid_file = optarg;
277 break;
278 case 'P':
paul4fc4e7a2003-01-22 19:47:09 +0000279 /* Deal with atoi() returning 0 on failure, and ospf6d not
280 listening on ospf6d port... */
281 if (strcmp(optarg, "0") == 0)
282 {
283 vty_port = 0;
284 break;
285 }
paul718e3742002-12-13 20:15:29 +0000286 vty_port = atoi (optarg);
paul4fc4e7a2003-01-22 19:47:09 +0000287 vty_port = (vty_port ? vty_port : OSPF6_VTY_PORT);
288 break;
pauledd7c242003-06-04 13:59:38 +0000289 case 'u':
290 ospf6d_privs.user = ospf6d_privs.group = optarg;
291 break;
paul718e3742002-12-13 20:15:29 +0000292 case 'v':
293 print_version (progname);
294 exit (0);
295 break;
296 case 'h':
297 usage (progname, 0);
298 break;
299 default:
300 usage (progname, 1);
301 break;
302 }
303 }
304
305 /* thread master */
306 master = thread_master_create ();
307
308 /* Initializations. */
309 if (! daemon_mode)
310 flag = ZLOG_STDOUT;
311 else
hassoe26bbeb2003-05-25 21:39:29 +0000312 flag = ZLOG_NOLOG;
paul718e3742002-12-13 20:15:29 +0000313
314 zlog_default = openzlog (progname, flag, ZLOG_OSPF6,
hassoe26bbeb2003-05-25 21:39:29 +0000315 LOG_CONS|LOG_NDELAY|LOG_PID,
paul718e3742002-12-13 20:15:29 +0000316 LOG_DAEMON);
pauledd7c242003-06-04 13:59:38 +0000317 zprivs_init (&ospf6d_privs);
paul718e3742002-12-13 20:15:29 +0000318 signal_init ();
319 cmd_init (1);
paulb21b19c2003-06-15 01:28:29 +0000320 vty_init (master);
paul718e3742002-12-13 20:15:29 +0000321 ospf6_init ();
322 memory_init ();
323 sort_node ();
324
325 /* parse config file */
326 vty_read_config (config_file, config_current, config_default);
327
328 if (daemon_mode)
329 daemon (0, 0);
330
331 /* pid file create */
332#if 0
333 pid_output_lock (pid_file);
334#else
335 pid_output (pid_file);
336#endif
337
338 /* Make ospf protocol socket. */
339 ospf6_serv_sock ();
340 thread_add_read (master, ospf6_receive, NULL, ospf6_sock);
341
342 /* Make ospf vty socket. */
paul4fc4e7a2003-01-22 19:47:09 +0000343 vty_serv_sock (vty_addr, vty_port, OSPF6_VTYSH_PATH);
paul718e3742002-12-13 20:15:29 +0000344
hassoe26bbeb2003-05-25 21:39:29 +0000345#ifdef DEBUG
paul718e3742002-12-13 20:15:29 +0000346 /* Print start message */
347 zlog_notice ("OSPF6d (Zebra-%s ospf6d-%s) starts",
348 ZEBRA_VERSION, OSPF6_DAEMON_VERSION);
hassoe26bbeb2003-05-25 21:39:29 +0000349#endif
paul718e3742002-12-13 20:15:29 +0000350
351 /* Start finite state machine, here we go! */
352 while (thread_fetch (master, &thread))
353 thread_call (&thread);
354
355 /* Log in case thread failed */
356 zlog_warn ("Thread failed");
357 terminate (0);
358
359 /* Not reached. */
360 exit (0);
361}
362