isis_main.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  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. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20. */
  21. #include <stdio.h>
  22. #include <zebra.h>
  23. #include <net/ethernet.h>
  24. #include "getopt.h"
  25. #include "thread.h"
  26. #include "log.h"
  27. #include "version.h"
  28. #include "command.h"
  29. #include "vty.h"
  30. #include "memory.h"
  31. #include "stream.h"
  32. #include "if.h"
  33. #include "privs.h"
  34. #include "isisd/dict.h"
  35. #include "include-netbsd/iso.h"
  36. #include "isisd/isis_constants.h"
  37. #include "isisd/isis_common.h"
  38. #include "isisd/isis_flags.h"
  39. #include "isisd/isis_circuit.h"
  40. #include "isisd/isisd.h"
  41. #include "isisd/isis_dynhn.h"
  42. /* Default configuration file name */
  43. #define ISISD_DEFAULT_CONFIG "isisd.conf"
  44. /* Default vty port */
  45. #define ISISD_VTY_PORT 2608
  46. /* isisd privileges */
  47. zebra_capabilities_t _caps_p [] =
  48. {
  49. ZCAP_RAW,
  50. ZCAP_BIND
  51. };
  52. struct zebra_privs_t isisd_privs =
  53. {
  54. #if defined(QUAGGA_USER)
  55. .user = QUAGGA_USER,
  56. #endif
  57. #if defined QUAGGA_GROUP
  58. .group = QUAGGA_GROUP,
  59. #endif
  60. #ifdef VTY_GROUP
  61. .vty_group = VTY_GROUP,
  62. #endif
  63. .caps_p = _caps_p,
  64. .cap_num_p = 2,
  65. .cap_num_i = 0
  66. };
  67. /* isisd options */
  68. struct option longopts[] =
  69. {
  70. { "daemon", no_argument, NULL, 'd'},
  71. { "config_file", required_argument, NULL, 'f'},
  72. { "vty_port", required_argument, NULL, 'P'},
  73. { "user", required_argument, NULL, 'u'},
  74. { "version", no_argument, NULL, 'v'},
  75. { "help", no_argument, NULL, 'h'},
  76. { 0 }
  77. };
  78. /* Configuration file and directory. */
  79. char config_current[] = ISISD_DEFAULT_CONFIG;
  80. char config_default[] = SYSCONFDIR ISISD_DEFAULT_CONFIG;
  81. char *config_file = NULL;
  82. /* isisd program name. */
  83. char *progname;
  84. int daemon_mode = 0;
  85. /* Master of threads. */
  86. struct thread_master *master;
  87. /* for reload */
  88. char _cwd[64];
  89. char _progpath[64];
  90. int _argc;
  91. char **_argv;
  92. char **_envp;
  93. /* Help information display. */
  94. static void
  95. usage (int status)
  96. {
  97. if (status != 0)
  98. fprintf (stderr, "Try `%s --help' for more information.\n", progname);
  99. else
  100. {
  101. printf ("Usage : %s [OPTION...]\n\n\
  102. Daemon which manages IS-IS routing\n\n\
  103. -d, --daemon Runs in daemon mode\n\
  104. -f, --config_file Set configuration file name\n\
  105. -P, --vty_port Set vty's port number\n\
  106. -u, --user User and group to run as\n\
  107. -v, --version Print program version\n\
  108. -h, --help Display this help and exit\n\
  109. \n\
  110. Report bugs to sambo@cs.tut.fi\n", progname);
  111. }
  112. exit (status);
  113. }
  114. void
  115. reload ()
  116. {
  117. zlog_info ("Reload");
  118. /* FIXME: Clean up func call here */
  119. vty_finish ();
  120. execve (_progpath, _argv, _envp);
  121. }
  122. void
  123. terminate (int i)
  124. {
  125. exit (i);
  126. }
  127. /*
  128. * Signal handlers
  129. */
  130. void
  131. sighup (int sig)
  132. {
  133. zlog_info ("SIGHUP received");
  134. reload ();
  135. return;
  136. }
  137. void
  138. sigint (int sig)
  139. {
  140. zlog_info ("SIGINT received");
  141. terminate (0);
  142. return;
  143. }
  144. void
  145. sigterm (int sig)
  146. {
  147. zlog_info ("SIGTERM received");
  148. terminate (0);
  149. }
  150. void
  151. sigusr1 (int sig)
  152. {
  153. zlog_info ("SIGUSR1 received");
  154. zlog_rotate (NULL);
  155. }
  156. /*
  157. * Signal wrapper.
  158. */
  159. RETSIGTYPE *
  160. signal_set (int signo, void (*func)(int))
  161. {
  162. int ret;
  163. struct sigaction sig;
  164. struct sigaction osig;
  165. sig.sa_handler = func;
  166. sigemptyset (&sig.sa_mask);
  167. sig.sa_flags = 0;
  168. #ifdef SA_RESTART
  169. sig.sa_flags |= SA_RESTART;
  170. #endif /* SA_RESTART */
  171. ret = sigaction (signo, &sig, &osig);
  172. if (ret < 0)
  173. return (SIG_ERR);
  174. else
  175. return (osig.sa_handler);
  176. }
  177. void
  178. signal_init ()
  179. {
  180. signal_set (SIGHUP, sighup);
  181. signal_set (SIGINT, sigint);
  182. signal_set (SIGTERM, sigterm);
  183. signal_set (SIGPIPE, SIG_IGN);
  184. #ifdef SIGTSTP
  185. signal_set (SIGTSTP, SIG_IGN);
  186. #endif
  187. #ifdef SIGTTIN
  188. signal_set (SIGTTIN, SIG_IGN);
  189. #endif
  190. #ifdef SIGTTOU
  191. signal_set (SIGTTOU, SIG_IGN);
  192. #endif
  193. signal_set (SIGUSR1, sigusr1);
  194. }
  195. /*
  196. * Main routine of isisd. Parse arguments and handle IS-IS state machine.
  197. */
  198. int
  199. main (int argc, char **argv, char **envp)
  200. {
  201. char *p;
  202. int opt, vty_port = ISISD_VTY_PORT;
  203. struct thread thread;
  204. char *config_file = NULL;
  205. char *vty_addr = NULL;
  206. /* Get the programname without the preceding path. */
  207. progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
  208. zlog_default = openzlog (progname, ZLOG_NOLOG, ZLOG_ISIS,
  209. LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
  210. /* for reload */
  211. _argc = argc;
  212. _argv = argv;
  213. _envp = envp;
  214. getcwd (_cwd, sizeof (_cwd));
  215. if (*argv[0] == '.')
  216. snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]);
  217. else
  218. snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
  219. /* Command line argument treatment. */
  220. while (1)
  221. {
  222. opt = getopt_long (argc, argv, "df:hAp:P:u:v", longopts, 0);
  223. if (opt == EOF)
  224. break;
  225. switch (opt)
  226. {
  227. case 0:
  228. break;
  229. case 'd':
  230. daemon_mode = 1;
  231. break;
  232. case 'f':
  233. config_file = optarg;
  234. break;
  235. case 'A':
  236. vty_addr = optarg;
  237. break;
  238. case 'P':
  239. /* Deal with atoi() returning 0 on failure, and isisd not
  240. listening on isisd port... */
  241. if (strcmp(optarg, "0") == 0)
  242. {
  243. vty_port = 0;
  244. break;
  245. }
  246. vty_port = atoi (optarg);
  247. vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
  248. break;
  249. case 'u':
  250. isisd_privs.user = isisd_privs.group = optarg;
  251. break;
  252. break;
  253. case 'v':
  254. printf("ISISd version %s\n", ISISD_VERSION);
  255. printf("Copyright (c) 2001-2002 Sampo Saaristo,"
  256. " Ofer Wald and Hannes Gredler\n");
  257. print_version ("Zebra");
  258. exit (0);
  259. break;
  260. case 'h':
  261. usage (0);
  262. break;
  263. default:
  264. usage (1);
  265. break;
  266. }
  267. }
  268. /* thread master */
  269. master = thread_master_create ();
  270. /* random seed from time */
  271. srand(time(NULL));
  272. /*
  273. * initializations
  274. */
  275. zprivs_init (&isisd_privs);
  276. signal_init ();
  277. cmd_init (1);
  278. vty_init (master);
  279. memory_init ();
  280. isis_init ();
  281. dyn_cache_init ();
  282. sort_node ();
  283. /* parse config file */
  284. /* this is needed three times! because we have interfaces before the areas */
  285. vty_read_config (config_file, config_current, config_default);
  286. #if 0
  287. vty_read_config (config_file, config_current, config_default);
  288. vty_read_config (config_file, config_current, config_default);
  289. #endif
  290. /* demonize */
  291. if (daemon_mode)
  292. daemon (0, 0);
  293. /* Process ID file creation. */
  294. pid_output (PATH_ISISD_PID);
  295. /* Make isis vty socket. */
  296. vty_serv_sock (vty_addr, vty_port, ISIS_VTYSH_PATH);
  297. /* Print banner. */
  298. #if defined(ZEBRA_VERSION)
  299. zlog_info ("ISISd %s starting: vty@%d", ZEBRA_VERSION, vty_port);
  300. #elif defined(QUAGGA_VERSION)
  301. zlog_info ("Quagga-ISISd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
  302. #endif
  303. #ifdef HAVE_IPV6
  304. zlog_info ("IPv6 enabled");
  305. #endif
  306. /* Start finite state machine. */
  307. while (thread_fetch (master, &thread))
  308. thread_call (&thread);
  309. /* Not reached. */
  310. exit (0);
  311. }