1 /*
2 Copyright (c) 2007, 2008 by Juliusz Chroboczek
3 Copyright (c) 2010 by Vincent Gross
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 THE SOFTWARE.
22 */
23
24 #include <string.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <sys/time.h>
32 #include <time.h>
33 #include <signal.h>
34 #include <assert.h>
35
36 #include <sys/ioctl.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <net/if.h>
40 #include <arpa/inet.h>
41
42 #include "babeld.h"
43 #include "util.h"
44 #include "net.h"
45 #include "kernel.h"
46 #include "interface.h"
47 #include "source.h"
48 #include "neighbour.h"
49 #include "route.h"
50 #include "xroute.h"
51 #include "message.h"
52 #include "resend.h"
53 #include "configuration.h"
54 #include "local.h"
55 #include "version.h"
56
57 struct timeval now;
58
59 unsigned char myid[8];
60 int have_id = 0;
61 int debug = 0;
62
63 int link_detect = 0;
64 int all_wireless = 0;
65 int has_ipv6_subtrees = 0;
66 int default_wireless_hello_interval = -1;
67 int default_wired_hello_interval = -1;
68 int resend_delay = -1;
69 int random_id = 0;
70 int do_daemonise = 0;
71 int skip_kernel_setup = 0;
72 const char *logfile = NULL,
73 *pidfile = "/var/run/babeld.pid",
74 *state_file = "/var/lib/babel-state";
75
76 unsigned char *receive_buffer = NULL;
77 int receive_buffer_size = 0;
78
79 const unsigned char zeroes[16] = {0};
80 const unsigned char ones[16] =
81 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
82 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
83
84 int protocol_port;
85 unsigned char protocol_group[16];
86 int protocol_socket = -1;
87 int kernel_socket = -1;
88 static int kernel_routes_changed = 0;
89 static int kernel_link_changed = 0;
90 static int kernel_addr_changed = 0;
91
92 struct timeval check_neighbours_timeout, check_interfaces_timeout;
93
94 static volatile sig_atomic_t exiting = 0, dumping = 0, reopening = 0;
95
96 static int accept_local_connections(void);
97 static void init_signals(void);
98 static void dump_tables(FILE *out);
99
100 static int
kernel_route_notify(struct kernel_route * route,void * closure)101 kernel_route_notify(struct kernel_route *route, void *closure)
102 {
103 kernel_routes_changed = 1;
104 return -1;
105 }
106
107 static int
kernel_addr_notify(struct kernel_addr * addr,void * closure)108 kernel_addr_notify(struct kernel_addr *addr, void *closure)
109 {
110 kernel_addr_changed = 1;
111 return -1;
112 }
113
114 static int
kernel_link_notify(struct kernel_link * link,void * closure)115 kernel_link_notify(struct kernel_link *link, void *closure)
116 {
117 struct interface *ifp;
118 FOR_ALL_INTERFACES(ifp) {
119 if(strcmp(ifp->name, link->ifname) == 0) {
120 kernel_link_changed = 1;
121 return -1;
122 }
123 }
124 return 0;
125 }
126
127 int
main(int argc,char ** argv)128 main(int argc, char **argv)
129 {
130 struct sockaddr_in6 sin6;
131 int rc, fd, i, opt;
132 time_t expiry_time, source_expiry_time, kernel_dump_time;
133 const char **config_files = NULL;
134 int num_config_files = 0;
135 void *vrc;
136 unsigned int seed;
137 struct interface *ifp;
138
139 gettime(&now);
140
141 rc = read_random_bytes(&seed, sizeof(seed));
142 if(rc < 0) {
143 perror("read(random)");
144 seed = 42;
145 }
146
147 seed ^= (now.tv_sec ^ now.tv_usec);
148 srandom(seed);
149
150 parse_address("ff02:0:0:0:0:0:1:6", protocol_group, NULL);
151 protocol_port = 6696;
152 change_smoothing_half_life(4);
153 has_ipv6_subtrees = kernel_has_ipv6_subtrees();
154
155 while(1) {
156 opt = getopt(argc, argv,
157 "m:p:h:H:i:k:A:srS:d:g:G:lwz:M:t:T:c:C:DL:I:V");
158 if(opt < 0)
159 break;
160
161 switch(opt) {
162 case 'm':
163 rc = parse_address(optarg, protocol_group, NULL);
164 if(rc < 0)
165 goto usage;
166 if(protocol_group[0] != 0xff) {
167 fprintf(stderr,
168 "%s is not a multicast address\n", optarg);
169 goto usage;
170 }
171 if(protocol_group[1] != 2) {
172 fprintf(stderr,
173 "Warning: %s is not a link-local multicast address\n",
174 optarg);
175 }
176 break;
177 case 'p':
178 protocol_port = parse_nat(optarg);
179 if(protocol_port <= 0 || protocol_port > 0xFFFF)
180 goto usage;
181 break;
182 case 'h':
183 default_wireless_hello_interval = parse_thousands(optarg);
184 if(default_wireless_hello_interval <= 0 ||
185 default_wireless_hello_interval > 0xFFFF * 10)
186 goto usage;
187 break;
188 case 'H':
189 default_wired_hello_interval = parse_thousands(optarg);
190 if(default_wired_hello_interval <= 0 ||
191 default_wired_hello_interval > 0xFFFF * 10)
192 goto usage;
193 break;
194 case 'k':
195 kernel_metric = parse_nat(optarg);
196 if(kernel_metric < 0 || kernel_metric > 0xFFFF)
197 goto usage;
198 break;
199 case 'A':
200 allow_duplicates = parse_nat(optarg);
201 if(allow_duplicates < 0 || allow_duplicates > 0xFFFF)
202 goto usage;
203 break;
204 case 's':
205 split_horizon = 0;
206 break;
207 case 'r':
208 random_id = 1;
209 break;
210 case 'S':
211 state_file = optarg;
212 break;
213 case 'd':
214 debug = parse_nat(optarg);
215 if(debug < 0)
216 goto usage;
217 break;
218 case 'g':
219 case 'G':
220 if(opt == 'g')
221 local_server_write = 0;
222 else
223 local_server_write = 1;
224 if(optarg[0] == '/') {
225 local_server_port = -1;
226 free(local_server_path);
227 local_server_path = strdup(optarg);
228 } else {
229 local_server_port = parse_nat(optarg);
230 free(local_server_path);
231 local_server_path = NULL;
232 if(local_server_port <= 0 || local_server_port > 0xFFFF)
233 goto usage;
234 }
235 break;
236 case 'l':
237 link_detect = 1;
238 break;
239 case 'w':
240 all_wireless = 1;
241 break;
242 case 'z':
243 {
244 char *comma;
245 diversity_kind = (int)strtol(optarg, &comma, 0);
246 if(*comma == '\0')
247 diversity_factor = 128;
248 else if(*comma == ',')
249 diversity_factor = parse_nat(comma + 1);
250 else
251 goto usage;
252 if(diversity_factor <= 0 || diversity_factor > 256)
253 goto usage;
254 }
255 break;
256 case 'M': {
257 int l = parse_nat(optarg);
258 if(l < 0 || l > 3600)
259 goto usage;
260 change_smoothing_half_life(l);
261 break;
262 }
263 case 't':
264 export_table = parse_nat(optarg);
265 if(export_table < 0 || export_table > 0xFFFF)
266 goto usage;
267 break;
268 case 'T':
269 if(add_import_table(parse_nat(optarg)))
270 goto usage;
271 break;
272 case 'c':
273 config_files = realloc(config_files,
274 (num_config_files + 1) * sizeof(char*));
275 if(config_files == NULL) {
276 fprintf(stderr, "Couldn't allocate config file.\n");
277 exit(1);
278 }
279 config_files[num_config_files++] = optarg;
280 break;
281 case 'C':
282 rc = parse_config_from_string(optarg, strlen(optarg), NULL);
283 if(rc != CONFIG_ACTION_DONE) {
284 fprintf(stderr,
285 "Couldn't parse configuration from command line.\n");
286 exit(1);
287 }
288 break;
289 case 'D':
290 do_daemonise = 1;
291 break;
292 case 'L':
293 logfile = optarg;
294 break;
295 case 'I':
296 pidfile = optarg;
297 break;
298 case 'V':
299 fprintf(stderr, "%s\n", BABELD_VERSION);
300 exit(0);
301 break;
302 default:
303 goto usage;
304 }
305 }
306
307 if(num_config_files == 0) {
308 if(access("/etc/babeld.conf", F_OK) >= 0) {
309 config_files = malloc(sizeof(char*));
310 if(config_files == NULL) {
311 fprintf(stderr, "Couldn't allocate config file.\n");
312 exit(1);
313 }
314 config_files[num_config_files++] = "/etc/babeld.conf";
315 }
316 }
317
318 for(i = 0; i < num_config_files; i++) {
319 int line;
320 rc = parse_config_from_file(config_files[i], &line);
321 if(rc < 0) {
322 fprintf(stderr,
323 "Couldn't parse configuration from file %s "
324 "(error at line %d).\n",
325 config_files[i], line);
326 exit(1);
327 }
328 }
329
330 free(config_files);
331
332 if(default_wireless_hello_interval <= 0)
333 default_wireless_hello_interval = 4000;
334 default_wireless_hello_interval = MAX(default_wireless_hello_interval, 5);
335
336 if(default_wired_hello_interval <= 0)
337 default_wired_hello_interval = 4000;
338 default_wired_hello_interval = MAX(default_wired_hello_interval, 5);
339
340 resend_delay = 2000;
341 resend_delay = MIN(resend_delay, default_wireless_hello_interval / 2);
342 resend_delay = MIN(resend_delay, default_wired_hello_interval / 2);
343 resend_delay = MAX(resend_delay, 20);
344
345 if(do_daemonise) {
346 if(logfile == NULL)
347 logfile = "/var/log/babeld.log";
348 }
349
350 rc = reopen_logfile();
351 if(rc < 0) {
352 perror("reopen_logfile()");
353 exit(1);
354 }
355
356 fd = open("/dev/null", O_RDONLY);
357 if(fd < 0) {
358 perror("open(null)");
359 exit(1);
360 }
361
362 rc = dup2(fd, 0);
363 if(rc < 0) {
364 perror("dup2(null, 0)");
365 exit(1);
366 }
367
368 close(fd);
369
370 if(do_daemonise) {
371 rc = daemonise();
372 if(rc < 0) {
373 perror("daemonise");
374 exit(1);
375 }
376 }
377
378 if(pidfile && pidfile[0] != '\0') {
379 int pfd, len;
380 char buf[100];
381
382 len = snprintf(buf, 100, "%lu", (unsigned long)getpid());
383 if(len < 0 || len >= 100) {
384 perror("snprintf(getpid)");
385 exit(1);
386 }
387
388 pfd = open(pidfile, O_WRONLY | O_CREAT | O_EXCL, 0644);
389 if(pfd < 0) {
390 char buf[40];
391 snprintf(buf, 40, "creat(%s)", pidfile);
392 buf[39] = '\0';
393 perror(buf);
394 exit(1);
395 }
396
397 rc = write(pfd, buf, len);
398 if(rc < len) {
399 perror("write(pidfile)");
400 goto fail_pid;
401 }
402
403 close(pfd);
404 }
405
406 rc = kernel_setup(1);
407 if(rc < 0) {
408 fprintf(stderr, "kernel_setup failed.\n");
409 goto fail_pid;
410 }
411
412 rc = kernel_setup_socket(1);
413 if(rc < 0) {
414 fprintf(stderr, "kernel_setup_socket failed.\n");
415 kernel_setup(0);
416 goto fail_pid;
417 }
418
419 rc = finalise_config();
420 if(rc < 0) {
421 fprintf(stderr, "Couldn't finalise configuration.\n");
422 goto fail;
423 }
424
425 for(i = optind; i < argc; i++) {
426 vrc = add_interface(argv[i], NULL);
427 if(vrc == NULL)
428 goto fail;
429 }
430
431 if(interfaces == NULL) {
432 fprintf(stderr, "Eek... asked to run on no interfaces!\n");
433 goto fail;
434 }
435
436 if(!have_id && !random_id) {
437 /* We use all available interfaces here, since this increases the
438 chances of getting a stable router-id in case the set of Babel
439 interfaces changes. */
440
441 for(i = 1; i < 256; i++) {
442 char buf[IF_NAMESIZE], *ifname;
443 unsigned char eui[8];
444 ifname = if_indextoname(i, buf);
445 if(ifname == NULL)
446 continue;
447 rc = if_eui64(ifname, i, eui);
448 if(rc < 0)
449 continue;
450 memcpy(myid, eui, 8);
451 have_id = 1;
452 break;
453 }
454 }
455
456 if(!have_id) {
457 if(!random_id)
458 fprintf(stderr,
459 "Warning: couldn't find router id -- "
460 "using random value.\n");
461 rc = read_random_bytes(myid, 8);
462 if(rc < 0) {
463 perror("read(random)");
464 goto fail;
465 }
466 /* Clear group and global bits */
467 myid[0] &= ~3;
468 }
469
470 myseqno = (random() & 0xFFFF);
471
472 fd = open(state_file, O_RDONLY);
473 if(fd < 0 && errno != ENOENT)
474 perror("open(babel-state)");
475 rc = unlink(state_file);
476 if(fd >= 0 && rc < 0) {
477 perror("unlink(babel-state)");
478 /* If we couldn't unlink it, it's probably stale. */
479 close(fd);
480 fd = -1;
481 }
482 if(fd >= 0) {
483 char buf[100];
484 int s;
485 rc = read(fd, buf, 99);
486 if(rc < 0) {
487 perror("read(babel-state)");
488 } else {
489 buf[rc] = '\0';
490 rc = sscanf(buf, "%d\n", &s);
491 if(rc == 1 && s >= 0 && s <= 0xFFFF) {
492 myseqno = seqno_plus(s, 1);
493 } else {
494 fprintf(stderr, "Couldn't parse babel-state.\n");
495 }
496 }
497 close(fd);
498 fd = -1;
499 }
500
501 protocol_socket = babel_socket(protocol_port);
502 if(protocol_socket < 0) {
503 perror("Couldn't create link local socket");
504 goto fail;
505 }
506
507 if(local_server_port >= 0) {
508 local_server_socket = tcp_server_socket(local_server_port, 1);
509 if(local_server_socket < 0) {
510 perror("local_server_socket");
511 goto fail;
512 }
513 } else if(local_server_path) {
514 local_server_socket = unix_server_socket(local_server_path);
515 if(local_server_socket < 0) {
516 perror("local_server_socket");
517 goto fail;
518 }
519 }
520
521 init_signals();
522 rc = resize_receive_buffer(1500);
523 if(rc < 0)
524 goto fail;
525 if(receive_buffer == NULL)
526 goto fail;
527
528 check_interfaces();
529
530 rc = check_xroutes(0);
531 if(rc < 0)
532 fprintf(stderr, "Warning: couldn't check exported routes.\n");
533
534 kernel_routes_changed = 0;
535 kernel_link_changed = 0;
536 kernel_addr_changed = 0;
537 kernel_dump_time = now.tv_sec + roughly(30);
538 schedule_neighbours_check(5000, 1);
539 schedule_interfaces_check(30000, 1);
540 expiry_time = now.tv_sec + roughly(30);
541 source_expiry_time = now.tv_sec + roughly(300);
542
543 /* Make some noise so that others notice us, and send retractions in
544 case we were restarted recently */
545 FOR_ALL_INTERFACES(ifp) {
546 if(!if_up(ifp))
547 continue;
548 /* Apply jitter before we send the first message. */
549 usleep(roughly(10000));
550 gettime(&now);
551 send_hello(ifp);
552 send_wildcard_retraction(ifp);
553 flushupdates(ifp);
554 flushbuf(&ifp->buf, ifp);
555 }
556
557 FOR_ALL_INTERFACES(ifp) {
558 if(!if_up(ifp))
559 continue;
560 usleep(roughly(10000));
561 gettime(&now);
562 send_hello(ifp);
563 send_wildcard_retraction(ifp);
564 send_self_update(ifp);
565 send_multicast_request(ifp, NULL, 0, NULL, 0);
566 flushupdates(ifp);
567 flushbuf(&ifp->buf, ifp);
568 }
569
570 debugf("Entering main loop.\n");
571
572 while(1) {
573 struct timeval tv;
574 fd_set readfds;
575 struct neighbour *neigh;
576
577 gettime(&now);
578
579 tv = check_neighbours_timeout;
580 timeval_min(&tv, &check_interfaces_timeout);
581 timeval_min_sec(&tv, expiry_time);
582 timeval_min_sec(&tv, source_expiry_time);
583 timeval_min_sec(&tv, kernel_dump_time);
584 timeval_min(&tv, &resend_time);
585 FOR_ALL_INTERFACES(ifp) {
586 if(!if_up(ifp))
587 continue;
588 timeval_min(&tv, &ifp->buf.timeout);
589 timeval_min(&tv, &ifp->hello_timeout);
590 timeval_min(&tv, &ifp->update_timeout);
591 timeval_min(&tv, &ifp->update_flush_timeout);
592 }
593 FOR_ALL_NEIGHBOURS(neigh) {
594 timeval_min(&tv, &neigh->buf.timeout);
595 }
596 FD_ZERO(&readfds);
597 if(timeval_compare(&tv, &now) > 0) {
598 int maxfd = 0;
599 timeval_minus(&tv, &tv, &now);
600 FD_SET(protocol_socket, &readfds);
601 maxfd = MAX(maxfd, protocol_socket);
602 if(kernel_socket < 0) kernel_setup_socket(1);
603 if(kernel_socket >= 0) {
604 FD_SET(kernel_socket, &readfds);
605 maxfd = MAX(maxfd, kernel_socket);
606 }
607 if(local_server_socket >= 0 &&
608 num_local_sockets < MAX_LOCAL_SOCKETS) {
609 FD_SET(local_server_socket, &readfds);
610 maxfd = MAX(maxfd, local_server_socket);
611 }
612 for(i = 0; i < num_local_sockets; i++) {
613 FD_SET(local_sockets[i].fd, &readfds);
614 maxfd = MAX(maxfd, local_sockets[i].fd);
615 }
616 rc = select(maxfd + 1, &readfds, NULL, NULL, &tv);
617 if(rc < 0) {
618 if(errno != EINTR) {
619 perror("select");
620 sleep(1);
621 }
622 rc = 0;
623 FD_ZERO(&readfds);
624 }
625 }
626
627 gettime(&now);
628
629 if(exiting)
630 break;
631
632 if(kernel_socket >= 0 && FD_ISSET(kernel_socket, &readfds)) {
633 struct kernel_filter filter = {0};
634 filter.route = kernel_route_notify;
635 filter.addr = kernel_addr_notify;
636 filter.link = kernel_link_notify;
637 kernel_callback(&filter);
638 }
639
640 if(FD_ISSET(protocol_socket, &readfds)) {
641 rc = babel_recv(protocol_socket,
642 receive_buffer, receive_buffer_size,
643 (struct sockaddr*)&sin6, sizeof(sin6));
644 if(rc < 0) {
645 if(errno != EAGAIN && errno != EINTR) {
646 perror("recv");
647 sleep(1);
648 }
649 } else {
650 FOR_ALL_INTERFACES(ifp) {
651 if(!if_up(ifp))
652 continue;
653 if(ifp->ifindex == sin6.sin6_scope_id) {
654 parse_packet((unsigned char*)&sin6.sin6_addr, ifp,
655 receive_buffer, rc);
656 VALGRIND_MAKE_MEM_UNDEFINED(receive_buffer,
657 receive_buffer_size);
658 break;
659 }
660 }
661 }
662 }
663
664 if(local_server_socket >= 0 && FD_ISSET(local_server_socket, &readfds))
665 accept_local_connections();
666
667 i = 0;
668 while(i < num_local_sockets) {
669 if(FD_ISSET(local_sockets[i].fd, &readfds)) {
670 rc = local_read(&local_sockets[i]);
671 if(rc <= 0) {
672 if(rc < 0) {
673 if(errno == EINTR || errno == EAGAIN)
674 continue;
675 perror("read(local_socket)");
676 }
677 local_socket_destroy(i);
678 }
679 }
680 i++;
681 }
682
683 if(reopening) {
684 kernel_dump_time = now.tv_sec;
685 check_neighbours_timeout = now;
686 expiry_time = now.tv_sec;
687 rc = reopen_logfile();
688 if(rc < 0) {
689 perror("reopen_logfile");
690 break;
691 }
692 reopening = 0;
693 }
694
695 if(kernel_link_changed || kernel_addr_changed) {
696 check_interfaces();
697 kernel_link_changed = 0;
698 }
699
700 if(kernel_routes_changed || kernel_addr_changed ||
701 now.tv_sec >= kernel_dump_time) {
702 rc = check_xroutes(1);
703 if(rc < 0)
704 fprintf(stderr, "Warning: couldn't check exported routes.\n");
705 kernel_routes_changed = kernel_addr_changed = 0;
706 if(kernel_socket >= 0)
707 kernel_dump_time = now.tv_sec + roughly(300);
708 else
709 kernel_dump_time = now.tv_sec + roughly(30);
710 }
711
712 if(timeval_compare(&check_neighbours_timeout, &now) < 0) {
713 int msecs;
714 msecs = check_neighbours();
715 /* Multiply by 3/2 to allow neighbours to expire. */
716 msecs = MAX(3 * msecs / 2, 10);
717 schedule_neighbours_check(msecs, 1);
718 }
719
720 if(timeval_compare(&check_interfaces_timeout, &now) < 0) {
721 check_interfaces();
722 schedule_interfaces_check(30000, 1);
723 }
724
725 if(now.tv_sec >= expiry_time) {
726 expire_routes();
727 expire_resend();
728 expiry_time = now.tv_sec + roughly(30);
729 }
730
731 if(now.tv_sec >= source_expiry_time) {
732 expire_sources();
733 source_expiry_time = now.tv_sec + roughly(300);
734 }
735
736 FOR_ALL_INTERFACES(ifp) {
737 if(!if_up(ifp))
738 continue;
739 if(timeval_compare(&now, &ifp->hello_timeout) >= 0)
740 send_hello(ifp);
741 if(timeval_compare(&now, &ifp->update_timeout) >= 0)
742 send_update(ifp, 0, NULL, 0, NULL, 0);
743 if(timeval_compare(&now, &ifp->update_flush_timeout) >= 0)
744 flushupdates(ifp);
745 }
746
747 if(resend_time.tv_sec != 0) {
748 if(timeval_compare(&now, &resend_time) >= 0)
749 do_resend();
750 }
751
752 FOR_ALL_INTERFACES(ifp) {
753 if(!if_up(ifp))
754 continue;
755 if(ifp->buf.timeout.tv_sec != 0) {
756 if(timeval_compare(&now, &ifp->buf.timeout) >= 0) {
757 flushupdates(ifp);
758 flushbuf(&ifp->buf, ifp);
759 }
760 }
761 }
762
763 FOR_ALL_NEIGHBOURS(neigh) {
764 if(neigh->buf.timeout.tv_sec != 0) {
765 if(timeval_compare(&now, &neigh->buf.timeout) >= 0) {
766 flushbuf(&neigh->buf, neigh->ifp);
767 }
768 }
769 }
770
771 if(UNLIKELY(debug || dumping)) {
772 dump_tables(stdout);
773 dumping = 0;
774 }
775 }
776
777 debugf("Exiting...\n");
778 usleep(roughly(10000));
779 gettime(&now);
780
781 /* We need to flush so interface_updown won't try to reinstall. */
782 flush_all_routes();
783
784 FOR_ALL_INTERFACES(ifp) {
785 if(!if_up(ifp))
786 continue;
787 send_wildcard_retraction(ifp);
788 /* Make sure that we expire quickly from our neighbours'
789 association caches. */
790 send_multicast_hello(ifp, 10, 1);
791 flushbuf(&ifp->buf, ifp);
792 usleep(roughly(1000));
793 gettime(&now);
794 }
795 FOR_ALL_INTERFACES(ifp) {
796 if(!if_up(ifp))
797 continue;
798 /* Make sure they got it. */
799 send_wildcard_retraction(ifp);
800 send_multicast_hello(ifp, 1, 1);
801 flushbuf(&ifp->buf, ifp);
802 usleep(roughly(10000));
803 gettime(&now);
804 interface_updown(ifp, 0);
805 }
806 kernel_setup_socket(0);
807 kernel_setup(0);
808
809 fd = open(state_file, O_WRONLY | O_TRUNC | O_CREAT, 0644);
810 if(fd < 0) {
811 perror("creat(babel-state)");
812 unlink(state_file);
813 } else {
814 char buf[10];
815 rc = snprintf(buf, 10, "%d\n", (int)myseqno);
816 if(rc < 0 || rc >= 10) {
817 fprintf(stderr, "write(babel-state): overflow.\n");
818 unlink(state_file);
819 } else {
820 rc = write(fd, buf, rc);
821 if(rc < 0) {
822 perror("write(babel-state)");
823 unlink(state_file);
824 }
825 fsync(fd);
826 }
827 close(fd);
828 }
829 if(local_server_socket >= 0 && local_server_path) {
830 unlink(local_server_path);
831 free(local_server_path);
832 }
833 if(pidfile)
834 unlink(pidfile);
835 debugf("Done.\n");
836 return 0;
837
838 usage:
839 fprintf(stderr,
840 "%s\n"
841 "Syntax: babeld "
842 "[-V] [-m multicast_address] [-p port] [-S state-file]\n"
843 " "
844 "[-h hello] [-H wired_hello] [-z kind[,factor]]\n"
845 " "
846 "[-g port] [-G port] [-k metric] [-A metric] [-s] [-l] [-w] [-r]\n"
847 " "
848 "[-t table] [-T table] [-c file] [-C statement]\n"
849 " "
850 "[-d level] [-D] [-L logfile] [-I pidfile]\n"
851 " "
852 "interface...\n",
853 BABELD_VERSION);
854 exit(1);
855
856 fail:
857 FOR_ALL_INTERFACES(ifp) {
858 if(!if_up(ifp))
859 continue;
860 interface_updown(ifp, 0);
861 }
862 kernel_setup_socket(0);
863 kernel_setup(0);
864 fail_pid:
865 if(pidfile)
866 unlink(pidfile);
867 exit(1);
868 }
869
870 static int
accept_local_connections()871 accept_local_connections()
872 {
873 int rc, s;
874 struct local_socket *ls;
875
876 if(local_server_socket < 0)
877 return 0;
878
879 s = accept(local_server_socket, NULL, NULL);
880
881 if(s < 0) {
882 if(errno != EINTR && errno != EAGAIN) {
883 perror("accept(local_server_socket)");
884 return -1;
885 }
886 return 0;
887 }
888
889 if(num_local_sockets >= MAX_LOCAL_SOCKETS) {
890 /* This should never happen, since we don't select for
891 the server socket in this case. But I'm paranoid. */
892 fprintf(stderr, "Internal error: too many local sockets.\n");
893 close(s);
894 return -1;
895 }
896
897 rc = fcntl(s, F_GETFL, 0);
898 if(rc < 0) {
899 fprintf(stderr, "Unable to get flags of local socket.\n");
900 close(s);
901 return -1;
902 }
903
904 rc = fcntl(s, F_SETFL, (rc | O_NONBLOCK));
905 if(rc < 0) {
906 fprintf(stderr, "Unable to set flags of local socket.\n");
907 close(s);
908 return -1;
909 }
910
911 ls = local_socket_create(s);
912 if(ls == NULL) {
913 fprintf(stderr, "Unable create local socket.\n");
914 close(s);
915 return -1;
916 }
917 local_header(ls);
918 return 1;
919 }
920
921 void
schedule_neighbours_check(int msecs,int override)922 schedule_neighbours_check(int msecs, int override)
923 {
924 struct timeval timeout;
925
926 timeval_add_msec(&timeout, &now, roughly(msecs));
927 if(override)
928 check_neighbours_timeout = timeout;
929 else
930 timeval_min(&check_neighbours_timeout, &timeout);
931 }
932
933 void
schedule_interfaces_check(int msecs,int override)934 schedule_interfaces_check(int msecs, int override)
935 {
936 struct timeval timeout;
937
938 timeval_add_msec(&timeout, &now, roughly(msecs));
939 if(override)
940 check_interfaces_timeout = timeout;
941 else
942 timeval_min(&check_interfaces_timeout, &timeout);
943 }
944
945 int
resize_receive_buffer(int size)946 resize_receive_buffer(int size)
947 {
948 unsigned char *new;
949
950 if(size <= receive_buffer_size)
951 return 0;
952
953 new = realloc(receive_buffer, size);
954 if(new == NULL) {
955 perror("realloc(receive_buffer)");
956 return -1;
957 }
958 receive_buffer = new;
959 receive_buffer_size = size;
960
961 return 1;
962 }
963
964 static void
sigexit(int signo)965 sigexit(int signo)
966 {
967 exiting = 1;
968 }
969
970 static void
sigdump(int signo)971 sigdump(int signo)
972 {
973 dumping = 1;
974 }
975
976 static void
sigreopening(int signo)977 sigreopening(int signo)
978 {
979 reopening = 1;
980 }
981
982 static void
init_signals(void)983 init_signals(void)
984 {
985 struct sigaction sa;
986 sigset_t ss;
987
988 sigemptyset(&ss);
989 sa.sa_handler = sigexit;
990 sa.sa_mask = ss;
991 sa.sa_flags = 0;
992 sigaction(SIGTERM, &sa, NULL);
993
994 sigemptyset(&ss);
995 sa.sa_handler = sigexit;
996 sa.sa_mask = ss;
997 sa.sa_flags = 0;
998 sigaction(SIGHUP, &sa, NULL);
999
1000 sigemptyset(&ss);
1001 sa.sa_handler = sigexit;
1002 sa.sa_mask = ss;
1003 sa.sa_flags = 0;
1004 sigaction(SIGINT, &sa, NULL);
1005
1006 sigemptyset(&ss);
1007 sa.sa_handler = SIG_IGN;
1008 sa.sa_mask = ss;
1009 sa.sa_flags = 0;
1010 sigaction(SIGPIPE, &sa, NULL);
1011
1012 sigemptyset(&ss);
1013 sa.sa_handler = sigdump;
1014 sa.sa_mask = ss;
1015 sa.sa_flags = 0;
1016 sigaction(SIGUSR1, &sa, NULL);
1017
1018 sigemptyset(&ss);
1019 sa.sa_handler = sigreopening;
1020 sa.sa_mask = ss;
1021 sa.sa_flags = 0;
1022 sigaction(SIGUSR2, &sa, NULL);
1023
1024 #ifdef SIGINFO
1025 sigemptyset(&ss);
1026 sa.sa_handler = sigdump;
1027 sa.sa_mask = ss;
1028 sa.sa_flags = 0;
1029 sigaction(SIGINFO, &sa, NULL);
1030 #endif
1031 }
1032
1033 static void
dump_route(FILE * out,struct babel_route * route)1034 dump_route(FILE *out, struct babel_route *route)
1035 {
1036 const unsigned char *nexthop =
1037 memcmp(route->nexthop, route->neigh->address, 16) == 0 ?
1038 NULL : route->nexthop;
1039 char channels[100];
1040
1041 if(route->channels_len == 0) {
1042 channels[0] = '\0';
1043 } else {
1044 int k, j = 0;
1045 snprintf(channels, 100, " chan (");
1046 j = strlen(channels);
1047 for(k = 0; k < route->channels_len; k++) {
1048 if(k > 0)
1049 channels[j++] = ',';
1050 snprintf(channels + j, 100 - j, "%u", (unsigned)route->channels[k]);
1051 j = strlen(channels);
1052 }
1053 snprintf(channels + j, 100 - j, ")");
1054 }
1055
1056 fprintf(out, "%s from %s metric %d (%d) refmetric %d id %s "
1057 "seqno %d%s age %d via %s neigh %s%s%s%s\n",
1058 format_prefix(route->src->prefix, route->src->plen),
1059 format_prefix(route->src->src_prefix, route->src->src_plen),
1060 route_metric(route), route_smoothed_metric(route), route->refmetric,
1061 format_eui64(route->src->id),
1062 (int)route->seqno,
1063 channels,
1064 (int)(now.tv_sec - route->time),
1065 route->neigh->ifp->name,
1066 format_address(route->neigh->address),
1067 nexthop ? " nexthop " : "",
1068 nexthop ? format_address(nexthop) : "",
1069 route->installed ? " (installed)" :
1070 route_feasible(route) ? " (feasible)" : "");
1071 }
1072
1073 static void
dump_xroute(FILE * out,struct xroute * xroute)1074 dump_xroute(FILE *out, struct xroute *xroute)
1075 {
1076 fprintf(out, "%s from %s metric %d (exported)\n",
1077 format_prefix(xroute->prefix, xroute->plen),
1078 format_prefix(xroute->src_prefix, xroute->src_plen),
1079 xroute->metric);
1080 }
1081
1082 static void
dump_tables(FILE * out)1083 dump_tables(FILE *out)
1084 {
1085 struct neighbour *neigh;
1086 struct xroute_stream *xroutes;
1087 struct route_stream *routes;
1088
1089 fprintf(out, "\n");
1090
1091 fprintf(out, "My id %s seqno %d\n", format_eui64(myid), myseqno);
1092
1093 FOR_ALL_NEIGHBOURS(neigh) {
1094 fprintf(out, "Neighbour %s dev %s reach %04x ureach %04x "
1095 "rxcost %u txcost %d rtt %s rttcost %u chan %d%s.\n",
1096 format_address(neigh->address),
1097 neigh->ifp->name,
1098 neigh->hello.reach,
1099 neigh->uhello.reach,
1100 neighbour_rxcost(neigh),
1101 neigh->txcost,
1102 format_thousands(neigh->rtt),
1103 neighbour_rttcost(neigh),
1104 neigh->ifp->channel,
1105 if_up(neigh->ifp) ? "" : " (down)");
1106 }
1107
1108 xroutes = xroute_stream();
1109 if(xroutes) {
1110 while(1) {
1111 struct xroute *xroute = xroute_stream_next(xroutes);
1112 if(xroute == NULL) break;
1113 dump_xroute(out, xroute);
1114 }
1115 xroute_stream_done(xroutes);
1116 }
1117
1118 routes = route_stream(0);
1119 if(routes) {
1120 while(1) {
1121 struct babel_route *route = route_stream_next(routes);
1122 if(route == NULL) break;
1123 dump_route(out, route);
1124 }
1125 route_stream_done(routes);
1126 }
1127
1128 fflush(out);
1129 }
1130
1131 int
reopen_logfile()1132 reopen_logfile()
1133 {
1134 int lfd, rc;
1135
1136 if(logfile == NULL)
1137 return 0;
1138
1139 lfd = open(logfile, O_CREAT | O_WRONLY | O_APPEND, 0644);
1140 if(lfd < 0)
1141 return -1;
1142
1143 fflush(stdout);
1144 fflush(stderr);
1145
1146 rc = dup2(lfd, 1);
1147 if(rc < 0)
1148 return -1;
1149
1150 rc = dup2(lfd, 2);
1151 if(rc < 0)
1152 return -1;
1153
1154 if(lfd > 2)
1155 close(lfd);
1156
1157 return 1;
1158 }
1159