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 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
*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
);
191 snprintf(state_file
, sizeof(state_file
), "%s/%s",
192 frr_vtydir
, "babel-state");
194 /* create the threads handler */
195 master
= frr_init ();
200 resend_delay
= BABEL_DEFAULT_RESEND_DELAY
;
201 change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE
);
203 babel_replace_by_null(STDIN_FILENO
);
205 /* init some quagga's dependencies, and babeld's commands */
206 if_zapi_callbacks(babel_ifp_create
, babel_ifp_up
,
207 babel_ifp_down
, babel_ifp_destroy
);
208 babeld_quagga_init();
209 /* init zebra client's structure and it's commands */
210 /* this replace kernel_setup && kernel_setup_socket */
211 babelz_zebra_init ();
214 rc
= resize_receive_buffer(1500);
218 schedule_neighbours_check(5000, 1);
232 /* initialize random value, and set 'babel_now' by the way. */
234 babel_init_random(void)
240 rc
= read_random_bytes(&seed
, sizeof(seed
));
242 flog_err_sys(EC_LIB_SYSTEM_CALL
, "read(random): %s",
243 safe_strerror(errno
));
247 seed
^= (babel_now
.tv_sec
^ babel_now
.tv_usec
);
252 close fd, and replace it by "/dev/null"
256 babel_replace_by_null(int fd
)
261 fd_null
= open("/dev/null", O_RDONLY
);
263 flog_err_sys(EC_LIB_SYSTEM_CALL
, "open(null): %s", safe_strerror(errno
));
267 rc
= dup2(fd_null
, fd
);
269 flog_err_sys(EC_LIB_SYSTEM_CALL
, "dup2(null, 0): %s",
270 safe_strerror(errno
));
278 Load the state file: check last babeld's running state, usefull in case of
279 "/etc/init.d/babeld restart"
282 babel_load_state_file(void)
287 fd
= open(state_file
, O_RDONLY
);
288 if(fd
< 0 && errno
!= ENOENT
)
289 flog_err_sys(EC_LIB_SYSTEM_CALL
, "open(babel-state: %s)",
290 safe_strerror(errno
));
291 rc
= unlink(state_file
);
292 if(fd
>= 0 && rc
< 0) {
293 flog_err_sys(EC_LIB_SYSTEM_CALL
, "unlink(babel-state): %s",
294 safe_strerror(errno
));
295 /* If we couldn't unlink it, it's probably stale. */
303 rc
= read(fd
, buf
, 99);
305 flog_err_sys(EC_LIB_SYSTEM_CALL
, "read(babel-state): %s",
306 safe_strerror(errno
));
309 rc
= sscanf(buf
, "%99s %d %ld\n", buf2
, &s
, &t
);
310 if(rc
== 3 && s
>= 0 && s
<= 0xFFFF) {
311 unsigned char sid
[8];
312 rc
= parse_eui64(buf2
, sid
);
314 flog_err(EC_BABEL_CONFIG
, "Couldn't parse babel-state.");
316 struct timeval realnow
;
317 debugf(BABEL_DEBUG_COMMON
,
318 "Got %s %d %ld from babel-state.",
319 format_eui64(sid
), s
, t
);
320 gettimeofday(&realnow
, NULL
);
321 if(memcmp(sid
, myid
, 8) == 0)
322 myseqno
= seqno_plus(s
, 1);
324 flog_err(EC_BABEL_CONFIG
,
325 "ID mismatch in babel-state. id=%s; old=%s",
330 flog_err(EC_BABEL_CONFIG
, "Couldn't parse babel-state.");
342 babel_exit_properly(void)
344 debugf(BABEL_DEBUG_COMMON
, "Exiting...");
345 usleep(roughly(10000));
348 /* Uninstall and flush all routes. */
349 debugf(BABEL_DEBUG_COMMON
, "Uninstall routes.");
351 babel_interface_close_all();
352 babel_zebra_close_connexion();
353 babel_save_state_file();
354 debugf(BABEL_DEBUG_COMMON
, "Remove pid file.");
355 debugf(BABEL_DEBUG_COMMON
, "Done.");
362 babel_save_state_file(void)
367 debugf(BABEL_DEBUG_COMMON
, "Save state file.");
368 fd
= open(state_file
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0644);
370 flog_err_sys(EC_LIB_SYSTEM_CALL
, "creat(babel-state): %s",
371 safe_strerror(errno
));
374 struct timeval realnow
;
376 gettimeofday(&realnow
, NULL
);
377 rc
= snprintf(buf
, 100, "%s %d %ld\n",
378 format_eui64(myid
), (int)myseqno
,
379 (long)realnow
.tv_sec
);
380 if(rc
< 0 || rc
>= 100) {
381 flog_err(EC_BABEL_CONFIG
, "write(babel-state): overflow.");
384 rc
= write(fd
, buf
, rc
);
386 flog_err(EC_BABEL_CONFIG
, "write(babel-state): %s",
387 safe_strerror(errno
));
397 show_babel_main_configuration (struct vty
*vty
)
401 "configuration file = %s\n"
402 "protocol information:\n"
403 " multicast address = %s\n"
408 "kernel_metric = %d\n",
410 babeld_di
.config_file
? babeld_di
.config_file
: babel_config_default
,
411 format_address(protocol_group
),
413 babel_vty_addr
? babel_vty_addr
: "None",