]> git.proxmox.com Git - mirror_frr.git/blob - zebra/test_main.c
zebra, lib/memtypes.c: the netlink sockets work per VRF
[mirror_frr.git] / zebra / test_main.c
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 /* Allow non-quagga entities to delete quagga routes */
50 int allow_delete = 0;
51
52 /* zebra_rib's workqueue hold time. Private export for use by test code only */
53 extern int rib_process_hold_time;
54
55 /* Pacify zclient.o in libzebra, which expects this variable. */
56 struct thread_master *master;
57
58 /* Command line options. */
59 struct option longopts[] =
60 {
61 { "batch", no_argument, NULL, 'b'},
62 { "daemon", no_argument, NULL, 'd'},
63 { "allow_delete", no_argument, NULL, 'a'},
64 { "config_file", required_argument, NULL, 'f'},
65 { "help", no_argument, NULL, 'h'},
66 { "vty_addr", required_argument, NULL, 'A'},
67 { "vty_port", required_argument, NULL, 'P'},
68 { "version", no_argument, NULL, 'v'},
69 { "rib_hold", required_argument, NULL, 'r'},
70 { 0 }
71 };
72
73 zebra_capabilities_t _caps_p [] =
74 {
75 ZCAP_NET_ADMIN,
76 ZCAP_SYS_ADMIN,
77 ZCAP_NET_RAW,
78 };
79
80 /* Default configuration file path. */
81 char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
82
83 /* Process ID saved for use by init system */
84 const char *pid_file = PATH_ZEBRA_PID;
85
86 /* Help information display. */
87 static void
88 usage (char *progname, int status)
89 {
90 if (status != 0)
91 fprintf (stderr, "Try `%s --help' for more information.\n", progname);
92 else
93 {
94 printf ("Usage : %s [OPTION...]\n\n"\
95 "Daemon which manages kernel routing table management and "\
96 "redistribution between different routing protocols.\n\n"\
97 "-b, --batch Runs in batch mode\n"\
98 "-d, --daemon Runs in daemon mode\n"\
99 "-a, --allow_delete Allow other processes to delete Quagga Routes\n" \
100 "-f, --config_file Set configuration file name\n"\
101 "-A, --vty_addr Set vty's bind address\n"\
102 "-P, --vty_port Set vty's port number\n"\
103 "-r, --rib_hold Set rib-queue hold time\n"\
104 "-v, --version Print program version\n"\
105 "-h, --help Display this help and exit\n"\
106 "\n"\
107 "Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
108 }
109
110 exit (status);
111 }
112
113 static unsigned int test_ifindex = 0;
114
115 /* testrib commands */
116 DEFUN (test_interface_state,
117 test_interface_state_cmd,
118 "state (up|down)",
119 "configure interface\n"
120 "up\n"
121 "down\n")
122 {
123 struct interface *ifp;
124 if (argc < 1)
125 return CMD_WARNING;
126
127 ifp = vty->index;
128 if (ifp->ifindex == IFINDEX_INTERNAL)
129 {
130 ifp->ifindex = ++test_ifindex;
131 ifp->mtu = 1500;
132 ifp->flags = IFF_BROADCAST|IFF_MULTICAST;
133 }
134
135 switch (argv[0][0])
136 {
137 case 'u':
138 SET_FLAG (ifp->flags, IFF_UP);
139 if_add_update (ifp);
140 printf ("up\n");
141 break;
142 case 'd':
143 UNSET_FLAG (ifp->flags, IFF_UP);
144 if_delete_update (ifp);
145 printf ("down\n");
146 break;
147 default:
148 return CMD_WARNING;
149 }
150 return CMD_SUCCESS;
151 }
152
153 static void
154 test_cmd_init (void)
155 {
156 install_element (INTERFACE_NODE, &test_interface_state_cmd);
157 }
158
159 /* SIGHUP handler. */
160 static void
161 sighup (void)
162 {
163 zlog_info ("SIGHUP received");
164
165 /* Reload of config file. */
166 ;
167 }
168
169 /* SIGINT handler. */
170 static void
171 sigint (void)
172 {
173 zlog_notice ("Terminating on signal");
174
175 exit (0);
176 }
177
178 /* SIGUSR1 handler. */
179 static void
180 sigusr1 (void)
181 {
182 zlog_rotate (NULL);
183 }
184
185 struct quagga_signal_t zebra_signals[] =
186 {
187 {
188 .signal = SIGHUP,
189 .handler = &sighup,
190 },
191 {
192 .signal = SIGUSR1,
193 .handler = &sigusr1,
194 },
195 {
196 .signal = SIGINT,
197 .handler = &sigint,
198 },
199 {
200 .signal = SIGTERM,
201 .handler = &sigint,
202 },
203 };
204
205 /* Callback upon creating a new VRF. */
206 static int
207 zebra_vrf_new (vrf_id_t vrf_id, void **info)
208 {
209 struct zebra_vrf *zvrf = *info;
210
211 if (! zvrf)
212 {
213 zvrf = zebra_vrf_alloc (vrf_id);
214 *info = (void *)zvrf;
215 }
216
217 return 0;
218 }
219
220 /* Callback upon enabling a VRF. */
221 static int
222 zebra_vrf_enable (vrf_id_t vrf_id, void **info)
223 {
224 struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
225
226 assert (zvrf);
227
228 kernel_init (zvrf);
229 route_read (zvrf);
230
231 return 0;
232 }
233
234 /* Callback upon disabling a VRF. */
235 static int
236 zebra_vrf_disable (vrf_id_t vrf_id, void **info)
237 {
238 struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
239 struct listnode *list_node;
240 struct interface *ifp;
241
242 assert (zvrf);
243
244 rib_close_table (zvrf->table[AFI_IP][SAFI_UNICAST]);
245 rib_close_table (zvrf->table[AFI_IP6][SAFI_UNICAST]);
246
247 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), list_node, ifp))
248 {
249 int operative = if_is_operative (ifp);
250 UNSET_FLAG (ifp->flags, IFF_UP);
251 if (operative)
252 if_down (ifp);
253 }
254
255 kernel_terminate (zvrf);
256
257 return 0;
258 }
259
260 /* Zebra VRF initialization. */
261 static void
262 zebra_vrf_init (void)
263 {
264 vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
265 vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
266 vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
267 vrf_init ();
268 }
269
270 /* Main startup routine. */
271 int
272 main (int argc, char **argv)
273 {
274 char *p;
275 char *vty_addr = NULL;
276 int vty_port = 0;
277 int batch_mode = 0;
278 int daemon_mode = 0;
279 char *config_file = NULL;
280 char *progname;
281 struct thread thread;
282
283 /* Set umask before anything for security */
284 umask (0027);
285
286 /* preserve my name */
287 progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
288
289 zlog_default = openzlog (progname, ZLOG_ZEBRA, 0,
290 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
291
292 while (1)
293 {
294 int opt;
295
296 opt = getopt_long (argc, argv, "bdaf:hA:P:r:v", longopts, 0);
297
298 if (opt == EOF)
299 break;
300
301 switch (opt)
302 {
303 case 0:
304 break;
305 case 'b':
306 batch_mode = 1;
307 case 'd':
308 daemon_mode = 1;
309 break;
310 case 'a':
311 allow_delete =1;
312 break;
313 case 'f':
314 config_file = optarg;
315 break;
316 case 'A':
317 vty_addr = optarg;
318 break;
319 case 'P':
320 /* Deal with atoi() returning 0 on failure, and zebra not
321 listening on zebra port... */
322 if (strcmp(optarg, "0") == 0)
323 {
324 vty_port = 0;
325 break;
326 }
327 vty_port = atoi (optarg);
328 break;
329 case 'r':
330 rib_process_hold_time = atoi(optarg);
331 break;
332 case 'v':
333 print_version (progname);
334 exit (0);
335 break;
336 case 'h':
337 usage (progname, 0);
338 break;
339 default:
340 usage (progname, 1);
341 break;
342 }
343 }
344
345 /* port and conf file mandatory */
346 if (!vty_port || !config_file)
347 {
348 fprintf (stderr, "Error: --vty_port and --config_file arguments"
349 " are both required\n");
350 usage (progname, 1);
351 }
352
353 /* Make master thread emulator. */
354 zebrad.master = thread_master_create ();
355
356 /* Vty related initialize. */
357 signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
358 cmd_init (1);
359 vty_init (zebrad.master);
360 memory_init ();
361 zebra_debug_init ();
362 zebra_if_init ();
363 test_cmd_init ();
364
365 /* Zebra related initialize. */
366 rib_init ();
367 access_list_init ();
368
369 /* Make kernel routing socket. */
370 zebra_vrf_init ();
371 zebra_vty_init();
372
373 /* Configuration file read*/
374 vty_read_config (config_file, config_default);
375
376 /* Clean up rib. */
377 rib_weed_tables ();
378
379 /* Exit when zebra is working in batch mode. */
380 if (batch_mode)
381 exit (0);
382
383 /* Daemonize. */
384 if (daemon_mode && daemon (0, 0) < 0)
385 {
386 perror("daemon start failed");
387 exit (1);
388 }
389
390 /* Needed for BSD routing socket. */
391 pid = getpid ();
392
393 /* Make vty server socket. */
394 vty_serv_sock (vty_addr, vty_port, "/tmp/test_zebra");
395
396 /* Print banner. */
397 zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port);
398
399 while (thread_fetch (zebrad.master, &thread))
400 thread_call (&thread);
401
402 /* Not reached... */
403 return 0;
404 }