1/* Main routine of bgpd.
2   Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING.  If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA.  */
20
21#include <zebra.h>
22
23#include "vector.h"
24#include "vty.h"
25#include "command.h"
26#include "getopt.h"
27#include "thread.h"
28#include <lib/version.h>
29#include "memory.h"
30#include "prefix.h"
31#include "log.h"
32#include "privs.h"
33#include "sigevent.h"
34#include "zclient.h"
35#include "routemap.h"
36#include "filter.h"
37#include "plist.h"
38#include "stream.h"
39
40#include "bgpd/bgpd.h"
41#include "bgpd/bgp_attr.h"
42#include "bgpd/bgp_mplsvpn.h"
43#include "bgpd/bgp_aspath.h"
44#include "bgpd/bgp_dump.h"
45#include "bgpd/bgp_route.h"
46#include "bgpd/bgp_nexthop.h"
47#include "bgpd/bgp_regex.h"
48#include "bgpd/bgp_clist.h"
49#include "bgpd/bgp_debug.h"
50#include "bgpd/bgp_filter.h"
51#include "bgpd/bgp_zebra.h"
52
53/* bgpd options, we use GNU getopt library. */
54static const struct option longopts[] =
55{
56  { "daemon",      no_argument,       NULL, 'd'},
57  { "config_file", required_argument, NULL, 'f'},
58  { "pid_file",    required_argument, NULL, 'i'},
59  { "socket",      required_argument, NULL, 'z'},
60  { "bgp_port",    required_argument, NULL, 'p'},
61  { "listenon",    required_argument, NULL, 'l'},
62  { "vty_addr",    required_argument, NULL, 'A'},
63  { "vty_port",    required_argument, NULL, 'P'},
64  { "retain",      no_argument,       NULL, 'r'},
65  { "no_kernel",   no_argument,       NULL, 'n'},
66  { "user",        required_argument, NULL, 'u'},
67  { "group",       required_argument, NULL, 'g'},
68  { "version",     no_argument,       NULL, 'v'},
69  { "dryrun",      no_argument,       NULL, 'C'},
70  { "help",        no_argument,       NULL, 'h'},
71  { 0 }
72};
73
74/* signal definitions */
75void sighup (void);
76void sigint (void);
77void sigusr1 (void);
78
79static void bgp_exit (int);
80
81static struct quagga_signal_t bgp_signals[] =
82{
83  {
84    .signal = SIGHUP,
85    .handler = &sighup,
86  },
87  {
88    .signal = SIGUSR1,
89    .handler = &sigusr1,
90  },
91  {
92    .signal = SIGINT,
93    .handler = &sigint,
94  },
95  {
96    .signal = SIGTERM,
97    .handler = &sigint,
98  },
99};
100
101/* Configuration file and directory. */
102char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
103
104/* Route retain mode flag. */
105static int retain_mode = 0;
106
107/* Master of threads. */
108struct thread_master *master;
109
110/* Manually specified configuration file name.  */
111char *config_file = NULL;
112
113/* Process ID saved for use by init system */
114static const char *pid_file = PATH_BGPD_PID;
115
116/* VTY port number and address.  */
117int vty_port = BGP_VTY_PORT;
118char *vty_addr = NULL;
119
120/* privileges */
121static zebra_capabilities_t _caps_p [] =
122{
123    ZCAP_BIND,
124    ZCAP_NET_RAW,
125    ZCAP_NET_ADMIN,
126};
127
128struct zebra_privs_t bgpd_privs =
129{
130#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
131  .user = QUAGGA_USER,
132  .group = QUAGGA_GROUP,
133#endif
134#ifdef VTY_GROUP
135  .vty_group = VTY_GROUP,
136#endif
137  .caps_p = _caps_p,
138  .cap_num_p = array_size(_caps_p),
139  .cap_num_i = 0,
140};
141
142/* Help information display. */
143static void
144usage (char *progname, int status)
145{
146  if (status != 0)
147    fprintf (stderr, "Try `%s --help' for more information.\n", progname);
148  else
149    {
150      printf ("Usage : %s [OPTION...]\n\n\
151Daemon which manages kernel routing table management and \
152redistribution between different routing protocols.\n\n\
153-d, --daemon       Runs in daemon mode\n\
154-f, --config_file  Set configuration file name\n\
155-i, --pid_file     Set process identifier file name\n\
156-z, --socket       Set path of zebra socket\n\
157-p, --bgp_port     Set bgp protocol's port number\n\
158-l, --listenon     Listen on specified address (implies -n)\n\
159-A, --vty_addr     Set vty's bind address\n\
160-P, --vty_port     Set vty's port number\n\
161-r, --retain       When program terminates, retain added route by bgpd.\n\
162-n, --no_kernel    Do not install route to kernel.\n\
163-u, --user         User to run as\n\
164-g, --group        Group to run as\n\
165-v, --version      Print program version\n\
166-C, --dryrun       Check configuration for validity and exit\n\
167-h, --help         Display this help and exit\n\
168\n\
169Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
170    }
171
172  exit (status);
173}
174
175/* SIGHUP handler. */
176void
177sighup (void)
178{
179  zlog (NULL, LOG_INFO, "SIGHUP received");
180
181  /* Terminate all thread. */
182  bgp_terminate ();
183  bgp_reset ();
184  zlog_info ("bgpd restarting!");
185
186  /* Reload config file. */
187  vty_read_config (config_file, config_default);
188
189  /* Create VTY's socket */
190  vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
191
192  /* Try to return to normal operation. */
193}
194
195/* SIGINT handler. */
196void
197sigint (void)
198{
199  zlog_notice ("Terminating on signal");
200
201  if (! retain_mode)
202    bgp_terminate ();
203
204  zprivs_terminate (&bgpd_privs);
205  bgp_exit (0);
206}
207
208/* SIGUSR1 handler. */
209void
210sigusr1 (void)
211{
212  zlog_rotate (NULL);
213}
214
215/*
216  Try to free up allocations we know about so that diagnostic tools such as
217  valgrind are able to better illuminate leaks.
218
219  Zebra route removal and protocol teardown are not meant to be done here.
220  For example, "retain_mode" may be set.
221*/
222static void
223bgp_exit (int status)
224{
225  struct bgp *bgp;
226  struct listnode *node, *nnode;
227  int *socket;
228  struct interface *ifp;
229  extern struct zclient *zclient;
230  extern struct zclient *zlookup;
231
232  /* it only makes sense for this to be called on a clean exit */
233  assert (status == 0);
234
235  /* reverse bgp_master_init */
236  for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
237    bgp_delete (bgp);
238  list_free (bm->bgp);
239
240  /* reverse bgp_master_init */
241  for (ALL_LIST_ELEMENTS_RO(bm->listen_sockets, node, socket))
242    {
243      if (close ((int)(long)socket) == -1)
244        zlog_err ("close (%d): %s", (int)(long)socket, safe_strerror (errno));
245    }
246  list_delete (bm->listen_sockets);
247
248  /* reverse bgp_zebra_init/if_init */
249  if (retain_mode)
250    if_add_hook (IF_DELETE_HOOK, NULL);
251  for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
252    {
253      struct listnode *c_node, *c_nnode;
254      struct connected *c;
255
256      for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
257        bgp_connected_delete (c);
258
259      if_delete (ifp);
260    }
261  list_free (iflist);
262
263  /* reverse bgp_attr_init */
264  bgp_attr_finish ();
265
266  /* reverse bgp_dump_init */
267  bgp_dump_finish ();
268
269  /* reverse bgp_route_init */
270  bgp_route_finish ();
271
272  /* reverse bgp_route_map_init/route_map_init */
273  route_map_finish ();
274
275  /* reverse bgp_scan_init */
276  bgp_scan_finish ();
277
278  /* reverse access_list_init */
279  access_list_add_hook (NULL);
280  access_list_delete_hook (NULL);
281  access_list_reset ();
282
283  /* reverse bgp_filter_init */
284  as_list_add_hook (NULL);
285  as_list_delete_hook (NULL);
286  bgp_filter_reset ();
287
288  /* reverse prefix_list_init */
289  prefix_list_add_hook (NULL);
290  prefix_list_delete_hook (NULL);
291  prefix_list_reset ();
292
293  /* reverse community_list_init */
294  community_list_terminate (bgp_clist);
295
296  cmd_terminate ();
297  vty_terminate ();
298  if (zclient)
299    zclient_free (zclient);
300  if (zlookup)
301    zclient_free (zlookup);
302  if (bgp_nexthop_buf)
303    stream_free (bgp_nexthop_buf);
304
305  /* reverse bgp_master_init */
306  if (master)
307    thread_master_free (master);
308
309  if (zlog_default)
310    closezlog (zlog_default);
311
312  if (CONF_BGP_DEBUG (normal, NORMAL))
313    log_memstats_stderr ("bgpd");
314
315  exit (status);
316}
317
318/* Main routine of bgpd. Treatment of argument and start bgp finite
319   state machine is handled at here. */
320int
321main (int argc, char **argv)
322{
323  char *p;
324  int opt;
325  int daemon_mode = 0;
326  int dryrun = 0;
327  char *progname;
328  struct thread thread;
329  int tmp_port;
330
331  /* Set umask before anything for security */
332  umask (0027);
333
334  /* Preserve name of myself. */
335  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
336
337  zlog_default = openzlog (progname, ZLOG_BGP,
338			   LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
339
340  /* BGP master init. */
341  bgp_master_init ();
342
343  /* Command line argument treatment. */
344  while (1)
345    {
346      opt = getopt_long (argc, argv, "df:i:z:hp:l:A:P:rnu:g:vC", longopts, 0);
347
348      if (opt == EOF)
349	break;
350
351      switch (opt)
352	{
353	case 0:
354	  break;
355	case 'd':
356	  daemon_mode = 1;
357	  break;
358	case 'f':
359	  config_file = optarg;
360	  break;
361        case 'i':
362          pid_file = optarg;
363          break;
364	case 'z':
365	  zclient_serv_path_set (optarg);
366	  break;
367	case 'p':
368	  tmp_port = atoi (optarg);
369	  if (tmp_port <= 0 || tmp_port > 0xffff)
370	    bm->port = BGP_PORT_DEFAULT;
371	  else
372	    bm->port = tmp_port;
373	  break;
374	case 'A':
375	  vty_addr = optarg;
376	  break;
377	case 'P':
378          /* Deal with atoi() returning 0 on failure, and bgpd not
379             listening on bgp port... */
380          if (strcmp(optarg, "0") == 0)
381            {
382              vty_port = 0;
383              break;
384            }
385          vty_port = atoi (optarg);
386	  if (vty_port <= 0 || vty_port > 0xffff)
387	    vty_port = BGP_VTY_PORT;
388	  break;
389	case 'r':
390	  retain_mode = 1;
391	  break;
392	case 'l':
393	  bm->address = optarg;
394	  /* listenon implies -n */
395	case 'n':
396	  bgp_option_set (BGP_OPT_NO_FIB);
397	  break;
398	case 'u':
399	  bgpd_privs.user = optarg;
400	  break;
401	case 'g':
402	  bgpd_privs.group = optarg;
403	  break;
404	case 'v':
405	  print_version (progname);
406	  exit (0);
407	  break;
408	case 'C':
409	  dryrun = 1;
410	  break;
411	case 'h':
412	  usage (progname, 0);
413	  break;
414	default:
415	  usage (progname, 1);
416	  break;
417	}
418    }
419
420  /* Make thread master. */
421  master = bm->master;
422
423  /* Initializations. */
424  srand (time (NULL));
425  signal_init (master, array_size(bgp_signals), bgp_signals);
426  zprivs_init (&bgpd_privs);
427  cmd_init (1);
428  vty_init (master);
429  memory_init ();
430
431  /* BGP related initialization.  */
432  bgp_init ();
433
434  /* Parse config file. */
435  vty_read_config (config_file, config_default);
436
437  /* Start execution only if not in dry-run mode */
438  if(dryrun)
439    return(0);
440
441  /* Turn into daemon if daemon_mode is set. */
442  if (daemon_mode && daemon (0, 0) < 0)
443    {
444      zlog_err("BGPd daemon failed: %s", strerror(errno));
445      return (1);
446    }
447
448
449  /* Process ID file creation. */
450  pid_output (pid_file);
451
452  /* Make bgp vty socket. */
453  vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
454
455  /* Print banner. */
456  zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", QUAGGA_VERSION,
457	       vty_port,
458	       (bm->address ? bm->address : "<all>"),
459	       bm->port);
460
461  /* Start finite state machine, here we go! */
462  while (thread_fetch (master, &thread))
463    thread_call (&thread);
464
465  /* Not reached. */
466  return (0);
467}
468