nhrp_main.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /* NHRP daemon main functions
  2. * Copyright (c) 2014-2015 Timo Teräs
  3. *
  4. * This file is free software: you may copy, redistribute and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #include <unistd.h>
  10. #include "zebra.h"
  11. #include "privs.h"
  12. #include "getopt.h"
  13. #include "thread.h"
  14. #include "sigevent.h"
  15. #include "version.h"
  16. #include "log.h"
  17. #include "memory.h"
  18. #include "command.h"
  19. #include "nhrpd.h"
  20. #include "netlink.h"
  21. unsigned int debug_flags = 0;
  22. struct thread_master *master;
  23. struct timeval current_time;
  24. static const char *pid_file = PATH_NHRPD_PID;
  25. static char config_default[] = SYSCONFDIR NHRP_DEFAULT_CONFIG;
  26. static char *config_file = NULL;
  27. static char *vty_addr = NULL;
  28. static int vty_port = NHRP_VTY_PORT;
  29. static int do_daemonise = 0;
  30. /* nhrpd options. */
  31. struct option longopts[] = {
  32. { "daemon", no_argument, NULL, 'd'},
  33. { "config_file", required_argument, NULL, 'f'},
  34. { "pid_file", required_argument, NULL, 'i'},
  35. { "socket", required_argument, NULL, 'z'},
  36. { "help", no_argument, NULL, 'h'},
  37. { "vty_addr", required_argument, NULL, 'A'},
  38. { "vty_port", required_argument, NULL, 'P'},
  39. { "user", required_argument, NULL, 'u'},
  40. { "group", required_argument, NULL, 'g'},
  41. { "version", no_argument, NULL, 'v'},
  42. { 0 }
  43. };
  44. /* nhrpd privileges */
  45. static zebra_capabilities_t _caps_p [] = {
  46. ZCAP_NET_RAW,
  47. ZCAP_NET_ADMIN,
  48. ZCAP_DAC_OVERRIDE, /* for now needed to write to /proc/sys/net/ipv4/<if>/send_redirect */
  49. };
  50. static struct zebra_privs_t nhrpd_privs = {
  51. #ifdef QUAGGA_USER
  52. .user = QUAGGA_USER,
  53. #endif
  54. #ifdef QUAGGA_GROUP
  55. .group = QUAGGA_GROUP,
  56. #endif
  57. #ifdef VTY_GROUP
  58. .vty_group = VTY_GROUP,
  59. #endif
  60. .caps_p = _caps_p,
  61. .cap_num_p = ZEBRA_NUM_OF(_caps_p),
  62. };
  63. static void usage(const char *progname, int status)
  64. {
  65. if (status != 0)
  66. fprintf(stderr, "Try `%s --help' for more information.\n", progname);
  67. else
  68. printf(
  69. "Usage : %s [OPTION...]\n\
  70. Daemon which manages NHRP protocol.\n\n\
  71. -d, --daemon Runs in daemon mode\n\
  72. -f, --config_file Set configuration file name\n\
  73. -i, --pid_file Set process identifier file name\n\
  74. -z, --socket Set path of zebra socket\n\
  75. -A, --vty_addr Set vty's bind address\n\
  76. -P, --vty_port Set vty's port number\n\
  77. -u, --user User to run as\n\
  78. -g, --group Group to run as\n\
  79. -v, --version Print program version\n\
  80. -h, --help Display this help and exit\n\
  81. \n\
  82. Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
  83. exit(status);
  84. }
  85. static void parse_arguments(const char *progname, int argc, char **argv)
  86. {
  87. int opt;
  88. while (1) {
  89. opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:v", longopts, 0);
  90. if(opt < 0) break;
  91. switch (opt) {
  92. case 0:
  93. break;
  94. case 'd':
  95. do_daemonise = -1;
  96. break;
  97. case 'f':
  98. config_file = optarg;
  99. break;
  100. case 'i':
  101. pid_file = optarg;
  102. break;
  103. case 'z':
  104. zclient_serv_path_set(optarg);
  105. break;
  106. case 'A':
  107. vty_addr = optarg;
  108. break;
  109. case 'P':
  110. vty_port = atoi (optarg);
  111. if (vty_port <= 0 || vty_port > 0xffff)
  112. vty_port = NHRP_VTY_PORT;
  113. break;
  114. case 'u':
  115. nhrpd_privs.user = optarg;
  116. break;
  117. case 'g':
  118. nhrpd_privs.group = optarg;
  119. break;
  120. case 'v':
  121. print_version(progname);
  122. exit(0);
  123. break;
  124. case 'h':
  125. usage(progname, 0);
  126. break;
  127. default:
  128. usage(progname, 1);
  129. break;
  130. }
  131. }
  132. }
  133. static void nhrp_sigusr1(void)
  134. {
  135. zlog_rotate(NULL);
  136. }
  137. static void nhrp_request_stop(void)
  138. {
  139. debugf(NHRP_DEBUG_COMMON, "Exiting...");
  140. nhrp_shortcut_terminate();
  141. nhrp_nhs_terminate();
  142. nhrp_zebra_terminate();
  143. vici_terminate();
  144. evmgr_terminate();
  145. nhrp_vc_terminate();
  146. vrf_terminate();
  147. /* memory_terminate(); */
  148. /* vty_terminate(); */
  149. cmd_terminate();
  150. /* signal_terminate(); */
  151. zprivs_terminate(&nhrpd_privs);
  152. debugf(NHRP_DEBUG_COMMON, "Remove pid file.");
  153. if (pid_file) unlink(pid_file);
  154. debugf(NHRP_DEBUG_COMMON, "Done.");
  155. closezlog(zlog_default);
  156. exit(0);
  157. }
  158. static struct quagga_signal_t sighandlers[] = {
  159. { .signal = SIGUSR1, .handler = &nhrp_sigusr1, },
  160. { .signal = SIGINT, .handler = &nhrp_request_stop, },
  161. { .signal = SIGTERM, .handler = &nhrp_request_stop, },
  162. };
  163. int main(int argc, char **argv)
  164. {
  165. struct thread thread;
  166. const char *progname;
  167. /* Set umask before anything for security */
  168. umask(0027);
  169. progname = basename(argv[0]);
  170. zlog_default = openzlog(progname, ZLOG_NHRP, LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON);
  171. zlog_set_level(NULL, ZLOG_DEST_STDOUT, LOG_WARNING);
  172. parse_arguments(progname, argc, argv);
  173. /* Library inits. */
  174. master = thread_master_create();
  175. zprivs_init(&nhrpd_privs);
  176. signal_init(master, array_size(sighandlers), sighandlers);
  177. cmd_init(1);
  178. vty_init(master);
  179. memory_init();
  180. nhrp_interface_init();
  181. vrf_init();
  182. resolver_init();
  183. /* Run with elevated capabilities, as for all netlink activity
  184. * we need privileges anyway. */
  185. nhrpd_privs.change(ZPRIVS_RAISE);
  186. netlink_init();
  187. evmgr_init();
  188. nhrp_vc_init();
  189. nhrp_packet_init();
  190. vici_init();
  191. nhrp_zebra_init();
  192. nhrp_shortcut_init();
  193. nhrp_config_init();
  194. /* Get zebra configuration file. */
  195. zlog_set_level(NULL, ZLOG_DEST_STDOUT, do_daemonise ? ZLOG_DISABLED : LOG_DEBUG);
  196. vty_read_config(config_file, config_default);
  197. if (do_daemonise && daemon(0, 0) < 0) {
  198. zlog_err("daemonise: %s", safe_strerror(errno));
  199. exit (1);
  200. }
  201. /* write pid file */
  202. if (pid_output(pid_file) < 0) {
  203. zlog_err("error while writing pidfile");
  204. exit (1);
  205. }
  206. /* Create VTY socket */
  207. vty_serv_sock(vty_addr, vty_port, NHRP_VTYSH_PATH);
  208. zlog_notice("nhrpd starting: vty@%d", vty_port);
  209. /* Main loop */
  210. while (thread_fetch(master, &thread))
  211. thread_call(&thread);
  212. return 0;
  213. }