nhrp_main.c 5.6 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 <libgen.h>
  11. #include "zebra.h"
  12. #include "privs.h"
  13. #include "getopt.h"
  14. #include "thread.h"
  15. #include "sigevent.h"
  16. #include "version.h"
  17. #include "log.h"
  18. #include "memory.h"
  19. #include "command.h"
  20. #include "nhrpd.h"
  21. #include "netlink.h"
  22. unsigned int debug_flags = 0;
  23. struct thread_master *master;
  24. struct timeval current_time;
  25. static const char *pid_file = PATH_NHRPD_PID;
  26. static char config_default[] = SYSCONFDIR NHRP_DEFAULT_CONFIG;
  27. static char *config_file = NULL;
  28. static char *vty_addr = NULL;
  29. static int vty_port = NHRP_VTY_PORT;
  30. static int do_daemonise = 0;
  31. /* nhrpd options. */
  32. struct option longopts[] = {
  33. { "daemon", no_argument, NULL, 'd'},
  34. { "config_file", required_argument, NULL, 'f'},
  35. { "pid_file", required_argument, NULL, 'i'},
  36. { "socket", required_argument, NULL, 'z'},
  37. { "help", no_argument, NULL, 'h'},
  38. { "vty_addr", required_argument, NULL, 'A'},
  39. { "vty_port", required_argument, NULL, 'P'},
  40. { "user", required_argument, NULL, 'u'},
  41. { "group", required_argument, NULL, 'g'},
  42. { "version", no_argument, NULL, 'v'},
  43. { 0 }
  44. };
  45. /* nhrpd privileges */
  46. static zebra_capabilities_t _caps_p [] = {
  47. ZCAP_NET_RAW,
  48. ZCAP_NET_ADMIN,
  49. ZCAP_DAC_OVERRIDE, /* for now needed to write to /proc/sys/net/ipv4/<if>/send_redirect */
  50. };
  51. static struct zebra_privs_t nhrpd_privs = {
  52. #ifdef QUAGGA_USER
  53. .user = QUAGGA_USER,
  54. #endif
  55. #ifdef 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 = ZEBRA_NUM_OF(_caps_p),
  63. };
  64. static void usage(const char *progname, int status)
  65. {
  66. if (status != 0)
  67. fprintf(stderr, "Try `%s --help' for more information.\n", progname);
  68. else
  69. printf(
  70. "Usage : %s [OPTION...]\n\
  71. Daemon which manages NHRP protocol.\n\n\
  72. -d, --daemon Runs in daemon mode\n\
  73. -f, --config_file Set configuration file name\n\
  74. -i, --pid_file Set process identifier file name\n\
  75. -z, --socket Set path of zebra socket\n\
  76. -A, --vty_addr Set vty's bind address\n\
  77. -P, --vty_port Set vty's port number\n\
  78. -u, --user User to run as\n\
  79. -g, --group Group to run as\n\
  80. -v, --version Print program version\n\
  81. -h, --help Display this help and exit\n\
  82. \n\
  83. Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
  84. exit(status);
  85. }
  86. static void parse_arguments(const char *progname, int argc, char **argv)
  87. {
  88. int opt;
  89. while (1) {
  90. opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:v", longopts, 0);
  91. if(opt < 0) break;
  92. switch (opt) {
  93. case 0:
  94. break;
  95. case 'd':
  96. do_daemonise = -1;
  97. break;
  98. case 'f':
  99. config_file = optarg;
  100. break;
  101. case 'i':
  102. pid_file = optarg;
  103. break;
  104. case 'z':
  105. zclient_serv_path_set(optarg);
  106. break;
  107. case 'A':
  108. vty_addr = optarg;
  109. break;
  110. case 'P':
  111. vty_port = atoi (optarg);
  112. if (vty_port <= 0 || vty_port > 0xffff)
  113. vty_port = NHRP_VTY_PORT;
  114. break;
  115. case 'u':
  116. nhrpd_privs.user = optarg;
  117. break;
  118. case 'g':
  119. nhrpd_privs.group = optarg;
  120. break;
  121. case 'v':
  122. print_version(progname);
  123. exit(0);
  124. break;
  125. case 'h':
  126. usage(progname, 0);
  127. break;
  128. default:
  129. usage(progname, 1);
  130. break;
  131. }
  132. }
  133. }
  134. static void nhrp_sigusr1(void)
  135. {
  136. zlog_rotate(NULL);
  137. }
  138. static void nhrp_request_stop(void)
  139. {
  140. debugf(NHRP_DEBUG_COMMON, "Exiting...");
  141. nhrp_shortcut_terminate();
  142. nhrp_nhs_terminate();
  143. nhrp_zebra_terminate();
  144. vici_terminate();
  145. evmgr_terminate();
  146. nhrp_vc_terminate();
  147. vrf_terminate();
  148. /* memory_terminate(); */
  149. /* vty_terminate(); */
  150. cmd_terminate();
  151. /* signal_terminate(); */
  152. zprivs_terminate(&nhrpd_privs);
  153. debugf(NHRP_DEBUG_COMMON, "Remove pid file.");
  154. if (pid_file) unlink(pid_file);
  155. debugf(NHRP_DEBUG_COMMON, "Done.");
  156. closezlog(zlog_default);
  157. exit(0);
  158. }
  159. static struct quagga_signal_t sighandlers[] = {
  160. { .signal = SIGUSR1, .handler = &nhrp_sigusr1, },
  161. { .signal = SIGINT, .handler = &nhrp_request_stop, },
  162. { .signal = SIGTERM, .handler = &nhrp_request_stop, },
  163. };
  164. int main(int argc, char **argv)
  165. {
  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. thread_main (master);
  211. return 0;
  212. }