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 */
37 #include "babel_main.h"
41 #include "babel_interface.h"
42 #include "neighbour.h"
47 #include "babel_zebra.h"
49 static void babel_fail(void);
50 static void babel_init_random(void);
51 static void babel_replace_by_null(int fd
);
52 static void babel_exit_properly(void);
53 static void babel_save_state_file(void);
56 struct thread_master
*master
; /* quagga's threads handler */
57 struct timeval babel_now
; /* current time */
59 unsigned char myid
[8]; /* unique id (mac address of an interface) */
62 int resend_delay
= -1;
64 const unsigned char zeroes
[16] = {0};
65 const unsigned char ones
[16] =
66 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
67 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
69 static const char *state_file
= DAEMON_VTY_DIR
"/babel-state";
71 unsigned char protocol_group
[16]; /* babel's link-local multicast address */
72 int protocol_port
; /* babel's port */
73 int protocol_socket
= -1; /* socket: communicate with others babeld */
75 static char babel_config_default
[] = SYSCONFDIR BABEL_DEFAULT_CONFIG
;
76 static char *babel_config_file
= NULL
;
77 static char *babel_vty_addr
= NULL
;
78 static int babel_vty_port
= BABEL_VTY_PORT
;
80 /* babeld privileges */
81 static zebra_capabilities_t _caps_p
[] =
87 static struct zebra_privs_t babeld_privs
=
96 .vty_group
= VTY_GROUP
,
99 .cap_num_p
= array_size(_caps_p
),
106 zlog_notice("Terminating on signal");
108 babel_exit_properly();
117 static struct quagga_signal_t babel_signals
[] =
121 .handler
= &babel_sigusr1
,
125 .handler
= &babel_sigexit
,
129 .handler
= &babel_sigexit
,
133 struct option longopts
[] =
138 FRR_DAEMON_INFO(babeld
, BABELD
,
139 .vty_port
= BABEL_VTY_PORT
,
140 .proghelp
= "Implementation of the BABEL routing protocol.",
142 .signals
= babel_signals
,
143 .n_signals
= array_size(babel_signals
),
145 .privs
= &babeld_privs
,
149 main(int argc
, char **argv
)
153 frr_preinit (&babeld_di
, argc
, argv
);
154 frr_opt_add ("", longopts
, "");
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;
166 opt
= frr_getopt (argc
, argv
, NULL
);
181 /* create the threads handler */
182 master
= frr_init ();
185 zprivs_init (&babeld_privs
);
189 resend_delay
= BABEL_DEFAULT_RESEND_DELAY
;
190 change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE
);
192 babel_replace_by_null(STDIN_FILENO
);
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 ();
200 /* Get zebra configuration file. */
201 vty_read_config (babel_config_file
, babel_config_default
);
204 rc
= resize_receive_buffer(1500);
208 schedule_neighbours_check(5000, 1);
222 /* initialize random value, and set 'babel_now' by the way. */
224 babel_init_random(void)
230 rc
= read_random_bytes(&seed
, sizeof(seed
));
232 zlog_err("read(random): %s", safe_strerror(errno
));
236 seed
^= (babel_now
.tv_sec
^ babel_now
.tv_usec
);
241 close fd, and replace it by "/dev/null"
245 babel_replace_by_null(int fd
)
250 fd_null
= open("/dev/null", O_RDONLY
);
252 zlog_err("open(null): %s", safe_strerror(errno
));
256 rc
= dup2(fd_null
, fd
);
258 zlog_err("dup2(null, 0): %s", safe_strerror(errno
));
266 Load the state file: check last babeld's running state, usefull in case of
267 "/etc/init.d/babeld restart"
270 babel_load_state_file(void)
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. */
290 rc
= read(fd
, buf
, 99);
292 zlog_err("read(babel-state): %s", safe_strerror(errno
));
295 rc
= sscanf(buf
, "%99s %d %ld\n", buf2
, &s
, &t
);
296 if(rc
== 3 && s
>= 0 && s
<= 0xFFFF) {
297 unsigned char sid
[8];
298 rc
= parse_eui64(buf2
, sid
);
300 zlog_err("Couldn't parse babel-state.");
302 struct timeval realnow
;
303 debugf(BABEL_DEBUG_COMMON
,
304 "Got %s %d %ld from babel-state.",
305 format_eui64(sid
), s
, t
);
306 gettimeofday(&realnow
, NULL
);
307 if(memcmp(sid
, myid
, 8) == 0)
308 myseqno
= seqno_plus(s
, 1);
310 zlog_err("ID mismatch in babel-state. id=%s; old=%s",
315 zlog_err("Couldn't parse babel-state.");
324 babel_exit_properly(void)
326 debugf(BABEL_DEBUG_COMMON
, "Exiting...");
327 usleep(roughly(10000));
330 /* Uninstall and flush all routes. */
331 debugf(BABEL_DEBUG_COMMON
, "Uninstall routes.");
333 babel_interface_close_all();
334 babel_zebra_close_connexion();
335 babel_save_state_file();
336 debugf(BABEL_DEBUG_COMMON
, "Remove pid file.");
337 debugf(BABEL_DEBUG_COMMON
, "Done.");
344 babel_save_state_file(void)
349 debugf(BABEL_DEBUG_COMMON
, "Save state file.");
350 fd
= open(state_file
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0644);
352 zlog_err("creat(babel-state): %s", safe_strerror(errno
));
355 struct timeval realnow
;
357 gettimeofday(&realnow
, NULL
);
358 rc
= snprintf(buf
, 100, "%s %d %ld\n",
359 format_eui64(myid
), (int)myseqno
,
360 (long)realnow
.tv_sec
);
361 if(rc
< 0 || rc
>= 100) {
362 zlog_err("write(babel-state): overflow.");
365 rc
= write(fd
, buf
, rc
);
367 zlog_err("write(babel-state): %s", safe_strerror(errno
));
377 show_babel_main_configuration (struct vty
*vty
)
381 "configuration file = %s\n"
382 "protocol informations:\n"
383 " multicast address = %s\n"
388 "kernel_metric = %d\n",
390 babel_config_file
? babel_config_file
: babel_config_default
,
391 format_address(protocol_group
),
393 babel_vty_addr
? babel_vty_addr
: "None",