1 /*
2  * IS-IS Rout(e)ing protocol - isis_main.c
3  *
4  * Copyright (C) 2001,2002   Sampo Saaristo
5  *                           Tampere University of Technology
6  *                           Institute of Communications Engineering
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public Licenseas published by the Free
10  * Software Foundation; either version 2 of the License, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; see the file COPYING; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <zebra.h>
24 
25 #include "getopt.h"
26 #include "thread.h"
27 #include "log.h"
28 #include <lib/version.h>
29 #include "command.h"
30 #include "vty.h"
31 #include "memory.h"
32 #include "stream.h"
33 #include "if.h"
34 #include "privs.h"
35 #include "sigevent.h"
36 #include "filter.h"
37 #include "plist.h"
38 #include "zclient.h"
39 #include "vrf.h"
40 #include "qobj.h"
41 #include "libfrr.h"
42 #include "routemap.h"
43 
44 #include "isisd/isis_constants.h"
45 #include "isisd/isis_common.h"
46 #include "isisd/isis_flags.h"
47 #include "isisd/isis_circuit.h"
48 #include "isisd/isisd.h"
49 #include "isisd/isis_dynhn.h"
50 #include "isisd/isis_spf.h"
51 #include "isisd/isis_route.h"
52 #include "isisd/isis_routemap.h"
53 #include "isisd/isis_zebra.h"
54 #include "isisd/isis_te.h"
55 #include "isisd/isis_errors.h"
56 #include "isisd/isis_bfd.h"
57 #include "isisd/isis_lsp.h"
58 #include "isisd/isis_mt.h"
59 #include "isisd/fabricd.h"
60 #include "isisd/isis_nb.h"
61 
62 /* Default configuration file name */
63 #define ISISD_DEFAULT_CONFIG "isisd.conf"
64 /* Default vty port */
65 #define ISISD_VTY_PORT       2608
66 #define FABRICD_VTY_PORT     2618
67 
68 /* isisd privileges */
69 zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_SYS_ADMIN};
70 
71 struct zebra_privs_t isisd_privs = {
72 #if defined(FRR_USER)
73 	.user = FRR_USER,
74 #endif
75 #if defined FRR_GROUP
76 	.group = FRR_GROUP,
77 #endif
78 #ifdef VTY_GROUP
79 	.vty_group = VTY_GROUP,
80 #endif
81 	.caps_p = _caps_p,
82 	.cap_num_p = array_size(_caps_p),
83 	.cap_num_i = 0};
84 
85 /* isisd options */
86 static const struct option longopts[] = {
87 	{"int_num", required_argument, NULL, 'I'},
88 	{0}};
89 
90 /* Master of threads. */
91 struct thread_master *master;
92 
93 /*
94  * Prototypes.
95  */
96 void sighup(void);
97 void sigint(void);
98 void sigterm(void);
99 void sigusr1(void);
100 
101 
terminate(int i)102 static __attribute__((__noreturn__)) void terminate(int i)
103 {
104 	isis_terminate();
105 	isis_sr_term();
106 	isis_zebra_stop();
107 	exit(i);
108 }
109 
110 /*
111  * Signal handlers
112  */
113 #ifdef FABRICD
sighup(void)114 void sighup(void)
115 {
116 	zlog_notice("SIGHUP/reload is not implemented for fabricd");
117 	return;
118 }
119 #else
120 static struct frr_daemon_info isisd_di;
sighup(void)121 void sighup(void)
122 {
123 	zlog_info("SIGHUP received");
124 
125 	/* Reload config file. */
126 	vty_read_config(NULL, isisd_di.config_file, config_default);
127 }
128 
129 #endif
130 
sigint(void)131 __attribute__((__noreturn__)) void sigint(void)
132 {
133 	zlog_notice("Terminating on signal SIGINT");
134 	terminate(0);
135 }
136 
sigterm(void)137 __attribute__((__noreturn__)) void sigterm(void)
138 {
139 	zlog_notice("Terminating on signal SIGTERM");
140 	terminate(0);
141 }
142 
sigusr1(void)143 void sigusr1(void)
144 {
145 	zlog_debug("SIGUSR1 received");
146 	zlog_rotate();
147 }
148 
149 struct quagga_signal_t isisd_signals[] = {
150 	{
151 		.signal = SIGHUP,
152 		.handler = &sighup,
153 	},
154 	{
155 		.signal = SIGUSR1,
156 		.handler = &sigusr1,
157 	},
158 	{
159 		.signal = SIGINT,
160 		.handler = &sigint,
161 	},
162 	{
163 		.signal = SIGTERM,
164 		.handler = &sigterm,
165 	},
166 };
167 
168 
169 static const struct frr_yang_module_info *const isisd_yang_modules[] = {
170 	&frr_filter_info,
171 	&frr_interface_info,
172 #ifndef FABRICD
173 	&frr_isisd_info,
174 #endif /* ifndef FABRICD */
175 	&frr_route_map_info,
176 	&frr_vrf_info,
177 };
178 
179 #ifdef FABRICD
180 FRR_DAEMON_INFO(fabricd, OPEN_FABRIC, .vty_port = FABRICD_VTY_PORT,
181 
182 		.proghelp = "Implementation of the OpenFabric routing protocol.",
183 #else
184 FRR_DAEMON_INFO(isisd, ISIS, .vty_port = ISISD_VTY_PORT,
185 
186 		.proghelp = "Implementation of the IS-IS routing protocol.",
187 #endif
188 		.copyright =
189 			"Copyright (c) 2001-2002 Sampo Saaristo, Ofer Wald and Hannes Gredler",
190 
191 		.signals = isisd_signals,
192 		.n_signals = array_size(isisd_signals),
193 
194 		.privs = &isisd_privs, .yang_modules = isisd_yang_modules,
195 		.n_yang_modules = array_size(isisd_yang_modules), )
196 
197 /*
198  * Main routine of isisd. Parse arguments and handle IS-IS state machine.
199  */
main(int argc,char ** argv,char ** envp)200 int main(int argc, char **argv, char **envp)
201 {
202 	int opt;
203 	int instance = 1;
204 
205 #ifdef FABRICD
206 	frr_preinit(&fabricd_di, argc, argv);
207 #else
208 	frr_preinit(&isisd_di, argc, argv);
209 #endif
210 	frr_opt_add(
211 		"I:", longopts,
212 		"  -I, --int_num      Set instance number (label-manager)\n");
213 
214 	/* Command line argument treatment. */
215 	while (1) {
216 		opt = frr_getopt(argc, argv, NULL);
217 
218 		if (opt == EOF)
219 			break;
220 
221 		switch (opt) {
222 		case 0:
223 			break;
224 		case 'I':
225 			instance = atoi(optarg);
226 			if (instance < 1 || instance > (unsigned short)-1)
227 				zlog_err("Instance %i out of range (1..%u)",
228 					 instance, (unsigned short)-1);
229 			break;
230 		default:
231 			frr_help_exit(1);
232 			break;
233 		}
234 	}
235 
236 	/* thread master */
237 	isis_master_init(frr_init());
238 	master = im->master;
239 	/*
240 	 *  initializations
241 	 */
242 	isis_error_init();
243 	access_list_init();
244 	isis_vrf_init();
245 	prefix_list_init();
246 	isis_init();
247 	isis_circuit_init();
248 #ifdef FABRICD
249 	isis_vty_daemon_init();
250 #endif /* FABRICD */
251 #ifndef FABRICD
252 	isis_cli_init();
253 #endif /* ifdef FABRICD */
254 	isis_spf_init();
255 	isis_redist_init();
256 	isis_route_map_init();
257 	isis_mpls_te_init();
258 	isis_sr_init();
259 	lsp_init();
260 	mt_init();
261 
262 	/* create the global 'isis' instance */
263 	isis_global_instance_create(VRF_DEFAULT_NAME);
264 
265 	isis_zebra_init(master, instance);
266 	isis_bfd_init();
267 	fabricd_init();
268 
269 	frr_config_fork();
270 	frr_run(master);
271 
272 	/* Not reached. */
273 	exit(0);
274 }
275