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