1/* zebra daemon main routine.
2 * Copyright (C) 1997, 98 Kunihiro Ishiguro
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 Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include <lib/version.h>
25#include "getopt.h"
26#include "command.h"
27#include "thread.h"
28#include "filter.h"
29#include "memory.h"
30#include "prefix.h"
31#include "log.h"
32#include "plist.h"
33#include "privs.h"
34#include "sigevent.h"
35
36#include "zebra/rib.h"
37#include "zebra/zserv.h"
38#include "zebra/debug.h"
39#include "zebra/router-id.h"
40#include "zebra/irdp.h"
41#include "zebra/rtadv.h"
42#include "zebra/zebra_fpm.h"
43
44/* Zebra instance */
45struct zebra_t zebrad =
46{
47  .rtm_table_default = 0,
48};
49
50/* process id. */
51pid_t pid;
52
53/* Pacify zclient.o in libzebra, which expects this variable. */
54struct thread_master *master;
55
56/* Route retain mode flag. */
57int retain_mode = 0;
58
59/* Don't delete kernel route. */
60int keep_kernel_mode = 0;
61
62#ifdef HAVE_NETLINK
63/* Receive buffer size for netlink socket */
64u_int32_t nl_rcvbufsize = 0;
65#endif /* HAVE_NETLINK */
66
67/* Command line options. */
68struct option longopts[] =
69{
70  { "batch",       no_argument,       NULL, 'b'},
71  { "daemon",      no_argument,       NULL, 'd'},
72  { "keep_kernel", no_argument,       NULL, 'k'},
73  { "config_file", required_argument, NULL, 'f'},
74  { "pid_file",    required_argument, NULL, 'i'},
75  { "socket",      required_argument, NULL, 'z'},
76  { "help",        no_argument,       NULL, 'h'},
77  { "vty_addr",    required_argument, NULL, 'A'},
78  { "vty_port",    required_argument, NULL, 'P'},
79  { "retain",      no_argument,       NULL, 'r'},
80  { "dryrun",      no_argument,       NULL, 'C'},
81#ifdef HAVE_NETLINK
82  { "nl-bufsize",  required_argument, NULL, 's'},
83#endif /* HAVE_NETLINK */
84  { "user",        required_argument, NULL, 'u'},
85  { "group",       required_argument, NULL, 'g'},
86  { "version",     no_argument,       NULL, 'v'},
87  { 0 }
88};
89
90zebra_capabilities_t _caps_p [] =
91{
92  ZCAP_NET_ADMIN,
93  ZCAP_SYS_ADMIN,
94  ZCAP_NET_RAW,
95};
96
97/* zebra privileges to run with */
98struct zebra_privs_t zserv_privs =
99{
100#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
101  .user = QUAGGA_USER,
102  .group = QUAGGA_GROUP,
103#endif
104#ifdef VTY_GROUP
105  .vty_group = VTY_GROUP,
106#endif
107  .caps_p = _caps_p,
108  .cap_num_p = array_size(_caps_p),
109  .cap_num_i = 0
110};
111
112/* Default configuration file path. */
113char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
114
115/* Process ID saved for use by init system */
116const char *pid_file = PATH_ZEBRA_PID;
117
118/* Help information display. */
119static void
120usage (char *progname, int status)
121{
122  if (status != 0)
123    fprintf (stderr, "Try `%s --help' for more information.\n", progname);
124  else
125    {
126      printf ("Usage : %s [OPTION...]\n\n"\
127	      "Daemon which manages kernel routing table management and "\
128	      "redistribution between different routing protocols.\n\n"\
129	      "-b, --batch        Runs in batch mode\n"\
130	      "-d, --daemon       Runs in daemon mode\n"\
131	      "-f, --config_file  Set configuration file name\n"\
132	      "-i, --pid_file     Set process identifier file name\n"\
133	      "-z, --socket       Set path of zebra socket\n"\
134	      "-k, --keep_kernel  Don't delete old routes which installed by "\
135				  "zebra.\n"\
136	      "-C, --dryrun       Check configuration for validity and exit\n"\
137	      "-A, --vty_addr     Set vty's bind address\n"\
138	      "-P, --vty_port     Set vty's port number\n"\
139	      "-r, --retain       When program terminates, retain added route "\
140				  "by zebra.\n"\
141	      "-u, --user         User to run as\n"\
142	      "-g, --group	  Group to run as\n", progname);
143#ifdef HAVE_NETLINK
144      printf ("-s, --nl-bufsize   Set netlink receive buffer size\n");
145#endif /* HAVE_NETLINK */
146      printf ("-v, --version      Print program version\n"\
147	      "-h, --help         Display this help and exit\n"\
148	      "\n"\
149	      "Report bugs to %s\n", ZEBRA_BUG_ADDRESS);
150    }
151
152  exit (status);
153}
154
155/* SIGHUP handler. */
156static void
157sighup (void)
158{
159  zlog_info ("SIGHUP received");
160
161  /* Reload of config file. */
162  ;
163}
164
165/* SIGINT handler. */
166static void
167sigint (void)
168{
169  zlog_notice ("Terminating on signal");
170
171  if (!retain_mode)
172    rib_close ();
173#ifdef HAVE_IRDP
174  irdp_finish();
175#endif
176
177  exit (0);
178}
179
180/* SIGUSR1 handler. */
181static void
182sigusr1 (void)
183{
184  zlog_rotate (NULL);
185}
186
187struct quagga_signal_t zebra_signals[] =
188{
189  {
190    .signal = SIGHUP,
191    .handler = &sighup,
192  },
193  {
194    .signal = SIGUSR1,
195    .handler = &sigusr1,
196  },
197  {
198    .signal = SIGINT,
199    .handler = &sigint,
200  },
201  {
202    .signal = SIGTERM,
203    .handler = &sigint,
204  },
205};
206
207/* Main startup routine. */
208int
209main (int argc, char **argv)
210{
211  char *p;
212  char *vty_addr = NULL;
213  int vty_port = ZEBRA_VTY_PORT;
214  int dryrun = 0;
215  int batch_mode = 0;
216  int daemon_mode = 0;
217  char *config_file = NULL;
218  char *progname;
219  struct thread thread;
220  char *zserv_path = NULL;
221
222  /* Set umask before anything for security */
223  umask (0027);
224
225  /* preserve my name */
226  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
227
228  zlog_default = openzlog (progname, ZLOG_ZEBRA,
229			   LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
230
231  while (1)
232    {
233      int opt;
234
235#ifdef HAVE_NETLINK
236      opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vs:C", longopts, 0);
237#else
238      opt = getopt_long (argc, argv, "bdkf:i:z:hA:P:ru:g:vC", longopts, 0);
239#endif /* HAVE_NETLINK */
240
241      if (opt == EOF)
242	break;
243
244      switch (opt)
245	{
246	case 0:
247	  break;
248	case 'b':
249	  batch_mode = 1;
250	case 'd':
251	  daemon_mode = 1;
252	  break;
253	case 'k':
254	  keep_kernel_mode = 1;
255	  break;
256	case 'C':
257	  dryrun = 1;
258	  break;
259	case 'f':
260	  config_file = optarg;
261	  break;
262	case 'A':
263	  vty_addr = optarg;
264	  break;
265        case 'i':
266          pid_file = optarg;
267          break;
268	case 'z':
269	  zserv_path = optarg;
270	  break;
271	case 'P':
272	  /* Deal with atoi() returning 0 on failure, and zebra not
273	     listening on zebra port... */
274	  if (strcmp(optarg, "0") == 0)
275	    {
276	      vty_port = 0;
277	      break;
278	    }
279	  vty_port = atoi (optarg);
280	  if (vty_port <= 0 || vty_port > 0xffff)
281	    vty_port = ZEBRA_VTY_PORT;
282	  break;
283	case 'r':
284	  retain_mode = 1;
285	  break;
286#ifdef HAVE_NETLINK
287	case 's':
288	  nl_rcvbufsize = atoi (optarg);
289	  break;
290#endif /* HAVE_NETLINK */
291	case 'u':
292	  zserv_privs.user = optarg;
293	  break;
294	case 'g':
295	  zserv_privs.group = optarg;
296	  break;
297	case 'v':
298	  print_version (progname);
299	  exit (0);
300	  break;
301	case 'h':
302	  usage (progname, 0);
303	  break;
304	default:
305	  usage (progname, 1);
306	  break;
307	}
308    }
309
310  /* Make master thread emulator. */
311  zebrad.master = thread_master_create ();
312
313  /* privs initialise */
314  zprivs_init (&zserv_privs);
315
316  /* Vty related initialize. */
317  signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
318  cmd_init (1);
319  vty_init (zebrad.master);
320  memory_init ();
321
322  /* Zebra related initialize. */
323  zebra_init ();
324  rib_init ();
325  zebra_if_init ();
326  zebra_debug_init ();
327  router_id_init();
328  zebra_vty_init ();
329  access_list_init ();
330  prefix_list_init ();
331#ifdef RTADV
332  rtadv_init ();
333#endif
334#ifdef HAVE_IRDP
335  irdp_init();
336#endif
337
338  /* For debug purpose. */
339  /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */
340
341  /* Make kernel routing socket. */
342  kernel_init ();
343  interface_list ();
344  route_read ();
345
346#ifdef HAVE_SNMP
347  zebra_snmp_init ();
348#endif /* HAVE_SNMP */
349
350#ifdef HAVE_FPM
351  zfpm_init (zebrad.master, 1, 0);
352#else
353  zfpm_init (zebrad.master, 0, 0);
354#endif
355
356  /* Process the configuration file. Among other configuration
357  *  directives we can meet those installing static routes. Such
358  *  requests will not be executed immediately, but queued in
359  *  zebra->ribq structure until we enter the main execution loop.
360  *  The notifications from kernel will show originating PID equal
361  *  to that after daemon() completes (if ever called).
362  */
363  vty_read_config (config_file, config_default);
364
365  /* Don't start execution if we are in dry-run mode */
366  if (dryrun)
367    return(0);
368
369  /* Clean up rib. */
370  rib_weed_tables ();
371
372  /* Exit when zebra is working in batch mode. */
373  if (batch_mode)
374    exit (0);
375
376  /* Daemonize. */
377  if (daemon_mode && daemon (0, 0) < 0)
378    {
379      zlog_err("Zebra daemon failed: %s", strerror(errno));
380      exit (1);
381    }
382
383  /* Output pid of zebra. */
384  pid_output (pid_file);
385
386  /* After we have successfully acquired the pidfile, we can be sure
387  *  about being the only copy of zebra process, which is submitting
388  *  changes to the FIB.
389  *  Clean up zebra-originated routes. The requests will be sent to OS
390  *  immediately, so originating PID in notifications from kernel
391  *  will be equal to the current getpid(). To know about such routes,
392  * we have to have route_read() called before.
393  */
394  if (! keep_kernel_mode)
395    rib_sweep_route ();
396
397  /* Needed for BSD routing socket. */
398  pid = getpid ();
399
400  /* This must be done only after locking pidfile (bug #403). */
401  zebra_zserv_socket_init (zserv_path);
402
403  /* Make vty server socket. */
404  vty_serv_sock (vty_addr, vty_port, ZEBRA_VTYSH_PATH);
405
406  /* Print banner. */
407  zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port);
408
409  while (thread_fetch (zebrad.master, &thread))
410    thread_call (&thread);
411
412  /* Not reached... */
413  return 0;
414}
415