]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - zebra/test_main.c
Import Upstream version 1.2.2
[quagga-debian.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 /* 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 }