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 */
31 #include "lib/version.h"
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 char state_file
[1024];
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 const 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 frr_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
*const babeld_yang_modules
[] = {
145 FRR_DAEMON_INFO(babeld
, BABELD
,
146 .vty_port
= BABEL_VTY_PORT
,
147 .proghelp
= "Implementation of the BABEL routing protocol.",
149 .signals
= babel_signals
,
150 .n_signals
= array_size(babel_signals
),
152 .privs
= &babeld_privs
,
154 .yang_modules
= babeld_yang_modules
,
155 .n_yang_modules
= array_size(babeld_yang_modules
),
159 main(int argc
, char **argv
)
163 frr_preinit (&babeld_di
, argc
, argv
);
164 frr_opt_add ("", longopts
, "");
168 /* set the Babel's default link-local multicast address and Babel's port */
169 parse_address("ff02:0:0:0:0:0:1:6", protocol_group
, NULL
);
170 protocol_port
= 6696;
176 opt
= frr_getopt (argc
, argv
, NULL
);
190 snprintf(state_file
, sizeof(state_file
), "%s/%s",
191 frr_vtydir
, "babel-state");
193 /* create the threads handler */
194 master
= frr_init ();
199 resend_delay
= BABEL_DEFAULT_RESEND_DELAY
;
200 change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE
);
202 babel_replace_by_null(STDIN_FILENO
);
204 /* init some quagga's dependencies, and babeld's commands */
205 if_zapi_callbacks(babel_ifp_create
, babel_ifp_up
,
206 babel_ifp_down
, babel_ifp_destroy
);
207 babeld_quagga_init();
208 /* init zebra client's structure and it's commands */
209 /* this replace kernel_setup && kernel_setup_socket */
210 babelz_zebra_init ();
213 rc
= resize_receive_buffer(1500);
217 schedule_neighbours_check(5000, 1);
231 /* initialize random value, and set 'babel_now' by the way. */
233 babel_init_random(void)
239 rc
= read_random_bytes(&seed
, sizeof(seed
));
241 flog_err_sys(EC_LIB_SYSTEM_CALL
, "read(random): %s",
242 safe_strerror(errno
));
246 seed
^= (babel_now
.tv_sec
^ babel_now
.tv_usec
);
251 close fd, and replace it by "/dev/null"
255 babel_replace_by_null(int fd
)
260 fd_null
= open("/dev/null", O_RDONLY
);
262 flog_err_sys(EC_LIB_SYSTEM_CALL
, "open(null): %s", safe_strerror(errno
));
266 rc
= dup2(fd_null
, fd
);
268 flog_err_sys(EC_LIB_SYSTEM_CALL
, "dup2(null, 0): %s",
269 safe_strerror(errno
));
277 Load the state file: check last babeld's running state, usefull in case of
278 "/etc/init.d/babeld restart"
281 babel_load_state_file(void)
286 fd
= open(state_file
, O_RDONLY
);
287 if(fd
< 0 && errno
!= ENOENT
)
288 flog_err_sys(EC_LIB_SYSTEM_CALL
, "open(babel-state: %s)",
289 safe_strerror(errno
));
290 rc
= unlink(state_file
);
291 if(fd
>= 0 && rc
< 0) {
292 flog_err_sys(EC_LIB_SYSTEM_CALL
, "unlink(babel-state): %s",
293 safe_strerror(errno
));
294 /* If we couldn't unlink it, it's probably stale. */
302 rc
= read(fd
, buf
, 99);
304 flog_err_sys(EC_LIB_SYSTEM_CALL
, "read(babel-state): %s",
305 safe_strerror(errno
));
308 rc
= sscanf(buf
, "%99s %d %ld\n", buf2
, &s
, &t
);
309 if(rc
== 3 && s
>= 0 && s
<= 0xFFFF) {
310 unsigned char sid
[8];
311 rc
= parse_eui64(buf2
, sid
);
313 flog_err(EC_BABEL_CONFIG
, "Couldn't parse babel-state.");
315 struct timeval realnow
;
316 debugf(BABEL_DEBUG_COMMON
,
317 "Got %s %d %ld from babel-state.",
318 format_eui64(sid
), s
, t
);
319 gettimeofday(&realnow
, NULL
);
320 if(memcmp(sid
, myid
, 8) == 0)
321 myseqno
= seqno_plus(s
, 1);
323 flog_err(EC_BABEL_CONFIG
,
324 "ID mismatch in babel-state. id=%s; old=%s",
329 flog_err(EC_BABEL_CONFIG
, "Couldn't parse babel-state.");
341 babel_exit_properly(void)
343 debugf(BABEL_DEBUG_COMMON
, "Exiting...");
344 usleep(roughly(10000));
347 /* Uninstall and flush all routes. */
348 debugf(BABEL_DEBUG_COMMON
, "Uninstall routes.");
350 babel_interface_close_all();
351 babel_zebra_close_connexion();
352 babel_save_state_file();
353 debugf(BABEL_DEBUG_COMMON
, "Remove pid file.");
354 debugf(BABEL_DEBUG_COMMON
, "Done.");
361 babel_save_state_file(void)
366 debugf(BABEL_DEBUG_COMMON
, "Save state file.");
367 fd
= open(state_file
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0644);
369 flog_err_sys(EC_LIB_SYSTEM_CALL
, "creat(babel-state): %s",
370 safe_strerror(errno
));
373 struct timeval realnow
;
375 gettimeofday(&realnow
, NULL
);
376 rc
= snprintf(buf
, 100, "%s %d %ld\n",
377 format_eui64(myid
), (int)myseqno
,
378 (long)realnow
.tv_sec
);
379 if(rc
< 0 || rc
>= 100) {
380 flog_err(EC_BABEL_CONFIG
, "write(babel-state): overflow.");
383 rc
= write(fd
, buf
, rc
);
385 flog_err(EC_BABEL_CONFIG
, "write(babel-state): %s",
386 safe_strerror(errno
));
396 show_babel_main_configuration (struct vty
*vty
)
400 "configuration file = %s\n"
401 "protocol information:\n"
402 " multicast address = %s\n"
407 "kernel_metric = %d\n",
409 babeld_di
.config_file
? babeld_di
.config_file
: babel_config_default
,
410 format_address(protocol_group
),
412 babel_vty_addr
? babel_vty_addr
: "None",