ospf6_main.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * Copyright (C) 1999 Yasuhiro Ohara
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the
  18. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include <lib/version.h>
  23. #include "getopt.h"
  24. #include "thread.h"
  25. #include "log.h"
  26. #include "command.h"
  27. #include "vty.h"
  28. #include "memory.h"
  29. #include "if.h"
  30. #include "filter.h"
  31. #include "prefix.h"
  32. #include "plist.h"
  33. #include "privs.h"
  34. #include "sigevent.h"
  35. #include "zclient.h"
  36. #include "vrf.h"
  37. #include "ospf6d.h"
  38. #include "ospf6_top.h"
  39. #include "ospf6_message.h"
  40. #include "ospf6_asbr.h"
  41. #include "ospf6_lsa.h"
  42. #include "ospf6_interface.h"
  43. #include "ospf6_zebra.h"
  44. /* Default configuration file name for ospf6d. */
  45. #define OSPF6_DEFAULT_CONFIG "ospf6d.conf"
  46. /* Default port values. */
  47. #define OSPF6_VTY_PORT 2606
  48. /* ospf6d privileges */
  49. zebra_capabilities_t _caps_p [] =
  50. {
  51. ZCAP_NET_RAW,
  52. ZCAP_BIND
  53. };
  54. struct zebra_privs_t ospf6d_privs =
  55. {
  56. #if defined(QUAGGA_USER)
  57. .user = QUAGGA_USER,
  58. #endif
  59. #if defined QUAGGA_GROUP
  60. .group = QUAGGA_GROUP,
  61. #endif
  62. #ifdef VTY_GROUP
  63. .vty_group = VTY_GROUP,
  64. #endif
  65. .caps_p = _caps_p,
  66. .cap_num_p = 2,
  67. .cap_num_i = 0
  68. };
  69. /* ospf6d options, we use GNU getopt library. */
  70. struct option longopts[] =
  71. {
  72. { "daemon", no_argument, NULL, 'd'},
  73. { "config_file", required_argument, NULL, 'f'},
  74. { "pid_file", required_argument, NULL, 'i'},
  75. { "socket", required_argument, NULL, 'z'},
  76. { "vty_addr", required_argument, NULL, 'A'},
  77. { "vty_port", required_argument, NULL, 'P'},
  78. { "user", required_argument, NULL, 'u'},
  79. { "group", required_argument, NULL, 'g'},
  80. { "version", no_argument, NULL, 'v'},
  81. { "dryrun", no_argument, NULL, 'C'},
  82. { "help", no_argument, NULL, 'h'},
  83. { 0 }
  84. };
  85. /* Configuration file and directory. */
  86. char config_default[] = SYSCONFDIR OSPF6_DEFAULT_CONFIG;
  87. /* ospf6d program name. */
  88. char *progname;
  89. /* is daemon? */
  90. int daemon_mode = 0;
  91. /* Master of threads. */
  92. struct thread_master *master;
  93. /* Process ID saved for use by init system */
  94. const char *pid_file = PATH_OSPF6D_PID;
  95. /* Help information display. */
  96. static void
  97. usage (char *progname, int status)
  98. {
  99. if (status != 0)
  100. fprintf (stderr, "Try `%s --help' for more information.\n", progname);
  101. else
  102. {
  103. printf ("Usage : %s [OPTION...]\n\n\
  104. Daemon which manages OSPF version 3.\n\n\
  105. -d, --daemon Runs in daemon mode\n\
  106. -f, --config_file Set configuration file name\n\
  107. -i, --pid_file Set process identifier file name\n\
  108. -z, --socket Set path of zebra socket\n\
  109. -A, --vty_addr Set vty's bind address\n\
  110. -P, --vty_port Set vty's port number\n\
  111. -u, --user User to run as\n\
  112. -g, --group Group to run as\n\
  113. -v, --version Print program version\n\
  114. -C, --dryrun Check configuration for validity and exit\n\
  115. -h, --help Display this help and exit\n\
  116. \n\
  117. Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
  118. }
  119. exit (status);
  120. }
  121. static void __attribute__ ((noreturn))
  122. ospf6_exit (int status)
  123. {
  124. struct listnode *node;
  125. struct interface *ifp;
  126. if (ospf6)
  127. ospf6_delete (ospf6);
  128. for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp))
  129. if (ifp->info != NULL)
  130. ospf6_interface_delete(ifp->info);
  131. ospf6_message_terminate ();
  132. ospf6_asbr_terminate ();
  133. ospf6_lsa_terminate ();
  134. vrf_terminate ();
  135. vty_terminate ();
  136. cmd_terminate ();
  137. if (zclient)
  138. zclient_free (zclient);
  139. if (master)
  140. thread_master_free (master);
  141. if (zlog_default)
  142. closezlog (zlog_default);
  143. exit (status);
  144. }
  145. /* SIGHUP handler. */
  146. static void
  147. sighup (void)
  148. {
  149. zlog_info ("SIGHUP received");
  150. }
  151. /* SIGINT handler. */
  152. static void
  153. sigint (void)
  154. {
  155. zlog_notice ("Terminating on signal SIGINT");
  156. ospf6_exit (0);
  157. }
  158. /* SIGTERM handler. */
  159. static void
  160. sigterm (void)
  161. {
  162. zlog_notice ("Terminating on signal SIGTERM");
  163. ospf6_clean();
  164. ospf6_exit (0);
  165. }
  166. /* SIGUSR1 handler. */
  167. static void
  168. sigusr1 (void)
  169. {
  170. zlog_info ("SIGUSR1 received");
  171. zlog_rotate (NULL);
  172. }
  173. struct quagga_signal_t ospf6_signals[] =
  174. {
  175. {
  176. .signal = SIGHUP,
  177. .handler = &sighup,
  178. },
  179. {
  180. .signal = SIGINT,
  181. .handler = &sigint,
  182. },
  183. {
  184. .signal = SIGTERM,
  185. .handler = &sigterm,
  186. },
  187. {
  188. .signal = SIGUSR1,
  189. .handler = &sigusr1,
  190. },
  191. };
  192. /* Main routine of ospf6d. Treatment of argument and starting ospf finite
  193. state machine is handled here. */
  194. int
  195. main (int argc, char *argv[], char *envp[])
  196. {
  197. char *p;
  198. int opt;
  199. char *vty_addr = NULL;
  200. int vty_port = 0;
  201. char *config_file = NULL;
  202. int dryrun = 0;
  203. /* Set umask before anything for security */
  204. umask (0027);
  205. /* Preserve name of myself. */
  206. progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
  207. /* Command line argument treatment. */
  208. while (1)
  209. {
  210. opt = getopt_long (argc, argv, "df:i:z:hp:A:P:u:g:vC", longopts, 0);
  211. if (opt == EOF)
  212. break;
  213. switch (opt)
  214. {
  215. case 0:
  216. break;
  217. case 'd':
  218. daemon_mode = 1;
  219. break;
  220. case 'f':
  221. config_file = optarg;
  222. break;
  223. case 'A':
  224. vty_addr = optarg;
  225. break;
  226. case 'i':
  227. pid_file = optarg;
  228. break;
  229. case 'z':
  230. zclient_serv_path_set (optarg);
  231. break;
  232. case 'P':
  233. /* Deal with atoi() returning 0 on failure, and ospf6d not
  234. listening on ospf6d port... */
  235. if (strcmp(optarg, "0") == 0)
  236. {
  237. vty_port = 0;
  238. break;
  239. }
  240. vty_port = atoi (optarg);
  241. if (vty_port <= 0 || vty_port > 0xffff)
  242. vty_port = OSPF6_VTY_PORT;
  243. break;
  244. case 'u':
  245. ospf6d_privs.user = optarg;
  246. break;
  247. case 'g':
  248. ospf6d_privs.group = optarg;
  249. break;
  250. case 'v':
  251. print_version (progname);
  252. exit (0);
  253. break;
  254. case 'C':
  255. dryrun = 1;
  256. break;
  257. case 'h':
  258. usage (progname, 0);
  259. break;
  260. default:
  261. usage (progname, 1);
  262. break;
  263. }
  264. }
  265. if (geteuid () != 0)
  266. {
  267. errno = EPERM;
  268. perror (progname);
  269. exit (1);
  270. }
  271. /* thread master */
  272. master = thread_master_create ();
  273. /* Initializations. */
  274. zlog_default = openzlog (progname, ZLOG_OSPF6,
  275. LOG_CONS|LOG_NDELAY|LOG_PID,
  276. LOG_DAEMON);
  277. zprivs_init (&ospf6d_privs);
  278. /* initialize zebra libraries */
  279. signal_init (master, array_size(ospf6_signals), ospf6_signals);
  280. cmd_init (1);
  281. vty_init (master);
  282. memory_init ();
  283. vrf_init ();
  284. access_list_init ();
  285. prefix_list_init ();
  286. /* initialize ospf6 */
  287. ospf6_init ();
  288. /* parse config file */
  289. vty_read_config (config_file, config_default);
  290. /* Start execution only if not in dry-run mode */
  291. if (dryrun)
  292. return(0);
  293. if (daemon_mode && daemon (0, 0) < 0)
  294. {
  295. zlog_err("OSPF6d daemon failed: %s", strerror(errno));
  296. exit (1);
  297. }
  298. /* pid file create */
  299. pid_output (pid_file);
  300. /* Make ospf6 vty socket. */
  301. if (!vty_port)
  302. vty_port = OSPF6_VTY_PORT;
  303. vty_serv_sock (vty_addr, vty_port, OSPF6_VTYSH_PATH);
  304. /* Print start message */
  305. zlog_notice ("OSPF6d (Quagga-%s ospf6d-%s) starts: vty@%d",
  306. QUAGGA_VERSION, OSPF6_DAEMON_VERSION,vty_port);
  307. /* Start finite state machine, here we go! */
  308. thread_main (master);
  309. /* Log in case thread failed */
  310. zlog_warn ("Thread failed");
  311. /* Not reached. */
  312. ospf6_exit (0);
  313. }