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