blob: 5681350370c184510e1c50b009db4de4bc23caed [file] [log] [blame]
jardineb5d44e2003-12-23 08:09:43 +00001/*
2 * IS-IS Rout(e)ing protocol - isis_main.c
3 *
4 * Copyright (C) 2001,2002 Sampo Saaristo
5 * Tampere University of Technology
6 * Institute of Communications Engineering
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public Licenseas published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23#include <stdio.h>
24#include <zebra.h>
25#include <net/ethernet.h>
26
27#include "getopt.h"
28#include "thread.h"
29#include "log.h"
30#include "version.h"
31#include "command.h"
32#include "vty.h"
33#include "memory.h"
34#include "stream.h"
35#include "if.h"
jardin9e867fe2003-12-23 08:56:18 +000036#include "privs.h"
jardineb5d44e2003-12-23 08:09:43 +000037
38#include "isisd/dict.h"
39#include "include-netbsd/iso.h"
40#include "isisd/isis_constants.h"
41#include "isisd/isis_common.h"
42#include "isisd/isis_flags.h"
43#include "isisd/isis_circuit.h"
44#include "isisd/isisd.h"
45#include "isisd/isis_dynhn.h"
46
47/* Default configuration file name */
48#define ISISD_DEFAULT_CONFIG "isisd.conf"
49/* Default vty port */
jardinfc58e872003-12-23 10:42:45 +000050#define ISISD_VTY_PORT 2608
jardineb5d44e2003-12-23 08:09:43 +000051
jardin9e867fe2003-12-23 08:56:18 +000052/* isisd privileges */
53zebra_capabilities_t _caps_p [] =
54{
55 ZCAP_RAW,
56 ZCAP_BIND
57};
58
59struct zebra_privs_t isisd_privs =
60{
61#if defined(QUAGGA_USER)
62 .user = QUAGGA_USER,
63#endif
64#if defined QUAGGA_GROUP
65 .group = QUAGGA_GROUP,
66#endif
67#ifdef VTY_GROUP
68 .vty_group = VTY_GROUP,
69#endif
70 .caps_p = _caps_p,
71 .cap_num_p = 2,
72 .cap_num_i = 0
73};
74
jardineb5d44e2003-12-23 08:09:43 +000075/* isisd options */
76struct option longopts[] =
77{
78 { "daemon", no_argument, NULL, 'd'},
79 { "config_file", required_argument, NULL, 'f'},
80 { "vty_port", required_argument, NULL, 'P'},
jardin9e867fe2003-12-23 08:56:18 +000081 { "user", required_argument, NULL, 'u'},
jardineb5d44e2003-12-23 08:09:43 +000082 { "version", no_argument, NULL, 'v'},
83 { "help", no_argument, NULL, 'h'},
84 { 0 }
85};
86
87/* Configuration file and directory. */
88char config_current[] = ISISD_DEFAULT_CONFIG;
89char config_default[] = SYSCONFDIR ISISD_DEFAULT_CONFIG;
90char *config_file = NULL;
91
92/* isisd program name. */
93char *progname;
94
95int daemon_mode = 0;
96
97/* Master of threads. */
98struct thread_master *master;
99
100
101/* for reload */
102char _cwd[64];
103char _progpath[64];
104int _argc;
105char **_argv;
106char **_envp;
107
108
109/* Help information display. */
110static void
111usage (int status)
112{
113 if (status != 0)
114 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
115 else
116 {
117 printf ("Usage : %s [OPTION...]\n\n\
118Daemon which manages IS-IS routing\n\n\
119-d, --daemon Runs in daemon mode\n\
120-f, --config_file Set configuration file name\n\
121-P, --vty_port Set vty's port number\n\
jardin9e867fe2003-12-23 08:56:18 +0000122-u, --user User and group to run as\n\
jardineb5d44e2003-12-23 08:09:43 +0000123-v, --version Print program version\n\
124-h, --help Display this help and exit\n\
125\n\
126Report bugs to sambo@cs.tut.fi\n", progname);
127 }
128
129 exit (status);
130}
131
132
133void
134reload ()
135{
136 zlog_info ("Reload");
137 /* FIXME: Clean up func call here */
138 vty_finish ();
139 execve (_progpath, _argv, _envp);
140}
141
142void
143terminate (int i)
144{
145 exit (i);
146}
147
148/*
149 * Signal handlers
150 */
151void
152sighup (int sig)
153{
154 zlog_info ("SIGHUP received");
155 reload ();
156
157 return;
158}
159
160void
161sigint (int sig)
162{
163 zlog_info ("SIGINT received");
164 terminate (0);
165
166 return;
167}
168
169void
170sigterm (int sig)
171{
172 zlog_info ("SIGTERM received");
173 terminate (0);
174}
175
176void
177sigusr1 (int sig)
178{
179 zlog_info ("SIGUSR1 received");
180 zlog_rotate (NULL);
181}
182
183/*
184 * Signal wrapper.
185 */
186RETSIGTYPE *
187signal_set (int signo, void (*func)(int))
188{
189 int ret;
190 struct sigaction sig;
191 struct sigaction osig;
192
193 sig.sa_handler = func;
194 sigemptyset (&sig.sa_mask);
195 sig.sa_flags = 0;
196#ifdef SA_RESTART
197 sig.sa_flags |= SA_RESTART;
198#endif /* SA_RESTART */
199
200 ret = sigaction (signo, &sig, &osig);
201
202 if (ret < 0)
203 return (SIG_ERR);
204 else
205 return (osig.sa_handler);
206}
207
208void
209signal_init ()
210{
211 signal_set (SIGHUP, sighup);
212 signal_set (SIGINT, sigint);
213 signal_set (SIGTERM, sigterm);
214 signal_set (SIGPIPE, SIG_IGN);
215#ifdef SIGTSTP
216 signal_set (SIGTSTP, SIG_IGN);
217#endif
218#ifdef SIGTTIN
219 signal_set (SIGTTIN, SIG_IGN);
220#endif
221#ifdef SIGTTOU
222 signal_set (SIGTTOU, SIG_IGN);
223#endif
224 signal_set (SIGUSR1, sigusr1);
225}
226
227/*
228 * Main routine of isisd. Parse arguments and handle IS-IS state machine.
229 */
230int
231main (int argc, char **argv, char **envp)
232{
233 char *p;
234 int opt, vty_port = ISISD_VTY_PORT;
235 struct thread thread;
236 char *config_file = NULL;
237 char *vty_addr = NULL;
238
239 /* Get the programname without the preceding path. */
240 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
241
242 zlog_default = openzlog (progname, ZLOG_NOLOG, ZLOG_ISIS,
243 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
244
245
246 /* for reload */
247 _argc = argc;
248 _argv = argv;
249 _envp = envp;
250 getcwd (_cwd, sizeof (_cwd));
251 if (*argv[0] == '.')
252 snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]);
253 else
254 snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
255
256 /* Command line argument treatment. */
257 while (1)
258 {
jardin9e867fe2003-12-23 08:56:18 +0000259 opt = getopt_long (argc, argv, "df:hAp:P:u:v", longopts, 0);
jardineb5d44e2003-12-23 08:09:43 +0000260
261 if (opt == EOF)
262 break;
263
264 switch (opt)
265 {
266 case 0:
267 break;
268 case 'd':
269 daemon_mode = 1;
270 break;
271 case 'f':
272 config_file = optarg;
273 break;
274 case 'A':
275 vty_addr = optarg;
276 break;
277 case 'P':
jardin9e867fe2003-12-23 08:56:18 +0000278 /* Deal with atoi() returning 0 on failure, and isisd not
279 listening on isisd port... */
280 if (strcmp(optarg, "0") == 0)
281 {
282 vty_port = 0;
283 break;
284 }
jardineb5d44e2003-12-23 08:09:43 +0000285 vty_port = atoi (optarg);
jardin9e867fe2003-12-23 08:56:18 +0000286 vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
287 break;
288 case 'u':
289 isisd_privs.user = isisd_privs.group = optarg;
290 break;
jardineb5d44e2003-12-23 08:09:43 +0000291 break;
292 case 'v':
293 printf("ISISd version %s\n", ISISD_VERSION);
294 printf("Copyright (c) 2001-2002 Sampo Saaristo,"
295 " Ofer Wald and Hannes Gredler\n");
296 print_version ("Zebra");
297 exit (0);
298 break;
299 case 'h':
300 usage (0);
301 break;
302 default:
303 usage (1);
304 break;
305 }
306 }
307
308 /* thread master */
309 master = thread_master_create ();
310
311 /* random seed from time */
312 srand(time(NULL));
313
314 /*
315 * initializations
316 */
jardin9e867fe2003-12-23 08:56:18 +0000317 zprivs_init (&isisd_privs);
jardineb5d44e2003-12-23 08:09:43 +0000318 signal_init ();
319 cmd_init (1);
jardin9e867fe2003-12-23 08:56:18 +0000320 vty_init (master);
jardineb5d44e2003-12-23 08:09:43 +0000321 memory_init ();
322 isis_init ();
323 dyn_cache_init ();
324 sort_node ();
325
326 /* parse config file */
327 /* this is needed three times! because we have interfaces before the areas */
328 vty_read_config (config_file, config_current, config_default);
329#if 0
330 vty_read_config (config_file, config_current, config_default);
331 vty_read_config (config_file, config_current, config_default);
332#endif
333 /* demonize */
334 if (daemon_mode)
335 daemon (0, 0);
336
jardineb5d44e2003-12-23 08:09:43 +0000337 /* Process ID file creation. */
338 pid_output (PATH_ISISD_PID);
339
340 /* Make isis vty socket. */
jardin9e867fe2003-12-23 08:56:18 +0000341 vty_serv_sock (vty_addr, vty_port, ISIS_VTYSH_PATH);
jardineb5d44e2003-12-23 08:09:43 +0000342
343 /* Print banner. */
jardin9e867fe2003-12-23 08:56:18 +0000344#if defined(ZEBRA_VERSION)
jardineb5d44e2003-12-23 08:09:43 +0000345 zlog_info ("ISISd %s starting: vty@%d", ZEBRA_VERSION, vty_port);
jardin9e867fe2003-12-23 08:56:18 +0000346#elif defined(QUAGGA_VERSION)
347 zlog_info ("Quagga-ISISd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
348#endif
jardineb5d44e2003-12-23 08:09:43 +0000349#ifdef HAVE_IPV6
350 zlog_info ("IPv6 enabled");
351#endif
352 /* Start finite state machine. */
353 while (thread_fetch (master, &thread))
354 thread_call (&thread);
355
356 /* Not reached. */
357 exit (0);
358}
359
360
361
362
363
364
365
366
367
368