]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - ospf6d/ospf6_main.c
New upstream version 1.2.4
[quagga-debian.git] / ospf6d / ospf6_main.c
1 /*
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 <lib/version.h>
24
25 #include "getopt.h"
26 #include "thread.h"
27 #include "log.h"
28 #include "command.h"
29 #include "vty.h"
30 #include "memory.h"
31 #include "if.h"
32 #include "filter.h"
33 #include "prefix.h"
34 #include "plist.h"
35 #include "privs.h"
36 #include "sigevent.h"
37 #include "zclient.h"
38 #include "vrf.h"
39
40 #include "ospf6d.h"
41 #include "ospf6_top.h"
42 #include "ospf6_message.h"
43 #include "ospf6_asbr.h"
44 #include "ospf6_lsa.h"
45 #include "ospf6_interface.h"
46 #include "ospf6_zebra.h"
47
48 /* Default configuration file name for ospf6d. */
49 #define OSPF6_DEFAULT_CONFIG       "ospf6d.conf"
50
51 /* Default port values. */
52 #define OSPF6_VTY_PORT             2606
53
54 /* ospf6d privileges */
55 zebra_capabilities_t _caps_p [] =
56 {
57   ZCAP_NET_RAW,
58   ZCAP_BIND
59 };
60
61 struct zebra_privs_t ospf6d_privs =
62 {
63 #if defined(QUAGGA_USER)
64   .user = QUAGGA_USER,
65 #endif
66 #if defined QUAGGA_GROUP
67   .group = QUAGGA_GROUP,
68 #endif
69 #ifdef VTY_GROUP
70   .vty_group = VTY_GROUP,
71 #endif
72   .caps_p = _caps_p,
73   .cap_num_p = 2,
74   .cap_num_i = 0
75 };
76
77 /* ospf6d options, we use GNU getopt library. */
78 struct option longopts[] = 
79 {
80   { "daemon",      no_argument,       NULL, 'd'},
81   { "config_file", required_argument, NULL, 'f'},
82   { "pid_file",    required_argument, NULL, 'i'},
83   { "socket",      required_argument, NULL, 'z'},
84   { "vty_addr",    required_argument, NULL, 'A'},
85   { "vty_port",    required_argument, NULL, 'P'},
86   { "user",        required_argument, NULL, 'u'},
87   { "group",       required_argument, NULL, 'g'},
88   { "version",     no_argument,       NULL, 'v'},
89   { "dryrun",      no_argument,       NULL, 'C'},
90   { "help",        no_argument,       NULL, 'h'},
91   { 0 }
92 };
93
94 /* Configuration file and directory. */
95 char config_default[] = SYSCONFDIR OSPF6_DEFAULT_CONFIG;
96
97 /* ospf6d program name. */
98 char *progname;
99
100 /* is daemon? */
101 int daemon_mode = 0;
102
103 /* Master of threads. */
104 struct thread_master *master;
105
106 /* Process ID saved for use by init system */
107 const char *pid_file = PATH_OSPF6D_PID;
108
109 /* Help information display. */
110 static void
111 usage (char *progname, 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\
118 Daemon which manages OSPF version 3.\n\n\
119 -d, --daemon       Runs in daemon mode\n\
120 -f, --config_file  Set configuration file name\n\
121 -i, --pid_file     Set process identifier file name\n\
122 -z, --socket       Set path of zebra socket\n\
123 -A, --vty_addr     Set vty's bind address\n\
124 -P, --vty_port     Set vty's port number\n\
125 -u, --user         User to run as\n\
126 -g, --group        Group to run as\n\
127 -v, --version      Print program version\n\
128 -C, --dryrun       Check configuration for validity and exit\n\
129 -h, --help         Display this help and exit\n\
130 \n\
131 Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
132     }
133
134   exit (status);
135 }
136
137 static void __attribute__ ((noreturn))
138 ospf6_exit (int status)
139 {
140   struct listnode *node;
141   struct interface *ifp;
142
143   if (ospf6)
144     ospf6_delete (ospf6);
145
146   for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp))
147     if (ifp->info != NULL)
148       ospf6_interface_delete(ifp->info);
149
150   ospf6_message_terminate ();
151   ospf6_asbr_terminate ();
152   ospf6_lsa_terminate ();
153
154   vrf_terminate ();
155   vty_terminate ();
156   cmd_terminate ();
157
158   if (zclient)
159     zclient_free (zclient);
160
161   if (master)
162     thread_master_free (master);
163
164   if (zlog_default)
165     closezlog (zlog_default);
166
167   exit (status);
168 }
169
170 /* SIGHUP handler. */
171 static void 
172 sighup (void)
173 {
174   zlog_info ("SIGHUP received");
175 }
176
177 /* SIGINT handler. */
178 static void
179 sigint (void)
180 {
181   zlog_notice ("Terminating on signal SIGINT");
182   ospf6_exit (0);
183 }
184
185 /* SIGTERM handler. */
186 static void
187 sigterm (void)
188 {
189   zlog_notice ("Terminating on signal SIGTERM");
190   ospf6_clean();
191   ospf6_exit (0);
192 }
193
194 /* SIGUSR1 handler. */
195 static void
196 sigusr1 (void)
197 {
198   zlog_info ("SIGUSR1 received");
199   zlog_rotate (NULL);
200 }
201
202 struct quagga_signal_t ospf6_signals[] =
203 {
204   {
205     .signal = SIGHUP,
206     .handler = &sighup,
207   },
208   {
209     .signal = SIGINT,
210     .handler = &sigint,
211   },
212   {
213     .signal = SIGTERM,
214     .handler = &sigterm,
215   },
216   {
217     .signal = SIGUSR1,
218     .handler = &sigusr1,
219   },
220 };
221
222 /* Main routine of ospf6d. Treatment of argument and starting ospf finite
223    state machine is handled here. */
224 int
225 main (int argc, char *argv[], char *envp[])
226 {
227   char *p;
228   int opt;
229   char *vty_addr = NULL;
230   int vty_port = 0;
231   char *config_file = NULL;
232   int dryrun = 0;
233
234   /* Set umask before anything for security */
235   umask (0027);
236
237   /* Preserve name of myself. */
238   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
239
240   /* Command line argument treatment. */
241   while (1) 
242     {
243       opt = getopt_long (argc, argv, "df:i:z:hp:A:P:u:g:vC", longopts, 0);
244     
245       if (opt == EOF)
246         break;
247
248       switch (opt) 
249         {
250         case 0:
251           break;
252         case 'd':
253           daemon_mode = 1;
254           break;
255         case 'f':
256           config_file = optarg;
257           break;
258         case 'A':
259           vty_addr = optarg;
260           break;
261         case 'i':
262           pid_file = optarg;
263           break;
264         case 'z':
265           zclient_serv_path_set (optarg);
266           break;
267         case 'P':
268          /* Deal with atoi() returning 0 on failure, and ospf6d not
269              listening on ospf6d port... */
270           if (strcmp(optarg, "0") == 0)
271             {
272               vty_port = 0;
273               break;
274             }
275           vty_port = atoi (optarg);
276           if (vty_port <= 0 || vty_port > 0xffff)
277             vty_port = OSPF6_VTY_PORT;
278           break;
279         case 'u':
280           ospf6d_privs.user = optarg;
281           break;
282         case 'g':
283           ospf6d_privs.group = optarg;
284           break;
285         case 'v':
286           print_version (progname);
287           exit (0);
288           break;
289         case 'C':
290           dryrun = 1;
291           break;
292         case 'h':
293           usage (progname, 0);
294           break;
295         default:
296           usage (progname, 1);
297           break;
298         }
299     }
300
301   if (geteuid () != 0)
302     {
303       errno = EPERM;
304       perror (progname);
305       exit (1);
306     }
307
308   /* thread master */
309   master = thread_master_create ();
310
311   /* Initializations. */
312   zlog_default = openzlog (progname, ZLOG_OSPF6,
313                            LOG_CONS|LOG_NDELAY|LOG_PID,
314                            LOG_DAEMON);
315   zprivs_init (&ospf6d_privs);
316   /* initialize zebra libraries */
317   signal_init (master, array_size(ospf6_signals), ospf6_signals);
318   cmd_init (1);
319   vty_init (master);
320   memory_init ();
321   vrf_init ();
322   access_list_init ();
323   prefix_list_init ();
324
325   /* initialize ospf6 */
326   ospf6_init ();
327
328   /* parse config file */
329   vty_read_config (config_file, config_default);
330
331   /* Start execution only if not in dry-run mode */
332   if (dryrun)
333     return(0);
334   
335   if (daemon_mode && daemon (0, 0) < 0)
336     {
337       zlog_err("OSPF6d daemon failed: %s", strerror(errno));
338       exit (1);
339     }
340
341   /* pid file create */
342   pid_output (pid_file);
343
344   /* Make ospf6 vty socket. */
345   if (!vty_port)
346     vty_port = OSPF6_VTY_PORT;
347   vty_serv_sock (vty_addr, vty_port, OSPF6_VTYSH_PATH);
348
349   /* Print start message */
350   zlog_notice ("OSPF6d (Quagga-%s ospf6d-%s) starts: vty@%d",
351                QUAGGA_VERSION, OSPF6_DAEMON_VERSION,vty_port);
352
353   /* Start finite state machine, here we go! */
354   thread_main (master);
355   
356   /* Log in case thread failed */
357   zlog_warn ("Thread failed");
358
359   /* Not reached. */
360   ospf6_exit (0);
361 }
362
363