]> git.proxmox.com Git - mirror_frr.git/blame - zebra/test_main.c
zebra, lib/memtypes.c: the netlink sockets work per VRF
[mirror_frr.git] / zebra / test_main.c
CommitLineData
457eb9af
PJ
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"
b72ede27 32#include "vrf.h"
457eb9af
PJ
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 */
41struct zebra_t zebrad =
42{
43 .rtm_table_default = 0,
44};
45
46/* process id. */
457eb9af
PJ
47pid_t pid;
48
6baf7bb8
DS
49/* Allow non-quagga entities to delete quagga routes */
50int allow_delete = 0;
51
457eb9af
PJ
52/* zebra_rib's workqueue hold time. Private export for use by test code only */
53extern int rib_process_hold_time;
54
55/* Pacify zclient.o in libzebra, which expects this variable. */
56struct thread_master *master;
57
58/* Command line options. */
59struct option longopts[] =
60{
6baf7bb8
DS
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'},
457eb9af
PJ
70 { 0 }
71};
72
73zebra_capabilities_t _caps_p [] =
74{
75 ZCAP_NET_ADMIN,
76 ZCAP_SYS_ADMIN,
77 ZCAP_NET_RAW,
78};
79
80/* Default configuration file path. */
81char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;
82
83/* Process ID saved for use by init system */
84const char *pid_file = PATH_ZEBRA_PID;
85
86/* Help information display. */
87static void
88usage (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"\
6baf7bb8 99 "-a, --allow_delete Allow other processes to delete Quagga Routes\n" \
457eb9af 100 "-f, --config_file Set configuration file name\n"\
457eb9af
PJ
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}
6b0655a2 112
457eb9af
PJ
113static unsigned int test_ifindex = 0;
114
115/* testrib commands */
116DEFUN (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
153static void
154test_cmd_init (void)
155{
156 install_element (INTERFACE_NODE, &test_interface_state_cmd);
157}
6b0655a2 158
457eb9af
PJ
159/* SIGHUP handler. */
160static void
161sighup (void)
162{
163 zlog_info ("SIGHUP received");
164
165 /* Reload of config file. */
166 ;
167}
168
169/* SIGINT handler. */
170static void
171sigint (void)
172{
173 zlog_notice ("Terminating on signal");
174
175 exit (0);
176}
177
178/* SIGUSR1 handler. */
179static void
180sigusr1 (void)
181{
182 zlog_rotate (NULL);
183}
184
185struct 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};
6b0655a2 204
b72ede27
FL
205/* Callback upon creating a new VRF. */
206static int
207zebra_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
a31c5886
FL
220/* Callback upon enabling a VRF. */
221static int
222zebra_vrf_enable (vrf_id_t vrf_id, void **info)
223{
224 struct zebra_vrf *zvrf = (struct zebra_vrf *) (*info);
225
226 assert (zvrf);
227
8f7d9fc0
FL
228 kernel_init (zvrf);
229 route_read (zvrf);
230
a31c5886
FL
231 return 0;
232}
233
234/* Callback upon disabling a VRF. */
235static int
236zebra_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
8f7d9fc0
FL
255 kernel_terminate (zvrf);
256
a31c5886
FL
257 return 0;
258}
259
b72ede27
FL
260/* Zebra VRF initialization. */
261static void
262zebra_vrf_init (void)
263{
264 vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new);
a31c5886
FL
265 vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable);
266 vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable);
b72ede27
FL
267 vrf_init ();
268}
269
457eb9af
PJ
270/* Main startup routine. */
271int
272main (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
7c8ff89e 289 zlog_default = openzlog (progname, ZLOG_ZEBRA, 0,
457eb9af
PJ
290 LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
291
292 while (1)
293 {
294 int opt;
295
6baf7bb8 296 opt = getopt_long (argc, argv, "bdaf:hA:P:r:v", longopts, 0);
457eb9af
PJ
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;
6baf7bb8
DS
310 case 'a':
311 allow_delete =1;
312 break;
457eb9af
PJ
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)
302d53f7
PJ
347 {
348 fprintf (stderr, "Error: --vty_port and --config_file arguments"
349 " are both required\n");
350 usage (progname, 1);
351 }
457eb9af
PJ
352
353 /* Make master thread emulator. */
354 zebrad.master = thread_master_create ();
355
356 /* Vty related initialize. */
837d16cc 357 signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
457eb9af
PJ
358 cmd_init (1);
359 vty_init (zebrad.master);
360 memory_init ();
457eb9af
PJ
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. */
b72ede27 370 zebra_vrf_init ();
457eb9af
PJ
371 zebra_vty_init();
372
457eb9af
PJ
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
457eb9af 383 /* Daemonize. */
065de903
SH
384 if (daemon_mode && daemon (0, 0) < 0)
385 {
386 perror("daemon start failed");
387 exit (1);
388 }
457eb9af
PJ
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}