1 // SPDX-License-Identifier: MIT
3 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
6 /* include zebra library */
14 #include "lib/version.h"
19 #include "lib_errors.h"
21 #include "babel_main.h"
25 #include "babel_interface.h"
26 #include "neighbour.h"
31 #include "babel_zebra.h"
32 #include "babel_errors.h"
34 static void babel_fail(void);
35 static void babel_init_random(void);
36 static void babel_exit_properly(void);
37 static void babel_save_state_file(void);
40 struct event_loop
*master
; /* quagga's threads handler */
41 struct timeval babel_now
; /* current time */
43 unsigned char myid
[8]; /* unique id (mac address of an interface) */
46 int resend_delay
= -1;
48 const unsigned char zeroes
[16] = {0};
49 const unsigned char ones
[16] =
50 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
51 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
53 static char state_file
[1024];
55 unsigned char protocol_group
[16]; /* babel's link-local multicast address */
56 int protocol_port
; /* babel's port */
57 int protocol_socket
= -1; /* socket: communicate with others babeld */
59 static const char babel_config_default
[] = SYSCONFDIR BABEL_DEFAULT_CONFIG
;
60 static char *babel_vty_addr
= NULL
;
61 static int babel_vty_port
= BABEL_VTY_PORT
;
63 /* babeld privileges */
64 static zebra_capabilities_t _caps_p
[] =
70 struct zebra_privs_t babeld_privs
=
79 .vty_group
= VTY_GROUP
,
82 .cap_num_p
= array_size(_caps_p
),
89 zlog_notice("Terminating on signal");
91 babel_exit_properly();
100 static struct frr_signal_t babel_signals
[] =
104 .handler
= &babel_sigusr1
,
108 .handler
= &babel_sigexit
,
112 .handler
= &babel_sigexit
,
116 struct option longopts
[] =
121 static const struct frr_yang_module_info
*const babeld_yang_modules
[] = {
127 FRR_DAEMON_INFO(babeld
, BABELD
,
128 .vty_port
= BABEL_VTY_PORT
,
129 .proghelp
= "Implementation of the BABEL routing protocol.",
131 .signals
= babel_signals
,
132 .n_signals
= array_size(babel_signals
),
134 .privs
= &babeld_privs
,
136 .yang_modules
= babeld_yang_modules
,
137 .n_yang_modules
= array_size(babeld_yang_modules
),
141 main(int argc
, char **argv
)
145 frr_preinit (&babeld_di
, argc
, argv
);
146 frr_opt_add ("", longopts
, "");
150 /* set the Babel's default link-local multicast address and Babel's port */
151 parse_address("ff02:0:0:0:0:0:1:6", protocol_group
, NULL
);
152 protocol_port
= 6696;
158 opt
= frr_getopt (argc
, argv
, NULL
);
172 snprintf(state_file
, sizeof(state_file
), "%s/%s",
173 frr_vtydir
, "babel-state");
175 /* create the threads handler */
176 master
= frr_init ();
181 resend_delay
= BABEL_DEFAULT_RESEND_DELAY
;
182 change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE
);
184 /* init some quagga's dependencies, and babeld's commands */
185 if_zapi_callbacks(babel_ifp_create
, babel_ifp_up
,
186 babel_ifp_down
, babel_ifp_destroy
);
187 babeld_quagga_init();
188 /* init zebra client's structure and it's commands */
189 /* this replace kernel_setup && kernel_setup_socket */
190 babelz_zebra_init ();
193 rc
= resize_receive_buffer(1500);
197 schedule_neighbours_check(5000, 1);
211 /* initialize random value, and set 'babel_now' by the way. */
213 babel_init_random(void)
219 rc
= read_random_bytes(&seed
, sizeof(seed
));
221 flog_err_sys(EC_LIB_SYSTEM_CALL
, "read(random): %s",
222 safe_strerror(errno
));
226 seed
^= (babel_now
.tv_sec
^ babel_now
.tv_usec
);
231 Load the state file: check last babeld's running state, usefull in case of
232 "/etc/init.d/babeld restart"
235 babel_load_state_file(void)
240 fd
= open(state_file
, O_RDONLY
);
241 if(fd
< 0 && errno
!= ENOENT
)
242 flog_err_sys(EC_LIB_SYSTEM_CALL
, "open(babel-state: %s)",
243 safe_strerror(errno
));
244 rc
= unlink(state_file
);
245 if(fd
>= 0 && rc
< 0) {
246 flog_err_sys(EC_LIB_SYSTEM_CALL
, "unlink(babel-state): %s",
247 safe_strerror(errno
));
248 /* If we couldn't unlink it, it's probably stale. */
256 rc
= read(fd
, buf
, 99);
258 flog_err_sys(EC_LIB_SYSTEM_CALL
, "read(babel-state): %s",
259 safe_strerror(errno
));
262 rc
= sscanf(buf
, "%99s %d %ld\n", buf2
, &s
, &t
);
263 if(rc
== 3 && s
>= 0 && s
<= 0xFFFF) {
264 unsigned char sid
[8];
265 rc
= parse_eui64(buf2
, sid
);
267 flog_err(EC_BABEL_CONFIG
, "Couldn't parse babel-state.");
269 struct timeval realnow
;
270 debugf(BABEL_DEBUG_COMMON
,
271 "Got %s %d %ld from babel-state.",
272 format_eui64(sid
), s
, t
);
273 gettimeofday(&realnow
, NULL
);
274 if(memcmp(sid
, myid
, 8) == 0)
275 myseqno
= seqno_plus(s
, 1);
277 flog_err(EC_BABEL_CONFIG
,
278 "ID mismatch in babel-state. id=%s; old=%s",
283 flog_err(EC_BABEL_CONFIG
, "Couldn't parse babel-state.");
295 babel_exit_properly(void)
297 debugf(BABEL_DEBUG_COMMON
, "Exiting...");
298 usleep(roughly(10000));
301 /* Uninstall and flush all routes. */
302 debugf(BABEL_DEBUG_COMMON
, "Uninstall routes.");
304 babel_interface_close_all();
305 babel_zebra_close_connexion();
306 babel_save_state_file();
307 debugf(BABEL_DEBUG_COMMON
, "Remove pid file.");
308 debugf(BABEL_DEBUG_COMMON
, "Done.");
315 babel_save_state_file(void)
320 debugf(BABEL_DEBUG_COMMON
, "Save state file.");
321 fd
= open(state_file
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0644);
323 flog_err_sys(EC_LIB_SYSTEM_CALL
, "creat(babel-state): %s",
324 safe_strerror(errno
));
327 struct timeval realnow
;
329 gettimeofday(&realnow
, NULL
);
330 rc
= snprintf(buf
, 100, "%s %d %ld\n",
331 format_eui64(myid
), (int)myseqno
,
332 (long)realnow
.tv_sec
);
333 if(rc
< 0 || rc
>= 100) {
334 flog_err(EC_BABEL_CONFIG
, "write(babel-state): overflow.");
337 rc
= write(fd
, buf
, rc
);
339 flog_err(EC_BABEL_CONFIG
, "write(babel-state): %s",
340 safe_strerror(errno
));
350 show_babel_main_configuration (struct vty
*vty
)
354 "configuration file = %s\n"
355 "protocol information:\n"
356 " multicast address = %s\n"
361 "kernel_metric = %d\n",
363 babeld_di
.config_file
? babeld_di
.config_file
: babel_config_default
,
364 format_address(protocol_group
),
366 babel_vty_addr
? babel_vty_addr
: "None",