isis_main.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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 <zebra.h>
  22. #include "getopt.h"
  23. #include "thread.h"
  24. #include "log.h"
  25. #include <lib/version.h>
  26. #include "command.h"
  27. #include "vty.h"
  28. #include "memory.h"
  29. #include "stream.h"
  30. #include "if.h"
  31. #include "privs.h"
  32. #include "sigevent.h"
  33. #include "filter.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. ZCAP_NET_RAW,
  49. ZCAP_BIND
  50. };
  51. struct zebra_privs_t isisd_privs = {
  52. #if defined(QUAGGA_USER)
  53. .user = QUAGGA_USER,
  54. #endif
  55. #if defined QUAGGA_GROUP
  56. .group = QUAGGA_GROUP,
  57. #endif
  58. #ifdef VTY_GROUP
  59. .vty_group = VTY_GROUP,
  60. #endif
  61. .caps_p = _caps_p,
  62. .cap_num_p = 2,
  63. .cap_num_i = 0
  64. };
  65. /* isisd options */
  66. struct option longopts[] = {
  67. {"daemon", no_argument, NULL, 'd'},
  68. {"config_file", required_argument, NULL, 'f'},
  69. {"pid_file", required_argument, NULL, 'i'},
  70. {"vty_addr", required_argument, NULL, 'A'},
  71. {"vty_port", required_argument, NULL, 'P'},
  72. {"user", required_argument, NULL, 'u'},
  73. {"group", required_argument, NULL, 'g'},
  74. {"version", no_argument, NULL, 'v'},
  75. {"dryrun", no_argument, NULL, 'C'},
  76. {"help", no_argument, NULL, 'h'},
  77. {0}
  78. };
  79. /* Configuration file and directory. */
  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. /* Process ID saved for use by init system */
  88. const char *pid_file = PATH_ISISD_PID;
  89. /* for reload */
  90. char _cwd[MAXPATHLEN];
  91. char _progpath[MAXPATHLEN];
  92. int _argc;
  93. char **_argv;
  94. char **_envp;
  95. /*
  96. * Prototypes.
  97. */
  98. void reload(void);
  99. void sighup(void);
  100. void sigint(void);
  101. void sigterm(void);
  102. void sigusr1(void);
  103. /* Help information display. */
  104. static void
  105. usage (int status)
  106. {
  107. if (status != 0)
  108. fprintf (stderr, "Try `%s --help' for more information.\n", progname);
  109. else
  110. {
  111. printf ("Usage : %s [OPTION...]\n\n\
  112. Daemon which manages IS-IS routing\n\n\
  113. -d, --daemon Runs in daemon mode\n\
  114. -f, --config_file Set configuration file name\n\
  115. -i, --pid_file Set process identifier file name\n\
  116. -A, --vty_addr Set vty's bind address\n\
  117. -P, --vty_port Set vty's port number\n\
  118. -u, --user User to run as\n\
  119. -g, --group Group to run as\n\
  120. -v, --version Print program version\n\
  121. -C, --dryrun Check configuration for validity and exit\n\
  122. -h, --help Display this help and exit\n\
  123. \n\
  124. Report bugs to http://bugzilla.quagga.net\n", progname);
  125. }
  126. exit (status);
  127. }
  128. void
  129. reload ()
  130. {
  131. zlog_debug ("Reload");
  132. /* FIXME: Clean up func call here */
  133. vty_reset ();
  134. execve (_progpath, _argv, _envp);
  135. }
  136. static void
  137. terminate (int i)
  138. {
  139. exit (i);
  140. }
  141. /*
  142. * Signal handlers
  143. */
  144. void
  145. sighup (void)
  146. {
  147. zlog_debug ("SIGHUP received");
  148. reload ();
  149. return;
  150. }
  151. void
  152. sigint (void)
  153. {
  154. zlog_notice ("Terminating on signal SIGINT");
  155. terminate (0);
  156. }
  157. void
  158. sigterm (void)
  159. {
  160. zlog_notice ("Terminating on signal SIGTERM");
  161. terminate (0);
  162. }
  163. void
  164. sigusr1 (void)
  165. {
  166. zlog_debug ("SIGUSR1 received");
  167. zlog_rotate (NULL);
  168. }
  169. struct quagga_signal_t isisd_signals[] =
  170. {
  171. {
  172. .signal = SIGHUP,
  173. .handler = &sighup,
  174. },
  175. {
  176. .signal = SIGUSR1,
  177. .handler = &sigusr1,
  178. },
  179. {
  180. .signal = SIGINT,
  181. .handler = &sigint,
  182. },
  183. {
  184. .signal = SIGTERM,
  185. .handler = &sigterm,
  186. },
  187. };
  188. /*
  189. * Main routine of isisd. Parse arguments and handle IS-IS state machine.
  190. */
  191. int
  192. main (int argc, char **argv, char **envp)
  193. {
  194. char *p;
  195. int opt, vty_port = ISISD_VTY_PORT;
  196. struct thread thread;
  197. char *config_file = NULL;
  198. char *vty_addr = NULL;
  199. int dryrun = 0;
  200. /* Get the programname without the preceding path. */
  201. progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
  202. zlog_default = openzlog (progname, ZLOG_ISIS,
  203. LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
  204. /* for reload */
  205. _argc = argc;
  206. _argv = argv;
  207. _envp = envp;
  208. getcwd (_cwd, sizeof (_cwd));
  209. if (*argv[0] == '.')
  210. snprintf (_progpath, sizeof (_progpath), "%s/%s", _cwd, _argv[0]);
  211. else
  212. snprintf (_progpath, sizeof (_progpath), "%s", argv[0]);
  213. /* Command line argument treatment. */
  214. while (1)
  215. {
  216. opt = getopt_long (argc, argv, "df:i:hA:p:P:u:g:vC", longopts, 0);
  217. if (opt == EOF)
  218. break;
  219. switch (opt)
  220. {
  221. case 0:
  222. break;
  223. case 'd':
  224. daemon_mode = 1;
  225. break;
  226. case 'f':
  227. config_file = optarg;
  228. break;
  229. case 'i':
  230. pid_file = optarg;
  231. break;
  232. case 'A':
  233. vty_addr = optarg;
  234. break;
  235. case 'P':
  236. /* Deal with atoi() returning 0 on failure, and isisd not
  237. listening on isisd port... */
  238. if (strcmp (optarg, "0") == 0)
  239. {
  240. vty_port = 0;
  241. break;
  242. }
  243. vty_port = atoi (optarg);
  244. vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
  245. break;
  246. case 'u':
  247. isisd_privs.user = optarg;
  248. break;
  249. case 'g':
  250. isisd_privs.group = optarg;
  251. break;
  252. case 'v':
  253. printf ("ISISd version %s\n", ISISD_VERSION);
  254. printf ("Copyright (c) 2001-2002 Sampo Saaristo,"
  255. " Ofer Wald and Hannes Gredler\n");
  256. print_version ("Zebra");
  257. exit (0);
  258. break;
  259. case 'C':
  260. dryrun = 1;
  261. break;
  262. case 'h':
  263. usage (0);
  264. break;
  265. default:
  266. usage (1);
  267. break;
  268. }
  269. }
  270. /* thread master */
  271. master = thread_master_create ();
  272. /* random seed from time */
  273. srand (time (NULL));
  274. /*
  275. * initializations
  276. */
  277. zprivs_init (&isisd_privs);
  278. signal_init (master, Q_SIGC (isisd_signals), isisd_signals);
  279. cmd_init (1);
  280. vty_init (master);
  281. memory_init ();
  282. access_list_init();
  283. isis_init ();
  284. dyn_cache_init ();
  285. sort_node ();
  286. /* parse config file */
  287. /* this is needed three times! because we have interfaces before the areas */
  288. vty_read_config (config_file, config_default);
  289. vty_read_config (config_file, config_default);
  290. vty_read_config (config_file, config_default);
  291. /* Start execution only if not in dry-run mode */
  292. if (dryrun)
  293. return(0);
  294. /* demonize */
  295. if (daemon_mode && daemon (0, 0) < 0)
  296. {
  297. zlog_err("ISISd daemon failed: %s", strerror(errno));
  298. exit (1);
  299. }
  300. /* Process ID file creation. */
  301. pid_output (pid_file);
  302. /* Make isis vty socket. */
  303. vty_serv_sock (vty_addr, vty_port, ISIS_VTYSH_PATH);
  304. /* Print banner. */
  305. zlog_notice ("Quagga-ISISd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
  306. /* Start finite state machine. */
  307. while (thread_fetch (master, &thread))
  308. thread_call (&thread);
  309. /* Not reached. */
  310. exit (0);
  311. }