2 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 /* include zebra library */
36 #include "lib_errors.h"
38 #include "babel_main.h"
42 #include "babel_interface.h"
43 #include "neighbour.h"
48 #include "babel_zebra.h"
49 #include "babel_errors.h"
51 static void babel_fail(void);
52 static void babel_init_random(void);
53 static void babel_replace_by_null(int fd
);
54 static void babel_exit_properly(void);
55 static void babel_save_state_file(void);
58 struct thread_master
*master
; /* quagga's threads handler */
59 struct timeval babel_now
; /* current time */
61 unsigned char myid
[8]; /* unique id (mac address of an interface) */
64 int resend_delay
= -1;
66 const unsigned char zeroes
[16] = {0};
67 const unsigned char ones
[16] =
68 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
69 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
71 static const char *state_file
= DAEMON_VTY_DIR
"/babel-state";
73 unsigned char protocol_group
[16]; /* babel's link-local multicast address */
74 int protocol_port
; /* babel's port */
75 int protocol_socket
= -1; /* socket: communicate with others babeld */
77 static char babel_config_default
[] = SYSCONFDIR BABEL_DEFAULT_CONFIG
;
78 static char *babel_vty_addr
= NULL
;
79 static int babel_vty_port
= BABEL_VTY_PORT
;
81 /* babeld privileges */
82 static zebra_capabilities_t _caps_p
[] =
88 struct zebra_privs_t babeld_privs
=
97 .vty_group
= VTY_GROUP
,
100 .cap_num_p
= array_size(_caps_p
),
107 zlog_notice("Terminating on signal");
109 babel_exit_properly();
118 static struct quagga_signal_t babel_signals
[] =
122 .handler
= &babel_sigusr1
,
126 .handler
= &babel_sigexit
,
130 .handler
= &babel_sigexit
,
134 struct option longopts
[] =
139 static const struct frr_yang_module_info
*babeld_yang_modules
[] =
144 FRR_DAEMON_INFO(babeld
, BABELD
,
145 .vty_port
= BABEL_VTY_PORT
,
146 .proghelp
= "Implementation of the BABEL routing protocol.",
148 .signals
= babel_signals
,
149 .n_signals
= array_size(babel_signals
),
151 .privs
= &babeld_privs
,
153 .yang_modules
= babeld_yang_modules
,
154 .n_yang_modules
= array_size(babeld_yang_modules
),
158 main(int argc
, char **argv
)
162 frr_preinit (&babeld_di
, argc
, argv
);
163 frr_opt_add ("", longopts
, "");
167 /* set the Babel's default link-local multicast address and Babel's port */
168 parse_address("ff02:0:0:0:0:0:1:6", protocol_group
, NULL
);
169 protocol_port
= 6696;
175 opt
= frr_getopt (argc
, argv
, NULL
);
190 /* create the threads handler */
191 master
= frr_init ();
196 resend_delay
= BABEL_DEFAULT_RESEND_DELAY
;
197 change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE
);
199 babel_replace_by_null(STDIN_FILENO
);
201 /* init some quagga's dependencies, and babeld's commands */
202 babeld_quagga_init();
203 /* init zebra client's structure and it's commands */
204 /* this replace kernel_setup && kernel_setup_socket */
205 babelz_zebra_init ();
208 rc
= resize_receive_buffer(1500);
212 schedule_neighbours_check(5000, 1);
226 /* initialize random value, and set 'babel_now' by the way. */
228 babel_init_random(void)
234 rc
= read_random_bytes(&seed
, sizeof(seed
));
236 flog_err_sys(EC_LIB_SYSTEM_CALL
, "read(random): %s",
237 safe_strerror(errno
));
241 seed
^= (babel_now
.tv_sec
^ babel_now
.tv_usec
);
246 close fd, and replace it by "/dev/null"
250 babel_replace_by_null(int fd
)
255 fd_null
= open("/dev/null", O_RDONLY
);
257 flog_err_sys(EC_LIB_SYSTEM_CALL
, "open(null): %s", safe_strerror(errno
));
261 rc
= dup2(fd_null
, fd
);
263 flog_err_sys(EC_LIB_SYSTEM_CALL
, "dup2(null, 0): %s",
264 safe_strerror(errno
));
272 Load the state file: check last babeld's running state, usefull in case of
273 "/etc/init.d/babeld restart"
276 babel_load_state_file(void)
281 fd
= open(state_file
, O_RDONLY
);
282 if(fd
< 0 && errno
!= ENOENT
)
283 flog_err_sys(EC_LIB_SYSTEM_CALL
, "open(babel-state: %s)",
284 safe_strerror(errno
));
285 rc
= unlink(state_file
);
286 if(fd
>= 0 && rc
< 0) {
287 flog_err_sys(EC_LIB_SYSTEM_CALL
, "unlink(babel-state): %s",
288 safe_strerror(errno
));
289 /* If we couldn't unlink it, it's probably stale. */
297 rc
= read(fd
, buf
, 99);
299 flog_err_sys(EC_LIB_SYSTEM_CALL
, "read(babel-state): %s",
300 safe_strerror(errno
));
303 rc
= sscanf(buf
, "%99s %d %ld\n", buf2
, &s
, &t
);
304 if(rc
== 3 && s
>= 0 && s
<= 0xFFFF) {
305 unsigned char sid
[8];
306 rc
= parse_eui64(buf2
, sid
);
308 flog_err(EC_BABEL_CONFIG
, "Couldn't parse babel-state.");
310 struct timeval realnow
;
311 debugf(BABEL_DEBUG_COMMON
,
312 "Got %s %d %ld from babel-state.",
313 format_eui64(sid
), s
, t
);
314 gettimeofday(&realnow
, NULL
);
315 if(memcmp(sid
, myid
, 8) == 0)
316 myseqno
= seqno_plus(s
, 1);
318 flog_err(EC_BABEL_CONFIG
,
319 "ID mismatch in babel-state. id=%s; old=%s",
324 flog_err(EC_BABEL_CONFIG
, "Couldn't parse babel-state.");
336 babel_exit_properly(void)
338 debugf(BABEL_DEBUG_COMMON
, "Exiting...");
339 usleep(roughly(10000));
342 /* Uninstall and flush all routes. */
343 debugf(BABEL_DEBUG_COMMON
, "Uninstall routes.");
345 babel_interface_close_all();
346 babel_zebra_close_connexion();
347 babel_save_state_file();
348 debugf(BABEL_DEBUG_COMMON
, "Remove pid file.");
349 debugf(BABEL_DEBUG_COMMON
, "Done.");
356 babel_save_state_file(void)
361 debugf(BABEL_DEBUG_COMMON
, "Save state file.");
362 fd
= open(state_file
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0644);
364 flog_err_sys(EC_LIB_SYSTEM_CALL
, "creat(babel-state): %s",
365 safe_strerror(errno
));
368 struct timeval realnow
;
370 gettimeofday(&realnow
, NULL
);
371 rc
= snprintf(buf
, 100, "%s %d %ld\n",
372 format_eui64(myid
), (int)myseqno
,
373 (long)realnow
.tv_sec
);
374 if(rc
< 0 || rc
>= 100) {
375 flog_err(EC_BABEL_CONFIG
, "write(babel-state): overflow.");
378 rc
= write(fd
, buf
, rc
);
380 flog_err(EC_BABEL_CONFIG
, "write(babel-state): %s",
381 safe_strerror(errno
));
391 show_babel_main_configuration (struct vty
*vty
)
395 "configuration file = %s\n"
396 "protocol information:\n"
397 " multicast address = %s\n"
402 "kernel_metric = %d\n",
404 babeld_di
.config_file
? babeld_di
.config_file
: babel_config_default
,
405 format_address(protocol_group
),
407 babel_vty_addr
? babel_vty_addr
: "None",