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