]> git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_main.c
lib: Improve formatting for matcher tracing output
[mirror_frr.git] / ospfd / ospf_main.c
1 /*
2 * OSPFd main routine.
3 * Copyright (C) 1998, 99 Kunihiro Ishiguro, Toshiaki Takada
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 <lib/version.h>
26 #include "getopt.h"
27 #include "thread.h"
28 #include "prefix.h"
29 #include "linklist.h"
30 #include "if.h"
31 #include "vector.h"
32 #include "vty.h"
33 #include "command.h"
34 #include "filter.h"
35 #include "plist.h"
36 #include "stream.h"
37 #include "log.h"
38 #include "memory.h"
39 #include "memory_vty.h"
40 #include "privs.h"
41 #include "sigevent.h"
42 #include "zclient.h"
43 #include "vrf.h"
44
45 #include "ospfd/ospfd.h"
46 #include "ospfd/ospf_interface.h"
47 #include "ospfd/ospf_asbr.h"
48 #include "ospfd/ospf_lsa.h"
49 #include "ospfd/ospf_lsdb.h"
50 #include "ospfd/ospf_neighbor.h"
51 #include "ospfd/ospf_dump.h"
52 #include "ospfd/ospf_zebra.h"
53 #include "ospfd/ospf_vty.h"
54 #include "ospfd/ospf_bfd.h"
55
56 /* ospfd privileges */
57 zebra_capabilities_t _caps_p [] =
58 {
59 ZCAP_NET_RAW,
60 ZCAP_BIND,
61 ZCAP_NET_ADMIN,
62 };
63
64 struct zebra_privs_t ospfd_privs =
65 {
66 #if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
67 .user = QUAGGA_USER,
68 .group = QUAGGA_GROUP,
69 #endif
70 #if defined(VTY_GROUP)
71 .vty_group = VTY_GROUP,
72 #endif
73 .caps_p = _caps_p,
74 .cap_num_p = array_size(_caps_p),
75 .cap_num_i = 0
76 };
77
78 /* Configuration filename and directory. */
79 char config_default[100];
80
81 /* OSPFd options. */
82 struct option longopts[] =
83 {
84 { "daemon", no_argument, NULL, 'd'},
85 { "instance", required_argument, NULL, 'n'},
86 { "config_file", required_argument, NULL, 'f'},
87 { "pid_file", required_argument, NULL, 'i'},
88 { "socket", required_argument, NULL, 'z'},
89 { "dryrun", no_argument, NULL, 'C'},
90 { "help", no_argument, NULL, 'h'},
91 { "vty_addr", required_argument, NULL, 'A'},
92 { "vty_port", required_argument, NULL, 'P'},
93 { "user", required_argument, NULL, 'u'},
94 { "group", required_argument, NULL, 'g'},
95 { "apiserver", no_argument, NULL, 'a'},
96 { "version", no_argument, NULL, 'v'},
97 { 0 }
98 };
99
100 /* OSPFd program name */
101
102 /* Master of threads. */
103 struct thread_master *master;
104
105 /* Process ID saved for use by init system */
106 char pid_file[100];
107
108 #ifdef SUPPORT_OSPF_API
109 extern int ospf_apiserver_enable;
110 #endif /* SUPPORT_OSPF_API */
111
112 /* Help information display. */
113 static void __attribute__ ((noreturn))
114 usage (char *progname, int status)
115 {
116 if (status != 0)
117 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
118 else
119 {
120 printf ("Usage : %s [OPTION...]\n\
121 Daemon which manages OSPF.\n\n\
122 -d, --daemon Runs in daemon mode\n\
123 -n, --instance Set the instance id\n\
124 -f, --config_file Set configuration file name\n\
125 -i, --pid_file Set process identifier file name\n\
126 -z, --socket Set path of zebra socket\n\
127 -A, --vty_addr Set vty's bind address\n\
128 -P, --vty_port Set vty's port number\n\
129 -u, --user User to run as\n\
130 -g, --group Group to run as\n\
131 -a. --apiserver Enable OSPF apiserver\n\
132 -v, --version Print program version\n\
133 -C, --dryrun Check configuration for validity and exit\n\
134 -h, --help Display this help and exit\n\
135 \n\
136 Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
137 }
138 exit (status);
139 }
140
141 /* SIGHUP handler. */
142 static void
143 sighup (void)
144 {
145 zlog (NULL, LOG_INFO, "SIGHUP received");
146 }
147
148 /* SIGINT / SIGTERM handler. */
149 static void
150 sigint (void)
151 {
152 zlog_notice ("Terminating on signal");
153 ospf_terminate ();
154 }
155
156 /* SIGUSR1 handler. */
157 static void
158 sigusr1 (void)
159 {
160 zlog_rotate (NULL);
161 }
162
163 struct quagga_signal_t ospf_signals[] =
164 {
165 {
166 .signal = SIGHUP,
167 .handler = &sighup,
168 },
169 {
170 .signal = SIGUSR1,
171 .handler = &sigusr1,
172 },
173 {
174 .signal = SIGINT,
175 .handler = &sigint,
176 },
177 {
178 .signal = SIGTERM,
179 .handler = &sigint,
180 },
181 };
182
183 /* OSPFd main routine. */
184 int
185 main (int argc, char **argv)
186 {
187 char *p;
188 char *vty_addr = NULL;
189 int vty_port = OSPF_VTY_PORT;
190 char vty_path[100];
191 int daemon_mode = 0;
192 char *config_file = NULL;
193 char *progname;
194 u_short instance = 0;
195 struct thread thread;
196 int dryrun = 0;
197
198 /* Set umask before anything for security */
199 umask (0027);
200
201 #ifdef SUPPORT_OSPF_API
202 /* OSPF apiserver is disabled by default. */
203 ospf_apiserver_enable = 0;
204 #endif /* SUPPORT_OSPF_API */
205
206 /* get program name */
207 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
208
209 while (1)
210 {
211 int opt;
212
213 opt = getopt_long (argc, argv, "df:i:n:z:hA:P:u:g:avC", longopts, 0);
214
215 if (opt == EOF)
216 break;
217
218 switch (opt)
219 {
220 case 'n':
221 instance = atoi(optarg);
222 if (instance < 1)
223 exit(0);
224 break;
225 case 0:
226 break;
227 case 'd':
228 daemon_mode = 1;
229 break;
230 case 'f':
231 config_file = optarg;
232 break;
233 case 'A':
234 vty_addr = optarg;
235 break;
236 case 'i':
237 strcpy(pid_file,optarg);
238 break;
239 case 'z':
240 zclient_serv_path_set (optarg);
241 break;
242 case 'P':
243 /* Deal with atoi() returning 0 on failure, and ospfd not
244 listening on ospfd port... */
245 if (strcmp(optarg, "0") == 0)
246 {
247 vty_port = 0;
248 break;
249 }
250 vty_port = atoi (optarg);
251 if (vty_port <= 0 || vty_port > 0xffff)
252 vty_port = OSPF_VTY_PORT;
253 break;
254 case 'u':
255 ospfd_privs.user = optarg;
256 break;
257 case 'g':
258 ospfd_privs.group = optarg;
259 break;
260 #ifdef SUPPORT_OSPF_API
261 case 'a':
262 ospf_apiserver_enable = 1;
263 break;
264 #endif /* SUPPORT_OSPF_API */
265 case 'v':
266 print_version (progname);
267 exit (0);
268 break;
269 case 'C':
270 dryrun = 1;
271 break;
272 case 'h':
273 usage (progname, 0);
274 break;
275 default:
276 usage (progname, 1);
277 break;
278 }
279 }
280
281 /* Invoked by a priviledged user? -- endo. */
282 if (geteuid () != 0)
283 {
284 errno = EPERM;
285 perror (progname);
286 exit (1);
287 }
288
289 zlog_default = openzlog (progname, ZLOG_OSPF, instance,
290 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
291 zprivs_init (&ospfd_privs);
292 #if defined(HAVE_CUMULUS)
293 zlog_set_level (NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
294 #endif
295
296 /* OSPF master init. */
297 ospf_master_init ();
298
299 /* Initializations. */
300 master = om->master;
301
302 /* Library inits. */
303 signal_init (master, array_size(ospf_signals), ospf_signals);
304 cmd_init (1);
305 debug_init ();
306 vty_init (master);
307 memory_init ();
308 vrf_init ();
309
310 access_list_init ();
311 prefix_list_init ();
312
313 /* OSPFd inits. */
314 ospf_if_init ();
315 ospf_zebra_init(master, instance);
316
317 /* OSPF vty inits. */
318 ospf_vty_init ();
319 ospf_vty_show_init ();
320 ospf_vty_clear_init ();
321
322 /* OSPF BFD init */
323 ospf_bfd_init();
324
325 ospf_route_map_init ();
326 #ifdef HAVE_SNMP
327 ospf_snmp_init ();
328 #endif /* HAVE_SNMP */
329 ospf_opaque_init ();
330
331 /* Need to initialize the default ospf structure, so the interface mode
332 commands can be duly processed if they are received before 'router ospf',
333 when quagga(ospfd) is restarted */
334 if (!ospf_get_instance(instance))
335 {
336 zlog_err("OSPF instance init failed: %s", strerror(errno));
337 exit (1);
338 }
339
340 /* Get configuration file. */
341 if (instance)
342 sprintf(config_default, "%sospfd-%d.conf", SYSCONFDIR, instance);
343 else
344 sprintf(config_default, "%s%s", SYSCONFDIR, OSPF_DEFAULT_CONFIG);
345 vty_read_config (config_file, config_default);
346
347 /* Start execution only if not in dry-run mode */
348 if (dryrun)
349 return(0);
350
351 /* Change to the daemon program. */
352 if (daemon_mode && daemon (0, 0) < 0)
353 {
354 zlog_err("OSPFd daemon failed: %s", strerror(errno));
355 exit (1);
356 }
357
358 /* Create VTY socket */
359 if (instance)
360 {
361 sprintf(pid_file, "/var/run/quagga/ospfd-%d.pid", instance);
362 sprintf(vty_path, "/var/run/quagga/ospfd-%d.vty", instance);
363 }
364 else
365 {
366 strcpy(pid_file, PATH_OSPFD_PID);
367 strcpy(vty_path, OSPF_VTYSH_PATH);
368 }
369 /* Process id file create. */
370 pid_output (pid_file);
371
372 vty_serv_sock (vty_addr, vty_port, vty_path);
373
374 /* Print banner. */
375 zlog_notice ("OSPFd %s starting: vty@%d, %s", QUAGGA_VERSION, vty_port, vty_path);
376
377 /* Fetch next active thread. */
378 while (thread_fetch (master, &thread))
379 thread_call (&thread);
380
381 /* Not reached. */
382 return (0);
383 }
384