New upstream version 1.2.3
[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
277   /* Set umask before anything for security */
278   umask (0027);
279
280   /* preserve my name */
281   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
282
283   zlog_default = openzlog (progname, ZLOG_ZEBRA,
284                            LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
285
286   while (1) 
287     {
288       int opt;
289   
290       opt = getopt_long (argc, argv, "bdf:hA:P:r:v", longopts, 0);
291
292       if (opt == EOF)
293         break;
294
295       switch (opt) 
296         {
297         case 0:
298           break;
299         case 'b':
300           batch_mode = 1;
301         case 'd':
302           daemon_mode = 1;
303           break;
304         case 'f':
305           config_file = optarg;
306           break;
307         case 'A':
308           vty_addr = optarg;
309           break;
310         case 'P':
311           /* Deal with atoi() returning 0 on failure, and zebra not
312              listening on zebra port... */
313           if (strcmp(optarg, "0") == 0) 
314             {
315               vty_port = 0;
316               break;
317             } 
318           vty_port = atoi (optarg);
319           break;
320         case 'r':
321           rib_process_hold_time = atoi(optarg);
322           break;
323         case 'v':
324           print_version (progname);
325           exit (0);
326           break;
327         case 'h':
328           usage (progname, 0);
329           break;
330         default:
331           usage (progname, 1);
332           break;
333         }
334     }
335   
336   /* port and conf file mandatory */
337   if (!vty_port || !config_file)
338     {
339       fprintf (stderr, "Error: --vty_port and --config_file arguments"
340                        " are both required\n");
341       usage (progname, 1);
342     }
343   
344   /* Make master thread emulator. */
345   zebrad.master = thread_master_create ();
346
347   /* Vty related initialize. */
348   signal_init (zebrad.master, array_size(zebra_signals), zebra_signals);
349   cmd_init (1);
350   vty_init (zebrad.master);
351   memory_init ();
352   zebra_debug_init ();
353   zebra_if_init ();
354   test_cmd_init ();
355
356   /* Zebra related initialize. */
357   rib_init ();
358   access_list_init ();
359
360   /* Make kernel routing socket. */
361   zebra_vrf_init ();
362   zebra_vty_init();
363
364   /* Configuration file read*/
365   vty_read_config (config_file, config_default);
366
367   /* Clean up rib. */
368   rib_weed_tables ();
369
370   /* Exit when zebra is working in batch mode. */
371   if (batch_mode)
372     exit (0);
373
374   /* Daemonize. */
375   if (daemon_mode && daemon (0, 0) < 0)
376     {
377       perror("daemon start failed");
378       exit (1);
379     }
380
381   /* Needed for BSD routing socket. */
382   pid = getpid ();
383
384   /* Make vty server socket. */
385   vty_serv_sock (vty_addr, vty_port, "/tmp/test_zebra");
386
387   /* Print banner. */
388   zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port);
389
390   thread_main (zebrad.master);
391
392   /* Not reached... */
393   return 0;
394 }