1: /* main routine.
2: * Copyright (C) 1997, 98 Kunihiro Ishiguro
3: *
4: * GNU Zebra is free software; you can redistribute it and/or modify it
5: * under the terms of the GNU General Public License as published by the
6: * Free Software Foundation; either version 2, or (at your option) any
7: * later version.
8: *
9: * GNU Zebra is distributed in the hope that it will be useful, but
10: * WITHOUT ANY WARRANTY; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12: * General Public License for more details.
13: *
14: * You should have received a copy of the GNU General Public License
15: * along with GNU Zebra; see the file COPYING. If not, write to the Free
16: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17: * 02111-1307, USA.
18: */
19:
20: #include <zebra.h>
21:
22: #include <lib/version.h>
23: #include "getopt.h"
24: #include "command.h"
25: #include "thread.h"
26: #include "filter.h"
27: #include "memory.h"
28: #include "prefix.h"
29: #include "log.h"
30: #include "privs.h"
31: #include "sigevent.h"
32: #include "vrf.h"
33:
34: #include "zebra/rib.h"
35: #include "zebra/zserv.h"
36: #include "zebra/debug.h"
37: #include "zebra/router-id.h"
38: #include "zebra/interface.h"
39:
40: /* Zebra instance */
41: struct zebra_t zebrad =
42: {
43: .rtm_table_default = 0,
44: };
45:
46: /* process id. */
47: pid_t pid;
48:
49: /* zebra_rib's workqueue hold time. Private export for use by test code only */
50: extern int rib_process_hold_time;
51:
52: /* Pacify zclient.o in libzebra, which expects this variable. */
53: struct thread_master *master;
54:
55: /* Command line options. */
56: struct option longopts[] =
57: {
58: { "batch", no_argument, NULL, 'b'},
59: { "daemon", no_argument, NULL, 'd'},
60: { "config_file", required_argument, NULL, 'f'},
61: { "help", no_argument, NULL, 'h'},
62: { "vty_addr", required_argument, NULL, 'A'},
63: { "vty_port", required_argument, NULL, 'P'},
64: { "version", no_argument, NULL, 'v'},
65: { "rib_hold", required_argument, NULL, 'r'},
66: { 0 }
67: };
68:
69: zebra_capabilities_t _caps_p [] =
70: {
71: ZCAP_NET_ADMIN,
72: ZCAP_SYS_ADMIN,
73: ZCAP_NET_RAW,
74: };
75:
76: /* Default configuration file path. */
77: char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
78:
79: /* Process ID saved for use by init system */
80: const char *pid_file = PATH_ZEBRA_PID;
81:
82: /* Help information display. */
83: static void
84: usage (char *progname, int status)
85: {
86: if (status != 0)
87: fprintf (stderr, "Try `%s --help' for more information.\n", progname);
88: else
89: {
90: printf ("Usage : %s [OPTION...]\n\n"\
91: "Daemon which manages kernel routing table management and "\
92: "redistribution between different routing protocols.\n\n"\
93: "-b, --batch Runs in batch mode\n"\
94: "-d, --daemon Runs in daemon mode\n"\
95: "-f, --config_file Set configuration file name\n"\
96: "-A, --vty_addr Set vty's bind address\n"\
97: "-P, --vty_port Set vty's port number\n"\
98: "-r, --rib_hold Set rib-queue hold time\n"\
99: "-v, --version Print program version\n"\
100: "-h, --help Display this help and exit\n"\
101: "\n"\
102: "Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
103: }
104:
105: exit (status);
106: }
107:
108: static ifindex_t test_ifindex = 0;
109:
110: /* testrib commands */
111: DEFUN (test_interface_state,
112: test_interface_state_cmd,
113: "state (up|down)",
114: "configure interface\n"
115: "up\n"
116: "down\n")
117: {
118: struct interface *ifp;
119: if (argc < 1)
120: return CMD_WARNING;
121:
122: ifp = vty->index;
123: if (ifp->ifindex == IFINDEX_INTERNAL)
124: {
125: ifp->ifindex = ++test_ifindex;
126: ifp->mtu = 1500;
127: ifp->flags = IFF_BROADCAST|IFF_MULTICAST;
128: }
129:
130: switch (argv[0][0])
131: {
132: case 'u':
133: SET_FLAG (ifp->flags, IFF_UP);
134: if_add_update (ifp);
135: printf ("up\n");
136: break;
137: case 'd':
138: UNSET_FLAG (ifp->flags, IFF_UP);
139: if_delete_update (ifp);
140: printf ("down\n");
141: break;
142: default:
143: return CMD_WARNING;
144: }
145: return CMD_SUCCESS;
146: }
147:
148: static void
149: test_cmd_init (void)
150: {
151: install_element (INTERFACE_NODE, &test_interface_state_cmd);
152: }
153:
154: /* SIGHUP handler. */
155: static void
156: sighup (void)
157: {
158: zlog_info ("SIGHUP received");
159:
160: /* Reload of config file. */
161: ;
162: }
163:
164: /* SIGINT handler. */
165: static void
166: sigint (void)
167: {
168: zlog_notice ("Terminating on signal");
169:
170: exit (0);
171: }
172:
173: /* SIGUSR1 handler. */
174: static void
175: sigusr1 (void)
176: {
177: zlog_rotate (NULL);
178: }
179:
180: struct quagga_signal_t zebra_signals[] =
181: {
182: {
183: .signal = SIGHUP,
184: .handler = &sighup,
185: },
186: {
187: .signal = SIGUSR1,
188: .handler = &sigusr1,
189: },
190: {
191: .signal = SIGINT,
192: .handler = &sigint,
193: },
194: {
195: .signal = SIGTERM,
196: .handler = &sigint,
197: },
198: };
199:
200: /* Callback upon creating a new VRF. */
201: static int
202: zebra_vrf_new (vrf_id_t vrf_id, void **info)
203: {
204: struct zebra_vrf *zvrf = *info;
205:
206: if (! zvrf)
207: {
208: zvrf = zebra_vrf_alloc (vrf_id);
209: *info = (void *)zvrf;
210: }
211:
212: return 0;
213: }
214:
215: /* Callback upon enabling a VRF. */
216: static int
217: zebra_vrf_enable (vrf_id_t vrf_id, void **info)
218: {
219: struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
220:
221: assert (zvrf);
222:
223: kernel_init (zvrf);
224: route_read (zvrf);
225:
226: return 0;
227: }
228:
229: /* Callback upon disabling a VRF. */
230: static int
231: zebra_vrf_disable (vrf_id_t vrf_id, void **info)
232: {
233: struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
234: struct listnode *list_node;
235: struct interface *ifp;
236:
237: assert (zvrf);
238:
239: rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
240: rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
241:
242: for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), list_node, ifp))
243: {
244: int operative = if_is_operative (ifp);
245: UNSET_FLAG (ifp->flags, IFF_UP);
246: if (operative)
247: if_down (ifp);
248: }
249:
250: kernel_terminate (zvrf);
251:
252: return 0;
253: }
254:
255: /* Zebra VRF initialization. */
256: static void
257: zebra_vrf_init (void)
258: {
259: vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
260: vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
261: vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
262: vrf_init ();
263: }
264:
265: /* Main startup routine. */
266: int
267: main (int argc, char **argv)
268: {
269: char *p;
270: char *vty_addr = NULL;
271: int vty_port = 0;
272: int batch_mode = 0;
273: int daemon_mode = 0;
274: char *config_file = NULL;
275: char *progname;
276: struct thread thread;
277:
278: /* Set umask before anything for security */
279: umask (0027);
280:
281: /* preserve my name */
282: progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
283:
284: zlog_default = openzlog (progname, ZLOG_ZEBRA,
285: LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
286:
287: while (1)
288: {
289: int opt;
290:
291: opt = getopt_long (argc, argv, "bdf:hA:P:r:v", longopts, 0);
292:
293: if (opt == EOF)
294: break;
295:
296: switch (opt)
297: {
298: case 0:
299: break;
300: case 'b':
301: batch_mode = 1;
302: case 'd':
303: daemon_mode = 1;
304: break;
305: case 'f':
306: config_file = optarg;
307: break;
308: case 'A':
309: vty_addr = optarg;
310: break;
311: case 'P':
312: /* Deal with atoi() returning 0 on failure, and zebra not
313: listening on zebra port... */
314: if (strcmp(optarg, "0") == 0)
315: {
316: vty_port = 0;
317: break;
318: }
319: vty_port = atoi (optarg);
320: break;
321: case 'r':
322: rib_process_hold_time = atoi(optarg);
323: break;
324: case 'v':
325: print_version (progname);
326: exit (0);
327: break;
328: case 'h':
329: usage (progname, 0);
330: break;
331: default:
332: usage (progname, 1);
333: break;
334: }
335: }
336:
337: /* port and conf file mandatory */
338: if (!vty_port || !config_file)
339: {
340: fprintf (stderr, "Error: --vty_port and --config_file arguments"
341: " are both required\n");
342: usage (progname, 1);
343: }
344:
345: /* Make master thread emulator. */
346: zebrad.master = thread_master_create ();
347:
348: /* Vty related initialize. */
349: signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
350: cmd_init (1);
351: vty_init (zebrad.master);
352: memory_init ();
353: zebra_debug_init ();
354: zebra_if_init ();
355: test_cmd_init ();
356:
357: /* Zebra related initialize. */
358: rib_init ();
359: access_list_init ();
360:
361: /* Make kernel routing socket. */
362: zebra_vrf_init ();
363: zebra_vty_init();
364:
365: /* Configuration file read*/
366: vty_read_config (config_file, config_default);
367:
368: /* Clean up rib. */
369: rib_weed_tables ();
370:
371: /* Exit when zebra is working in batch mode. */
372: if (batch_mode)
373: exit (0);
374:
375: /* Daemonize. */
376: if (daemon_mode && daemon (0, 0) < 0)
377: {
378: perror("daemon start failed");
379: exit (1);
380: }
381:
382: /* Needed for BSD routing socket. */
383: pid = getpid ();
384:
385: /* Make vty server socket. */
386: vty_serv_sock (vty_addr, vty_port, "/tmp/test_zebra");
387:
388: /* Print banner. */
389: zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port);
390:
391: while (thread_fetch (zebrad.master, &thread))
392: thread_call (&thread);
393:
394: /* Not reached... */
395: return 0;
396: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>