]> git.proxmox.com Git - mirror_frr.git/blame - babeld/babel_main.c
tools: enable stylechecker to handle new files
[mirror_frr.git] / babeld / babel_main.c
CommitLineData
ca10883e
DS
1/*
2Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23/* include zebra library */
24#include <zebra.h>
25#include "getopt.h"
26#include "if.h"
27#include "log.h"
28#include "thread.h"
29#include "privs.h"
30#include "sigevent.h"
31#include "version.h"
32#include "command.h"
33#include "vty.h"
34#include "memory.h"
35#include "libfrr.h"
36
37#include "babel_main.h"
38#include "babeld.h"
39#include "util.h"
40#include "kernel.h"
41#include "babel_interface.h"
42#include "neighbour.h"
43#include "route.h"
44#include "xroute.h"
45#include "message.h"
46#include "resend.h"
47#include "babel_zebra.h"
48
ca10883e
DS
49static void babel_fail(void);
50static void babel_init_random(void);
51static void babel_replace_by_null(int fd);
52static void babel_exit_properly(void);
53static void babel_save_state_file(void);
54
55
56struct thread_master *master; /* quagga's threads handler */
57struct timeval babel_now; /* current time */
58
59unsigned char myid[8]; /* unique id (mac address of an interface) */
60int debug = 0;
61
62int resend_delay = -1;
63
64const unsigned char zeroes[16] = {0};
65const unsigned char ones[16] =
66 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
67 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
68
69static const char *state_file = DAEMON_VTY_DIR "/babel-state";
70
71unsigned char protocol_group[16]; /* babel's link-local multicast address */
72int protocol_port; /* babel's port */
73int protocol_socket = -1; /* socket: communicate with others babeld */
74
75static char babel_config_default[] = SYSCONFDIR BABEL_DEFAULT_CONFIG;
76static char *babel_config_file = NULL;
77static char *babel_vty_addr = NULL;
78static int babel_vty_port = BABEL_VTY_PORT;
79
80/* babeld privileges */
81static zebra_capabilities_t _caps_p [] =
82{
83 ZCAP_NET_RAW,
84 ZCAP_BIND
85};
900b8c58 86
346526cc 87struct zebra_privs_t babeld_privs =
ca10883e 88{
dd329373
DS
89#if defined(FRR_USER)
90 .user = FRR_USER,
ca10883e 91#endif
dd329373
DS
92#if defined FRR_GROUP
93 .group = FRR_GROUP,
ca10883e
DS
94#endif
95#ifdef VTY_GROUP
96 .vty_group = VTY_GROUP,
97#endif
98 .caps_p = _caps_p,
900b8c58 99 .cap_num_p = array_size(_caps_p),
ca10883e
DS
100 .cap_num_i = 0
101};
102
103static void
104babel_sigexit(void)
105{
106 zlog_notice("Terminating on signal");
107
108 babel_exit_properly();
109}
110
111static void
112babel_sigusr1 (void)
113{
114 zlog_rotate ();
115}
116
117static struct quagga_signal_t babel_signals[] =
118 {
119 {
120 .signal = SIGUSR1,
121 .handler = &babel_sigusr1,
122 },
123 {
124 .signal = SIGINT,
125 .handler = &babel_sigexit,
126 },
127 {
128 .signal = SIGTERM,
129 .handler = &babel_sigexit,
130 },
131 };
132
133struct option longopts[] =
134 {
135 { 0 }
136 };
137
138FRR_DAEMON_INFO(babeld, BABELD,
139 .vty_port = BABEL_VTY_PORT,
140 .proghelp = "Implementation of the BABEL routing protocol.",
141
142 .signals = babel_signals,
143 .n_signals = array_size(babel_signals),
144
145 .privs = &babeld_privs,
146 )
147
148int
149main(int argc, char **argv)
150{
900b8c58 151 int rc;
ca10883e 152
900b8c58
DS
153 frr_preinit (&babeld_di, argc, argv);
154 frr_opt_add ("", longopts, "");
ca10883e
DS
155
156 babel_init_random();
157
158 /* set the Babel's default link-local multicast address and Babel's port */
159 parse_address("ff02:0:0:0:0:0:1:6", protocol_group, NULL);
160 protocol_port = 6696;
161
162 /* get options */
163 while(1) {
164 int opt;
165
166 opt = frr_getopt (argc, argv, NULL);
167
168 if (opt == EOF)
169 break;
170
171 switch (opt)
172 {
173 case 0:
174 break;
175 default:
176 frr_help_exit (1);
177 break;
178 }
179 }
180
181 /* create the threads handler */
900b8c58 182 master = frr_init ();
ca10883e
DS
183
184 /* Library inits. */
185 zprivs_init (&babeld_privs);
186 cmd_init (1);
187 vty_init (master);
188
189 resend_delay = BABEL_DEFAULT_RESEND_DELAY;
190 change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE);
191
192 babel_replace_by_null(STDIN_FILENO);
193
194 /* init some quagga's dependencies, and babeld's commands */
195 babeld_quagga_init();
196 /* init zebra client's structure and it's commands */
197 /* this replace kernel_setup && kernel_setup_socket */
198 babelz_zebra_init ();
199
200 /* Get zebra configuration file. */
201 vty_read_config (babel_config_file, babel_config_default);
202
203 /* init buffer */
204 rc = resize_receive_buffer(1500);
205 if(rc < 0)
206 babel_fail();
207
208 schedule_neighbours_check(5000, 1);
209
900b8c58
DS
210 frr_config_fork();
211 frr_run(master);
212
213 return 0;
ca10883e
DS
214}
215
216static void
217babel_fail(void)
218{
219 exit(1);
220}
221
222/* initialize random value, and set 'babel_now' by the way. */
223static void
224babel_init_random(void)
225{
226 gettime(&babel_now);
227 int rc;
228 unsigned int seed;
229
230 rc = read_random_bytes(&seed, sizeof(seed));
231 if(rc < 0) {
232 zlog_err("read(random): %s", safe_strerror(errno));
233 seed = 42;
234 }
235
236 seed ^= (babel_now.tv_sec ^ babel_now.tv_usec);
237 srandom(seed);
238}
239
240/*
241 close fd, and replace it by "/dev/null"
242 exit if error
243 */
244static void
245babel_replace_by_null(int fd)
246{
247 int fd_null;
248 int rc;
249
250 fd_null = open("/dev/null", O_RDONLY);
251 if(fd_null < 0) {
252 zlog_err("open(null): %s", safe_strerror(errno));
253 exit(1);
254 }
255
256 rc = dup2(fd_null, fd);
257 if(rc < 0) {
258 zlog_err("dup2(null, 0): %s", safe_strerror(errno));
259 exit(1);
260 }
261
262 close(fd_null);
263}
264
265/*
266 Load the state file: check last babeld's running state, usefull in case of
267 "/etc/init.d/babeld restart"
268 */
269void
270babel_load_state_file(void)
271{
272 int fd;
273 int rc;
274
275 fd = open(state_file, O_RDONLY);
276 if(fd < 0 && errno != ENOENT)
277 zlog_err("open(babel-state: %s)", safe_strerror(errno));
278 rc = unlink(state_file);
279 if(fd >= 0 && rc < 0) {
280 zlog_err("unlink(babel-state): %s", safe_strerror(errno));
281 /* If we couldn't unlink it, it's probably stale. */
c31a793b 282 goto fini;
ca10883e
DS
283 }
284 if(fd >= 0) {
285 char buf[100];
286 char buf2[100];
287 int s;
288 long t;
289 rc = read(fd, buf, 99);
290 if(rc < 0) {
291 zlog_err("read(babel-state): %s", safe_strerror(errno));
292 } else {
293 buf[rc] = '\0';
294 rc = sscanf(buf, "%99s %d %ld\n", buf2, &s, &t);
295 if(rc == 3 && s >= 0 && s <= 0xFFFF) {
296 unsigned char sid[8];
297 rc = parse_eui64(buf2, sid);
298 if(rc < 0) {
299 zlog_err("Couldn't parse babel-state.");
300 } else {
301 struct timeval realnow;
302 debugf(BABEL_DEBUG_COMMON,
303 "Got %s %d %ld from babel-state.",
304 format_eui64(sid), s, t);
305 gettimeofday(&realnow, NULL);
306 if(memcmp(sid, myid, 8) == 0)
307 myseqno = seqno_plus(s, 1);
308 else
309 zlog_err("ID mismatch in babel-state. id=%s; old=%s",
310 format_eui64(myid),
311 format_eui64(sid));
312 }
313 } else {
314 zlog_err("Couldn't parse babel-state.");
315 }
316 }
c31a793b 317 goto fini;
ca10883e 318 }
c31a793b
VJ
319fini:
320 if (fd >= 0)
321 close(fd);
322 return ;
ca10883e
DS
323}
324
325static void
326babel_exit_properly(void)
327{
328 debugf(BABEL_DEBUG_COMMON, "Exiting...");
329 usleep(roughly(10000));
330 gettime(&babel_now);
331
332 /* Uninstall and flush all routes. */
333 debugf(BABEL_DEBUG_COMMON, "Uninstall routes.");
334 flush_all_routes();
335 babel_interface_close_all();
336 babel_zebra_close_connexion();
337 babel_save_state_file();
338 debugf(BABEL_DEBUG_COMMON, "Remove pid file.");
339 debugf(BABEL_DEBUG_COMMON, "Done.");
8879bd22 340 frr_fini();
ca10883e
DS
341
342 exit(0);
343}
344
345static void
346babel_save_state_file(void)
347{
348 int fd;
349 int rc;
350
351 debugf(BABEL_DEBUG_COMMON, "Save state file.");
352 fd = open(state_file, O_WRONLY | O_TRUNC | O_CREAT, 0644);
353 if(fd < 0) {
354 zlog_err("creat(babel-state): %s", safe_strerror(errno));
355 unlink(state_file);
356 } else {
357 struct timeval realnow;
358 char buf[100];
359 gettimeofday(&realnow, NULL);
360 rc = snprintf(buf, 100, "%s %d %ld\n",
361 format_eui64(myid), (int)myseqno,
362 (long)realnow.tv_sec);
363 if(rc < 0 || rc >= 100) {
364 zlog_err("write(babel-state): overflow.");
365 unlink(state_file);
366 } else {
367 rc = write(fd, buf, rc);
368 if(rc < 0) {
369 zlog_err("write(babel-state): %s", safe_strerror(errno));
370 unlink(state_file);
371 }
372 fsync(fd);
373 }
374 close(fd);
375 }
376}
377
378void
379show_babel_main_configuration (struct vty *vty)
380{
181039f3 381 vty_out (vty,
cdda2010
DL
382 "state file = %s\n"
383 "configuration file = %s\n"
384 "protocol informations:\n"
385 " multicast address = %s\n"
386 " port = %d\n"
387 "vty address = %s\n"
388 "vty port = %d\n"
389 "id = %s\n"
181039f3 390 "kernel_metric = %d\n",
cdda2010 391 state_file,
ca10883e 392 babel_config_file ? babel_config_file : babel_config_default,
cdda2010
DL
393 format_address(protocol_group),
394 protocol_port,
ca10883e 395 babel_vty_addr ? babel_vty_addr : "None",
cdda2010
DL
396 babel_vty_port,
397 format_eui64(myid),
96ade3ed 398 kernel_metric);
ca10883e 399}