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
29 #include "distribute.h"
30 #include "lib_errors.h"
32 #include "babel_main.h"
35 #include "babel_interface.h"
38 #include "babel_zebra.h"
39 #include "neighbour.h"
42 #include "babel_memory.h"
43 #include "babel_errors.h"
45 #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0)
47 static int babel_enable_if_lookup (const char *ifname
);
48 static int babel_enable_if_add (const char *ifname
);
49 static int babel_enable_if_delete (const char *ifname
);
50 static int interface_recalculate(struct interface
*ifp
);
51 static int interface_reset(struct interface
*ifp
);
52 static int babel_if_new_hook (struct interface
*ifp
);
53 static int babel_if_delete_hook (struct interface
*ifp
);
54 static int interface_config_write (struct vty
*vty
);
55 static babel_interface_nfo
* babel_interface_allocate (void);
56 static void babel_interface_free (babel_interface_nfo
*bi
);
59 static vector babel_enable_if
; /* enable interfaces (by cmd). */
60 static struct cmd_node babel_interface_node
= /* babeld's interface node. */
69 babel_interface_up (ZAPI_CALLBACK_ARGS
)
71 struct stream
*s
= NULL
;
72 struct interface
*ifp
= NULL
;
74 debugf(BABEL_DEBUG_IF
, "receive a 'interface up'");
77 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
83 interface_recalculate(ifp
);
88 babel_interface_down (ZAPI_CALLBACK_ARGS
)
90 struct stream
*s
= NULL
;
91 struct interface
*ifp
= NULL
;
93 debugf(BABEL_DEBUG_IF
, "receive a 'interface down'");
96 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
102 interface_reset(ifp
);
107 babel_interface_add (ZAPI_CALLBACK_ARGS
)
109 struct interface
*ifp
= NULL
;
111 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
113 /* read and add the interface in the iflist. */
114 ifp
= zebra_interface_add_read (zclient
->ibuf
, vrf_id
);
120 interface_recalculate(ifp
);
125 babel_interface_delete (ZAPI_CALLBACK_ARGS
)
127 struct interface
*ifp
;
130 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
133 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
139 interface_reset(ifp
);
141 /* To support pseudo interface do not free interface structure. */
142 /* if_delete(ifp); */
143 if_set_index(ifp
, IFINDEX_INTERNAL
);
149 babel_interface_address_add (ZAPI_CALLBACK_ARGS
)
151 babel_interface_nfo
*babel_ifp
;
152 struct connected
*ifc
;
153 struct prefix
*prefix
;
155 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
157 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
158 zclient
->ibuf
, vrf_id
);
163 prefix
= ifc
->address
;
165 if (prefix
->family
== AF_INET
) {
166 flush_interface_routes(ifc
->ifp
, 0);
167 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
168 if (babel_ifp
->ipv4
== NULL
) {
169 babel_ifp
->ipv4
= malloc(4);
170 if (babel_ifp
->ipv4
== NULL
) {
171 flog_err(EC_BABEL_MEMORY
, "not enough memory");
173 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
178 send_request(ifc
->ifp
, NULL
, 0);
179 send_update(ifc
->ifp
, 0, NULL
, 0);
185 babel_interface_address_delete (ZAPI_CALLBACK_ARGS
)
187 babel_interface_nfo
*babel_ifp
;
188 struct connected
*ifc
;
189 struct prefix
*prefix
;
191 debugf(BABEL_DEBUG_IF
, "receive a 'interface address delete'");
193 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE
,
194 zclient
->ibuf
, vrf_id
);
199 prefix
= ifc
->address
;
201 if (prefix
->family
== AF_INET
) {
202 flush_interface_routes(ifc
->ifp
, 0);
203 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
204 if (babel_ifp
->ipv4
!= NULL
205 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4) == 0) {
206 free(babel_ifp
->ipv4
);
207 babel_ifp
->ipv4
= NULL
;
211 send_request(ifc
->ifp
, NULL
, 0);
212 send_update(ifc
->ifp
, 0, NULL
, 0);
217 /* Lookup function. */
219 babel_enable_if_lookup (const char *ifname
)
224 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
225 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
226 if (strcmp (str
, ifname
) == 0)
231 /* Add interface to babel_enable_if. */
233 babel_enable_if_add (const char *ifname
)
236 struct interface
*ifp
= NULL
;
238 ret
= babel_enable_if_lookup (ifname
);
242 vector_set (babel_enable_if
, strdup (ifname
));
244 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
246 interface_recalculate(ifp
);
251 /* Delete interface from babel_enable_if. */
253 babel_enable_if_delete (const char *ifname
)
255 int babel_enable_if_index
;
257 struct interface
*ifp
= NULL
;
259 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
260 if (babel_enable_if_index
< 0)
263 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
265 vector_unset (babel_enable_if
, babel_enable_if_index
);
267 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
269 interface_reset(ifp
);
274 /* [Babel Command] Babel enable on specified interface or matched network. */
275 DEFUN (babel_network
,
277 "network IF_OR_ADDR",
278 "Enable Babel protocol on specified interface or network.\n"
279 "Interface or address\n")
284 ret
= str2prefix (argv
[1]->arg
, &p
);
286 /* Given string is: */
287 if (ret
) /* an IPv4 or v6 network */
288 return CMD_ERR_NO_MATCH
; /* not implemented yet */
289 else /* an interface name */
290 ret
= babel_enable_if_add (argv
[1]->arg
);
293 vty_out (vty
, "There is same network configuration %s\n",
301 /* [Babel Command] Babel enable on specified interface or matched network. */
302 DEFUN (no_babel_network
,
303 no_babel_network_cmd
,
304 "no network IF_OR_ADDR",
306 "Disable Babel protocol on specified interface or network.\n"
307 "Interface or address\n")
312 ret
= str2prefix (argv
[2]->arg
, &p
);
314 /* Given string is: */
315 if (ret
) /* an IPv4 or v6 network */
316 return CMD_ERR_NO_MATCH
; /* not implemented yet */
317 else /* an interface name */
318 ret
= babel_enable_if_delete (argv
[2]->arg
);
321 vty_out (vty
, "can't find network %s\n",argv
[2]->arg
);
322 return CMD_WARNING_CONFIG_FAILED
;
328 /* There are a number of interface parameters that must be changed when
329 an interface becomes wired/wireless. In Quagga, they cannot be
330 configured separately. */
333 babel_set_wired_internal(babel_interface_nfo
*babel_ifp
, int wired
)
336 babel_ifp
->flags
|= BABEL_IF_WIRED
;
337 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
338 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRED
;
339 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
340 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
342 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
343 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
344 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRELESS
;
345 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
346 babel_ifp
->flags
|= BABEL_IF_LQ
;
351 /* [Interface Command] Tell the interface is wire. */
352 DEFUN (babel_set_wired
,
355 "Babel interface commands\n"
356 "Enable wired optimizations\n")
358 VTY_DECLVAR_CONTEXT(interface
, ifp
);
359 babel_interface_nfo
*babel_ifp
;
361 babel_ifp
= babel_get_if_nfo(ifp
);
363 assert (babel_ifp
!= NULL
);
364 babel_set_wired_internal(babel_ifp
, 1);
368 /* [Interface Command] Tell the interface is wireless (default). */
369 DEFUN (babel_set_wireless
,
370 babel_set_wireless_cmd
,
372 "Babel interface commands\n"
373 "Disable wired optimizations (assume wireless)\n")
375 VTY_DECLVAR_CONTEXT(interface
, ifp
);
376 babel_interface_nfo
*babel_ifp
;
378 babel_ifp
= babel_get_if_nfo(ifp
);
380 assert (babel_ifp
!= NULL
);
381 babel_set_wired_internal(babel_ifp
, 0);
385 /* [Interface Command] Enable split horizon. */
386 DEFUN (babel_split_horizon
,
387 babel_split_horizon_cmd
,
388 "babel split-horizon",
389 "Babel interface commands\n"
390 "Enable split horizon processing\n")
392 VTY_DECLVAR_CONTEXT(interface
, ifp
);
393 babel_interface_nfo
*babel_ifp
;
395 babel_ifp
= babel_get_if_nfo(ifp
);
397 assert (babel_ifp
!= NULL
);
398 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
402 /* [Interface Command] Disable split horizon (default). */
403 DEFUN (no_babel_split_horizon
,
404 no_babel_split_horizon_cmd
,
405 "no babel split-horizon",
407 "Babel interface commands\n"
408 "Disable split horizon processing\n")
410 VTY_DECLVAR_CONTEXT(interface
, ifp
);
411 babel_interface_nfo
*babel_ifp
;
413 babel_ifp
= babel_get_if_nfo(ifp
);
415 assert (babel_ifp
!= NULL
);
416 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
420 /* [Interface Command]. */
421 DEFUN (babel_set_hello_interval
,
422 babel_set_hello_interval_cmd
,
423 "babel hello-interval (20-655340)",
424 "Babel interface commands\n"
425 "Time between scheduled hellos\n"
428 VTY_DECLVAR_CONTEXT(interface
, ifp
);
429 babel_interface_nfo
*babel_ifp
;
432 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
434 babel_ifp
= babel_get_if_nfo(ifp
);
435 assert (babel_ifp
!= NULL
);
437 babel_ifp
->hello_interval
= interval
;
441 /* [Interface Command]. */
442 DEFUN (babel_set_update_interval
,
443 babel_set_update_interval_cmd
,
444 "babel update-interval (20-655340)",
445 "Babel interface commands\n"
446 "Time between scheduled updates\n"
449 VTY_DECLVAR_CONTEXT(interface
, ifp
);
450 babel_interface_nfo
*babel_ifp
;
453 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
455 babel_ifp
= babel_get_if_nfo(ifp
);
456 assert (babel_ifp
!= NULL
);
458 babel_ifp
->update_interval
= interval
;
462 DEFUN (babel_set_rxcost
,
463 babel_set_rxcost_cmd
,
464 "babel rxcost (1-65534)",
465 "Babel interface commands\n"
466 "Rxcost multiplier\n"
469 VTY_DECLVAR_CONTEXT(interface
, ifp
);
470 babel_interface_nfo
*babel_ifp
;
473 rxcost
= strtoul(argv
[2]->arg
, NULL
, 10);
475 babel_ifp
= babel_get_if_nfo(ifp
);
476 assert (babel_ifp
!= NULL
);
478 babel_ifp
->cost
= rxcost
;
482 DEFUN (babel_set_rtt_decay
,
483 babel_set_rtt_decay_cmd
,
484 "babel rtt-decay (1-256)",
485 "Babel interface commands\n"
486 "Decay factor for exponential moving average of RTT samples\n"
489 VTY_DECLVAR_CONTEXT(interface
, ifp
);
490 babel_interface_nfo
*babel_ifp
;
493 decay
= strtoul(argv
[2]->arg
, NULL
, 10);
495 babel_ifp
= babel_get_if_nfo(ifp
);
496 assert (babel_ifp
!= NULL
);
498 babel_ifp
->rtt_decay
= decay
;
502 DEFUN (babel_set_rtt_min
,
503 babel_set_rtt_min_cmd
,
504 "babel rtt-min (1-65535)",
505 "Babel interface commands\n"
506 "Minimum RTT starting for increasing cost\n"
509 VTY_DECLVAR_CONTEXT(interface
, ifp
);
510 babel_interface_nfo
*babel_ifp
;
513 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
515 babel_ifp
= babel_get_if_nfo(ifp
);
516 assert (babel_ifp
!= NULL
);
518 babel_ifp
->rtt_min
= rtt
;
522 DEFUN (babel_set_rtt_max
,
523 babel_set_rtt_max_cmd
,
524 "babel rtt-max (1-65535)",
525 "Babel interface commands\n"
529 VTY_DECLVAR_CONTEXT(interface
, ifp
);
530 babel_interface_nfo
*babel_ifp
;
533 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
535 babel_ifp
= babel_get_if_nfo(ifp
);
536 assert (babel_ifp
!= NULL
);
538 babel_ifp
->rtt_max
= rtt
;
542 DEFUN (babel_set_max_rtt_penalty
,
543 babel_set_max_rtt_penalty_cmd
,
544 "babel max-rtt-penalty (0-65535)",
545 "Babel interface commands\n"
546 "Maximum additional cost due to RTT\n"
549 VTY_DECLVAR_CONTEXT(interface
, ifp
);
550 babel_interface_nfo
*babel_ifp
;
553 penalty
= strtoul(argv
[2]->arg
, NULL
, 10);
555 babel_ifp
= babel_get_if_nfo(ifp
);
556 assert (babel_ifp
!= NULL
);
558 babel_ifp
->max_rtt_penalty
= penalty
;
562 DEFUN (babel_set_enable_timestamps
,
563 babel_set_enable_timestamps_cmd
,
564 "babel enable-timestamps",
565 "Babel interface commands\n"
566 "Enable timestamps\n")
568 VTY_DECLVAR_CONTEXT(interface
, ifp
);
569 babel_interface_nfo
*babel_ifp
;
571 babel_ifp
= babel_get_if_nfo(ifp
);
572 assert (babel_ifp
!= NULL
);
574 babel_ifp
->flags
|= BABEL_IF_TIMESTAMPS
;
578 DEFUN (no_babel_set_enable_timestamps
,
579 no_babel_set_enable_timestamps_cmd
,
580 "no babel enable-timestamps",
582 "Babel interface commands\n"
583 "Disable timestamps\n")
585 VTY_DECLVAR_CONTEXT(interface
, ifp
);
586 babel_interface_nfo
*babel_ifp
;
588 babel_ifp
= babel_get_if_nfo(ifp
);
589 assert (babel_ifp
!= NULL
);
591 babel_ifp
->flags
&= ~BABEL_IF_TIMESTAMPS
;
595 DEFUN (babel_set_channel
,
596 babel_set_channel_cmd
,
597 "babel channel (1-254)",
598 "Babel interface commands\n"
599 "Channel number for diversity routing\n"
602 VTY_DECLVAR_CONTEXT(interface
, ifp
);
603 babel_interface_nfo
*babel_ifp
;
606 channel
= strtoul(argv
[2]->arg
, NULL
, 10);
608 babel_ifp
= babel_get_if_nfo(ifp
);
609 assert (babel_ifp
!= NULL
);
611 babel_ifp
->channel
= channel
;
615 DEFUN (babel_set_channel_interfering
,
616 babel_set_channel_interfering_cmd
,
617 "babel channel interfering",
618 "Babel interface commands\n"
619 "Channel number for diversity routing\n"
620 "Mark channel as interfering\n")
622 VTY_DECLVAR_CONTEXT(interface
, ifp
);
623 babel_interface_nfo
*babel_ifp
;
625 babel_ifp
= babel_get_if_nfo(ifp
);
626 assert (babel_ifp
!= NULL
);
628 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
632 DEFUN (babel_set_channel_noninterfering
,
633 babel_set_channel_noninterfering_cmd
,
634 "babel channel noninterfering",
635 "Babel interface commands\n"
636 "Channel number for diversity routing\n"
637 "Mark channel as noninterfering\n")
639 VTY_DECLVAR_CONTEXT(interface
, ifp
);
640 babel_interface_nfo
*babel_ifp
;
642 babel_ifp
= babel_get_if_nfo(ifp
);
643 assert (babel_ifp
!= NULL
);
645 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
649 /* This should be no more than half the hello interval, so that hellos
650 aren't sent late. The result is in milliseconds. */
652 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
654 unsigned interval
= babel_ifp
->hello_interval
;
656 interval
= MIN(interval
, 100);
658 interval
= MIN(interval
, 4000);
659 return roughly(interval
) / 4;
663 update_jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
665 unsigned interval
= babel_ifp
->hello_interval
;
667 interval
= MIN(interval
, 100);
669 interval
= MIN(interval
, 4000);
670 return roughly(interval
);
673 /* calculate babeld's specific datas of an interface (change when the interface
676 interface_recalculate(struct interface
*ifp
)
678 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
679 unsigned char *tmp
= NULL
;
681 struct ipv6_mreq mreq
;
686 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
687 interface_reset(ifp
);
691 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
693 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
695 /* We need to be able to fit at least two messages into a packet,
696 so MTUs below 116 require lower layer fragmentation. */
697 /* In IPv6, the minimum MTU is 1280, and every host must be able
698 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
700 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
701 mtu
, ifp
->name
, ifp
->ifindex
);
705 /* 4 for Babel header; 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
706 babel_ifp
->bufsize
= mtu
- 4 - 60;
707 tmp
= babel_ifp
->sendbuf
;
708 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
709 if(babel_ifp
->sendbuf
== NULL
) {
710 flog_err(EC_BABEL_MEMORY
, "Couldn't reallocate sendbuf.");
712 babel_ifp
->bufsize
= 0;
717 rc
= resize_receive_buffer(mtu
);
719 zlog_warn("couldn't resize "
720 "receive buffer for interface %s (%d) (%d bytes).\n",
721 ifp
->name
, ifp
->ifindex
, mtu
);
723 memset(&mreq
, 0, sizeof(mreq
));
724 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
725 mreq
.ipv6mr_interface
= ifp
->ifindex
;
727 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
728 (char*)&mreq
, sizeof(mreq
));
730 flog_err_sys(EC_LIB_SOCKET
,
731 "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
732 ifp
->name
, safe_strerror(errno
));
733 /* This is probably due to a missing link-local address,
734 so down this interface, and wait until the main loop
735 tries to up it again. */
736 interface_reset(ifp
);
740 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
741 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
743 send_request(ifp
, NULL
, 0);
745 update_interface_metric(ifp
);
747 debugf(BABEL_DEBUG_COMMON
,
748 "Upped interface %s (%s, cost=%d, channel=%d%s).",
750 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
753 babel_ifp
->ipv4
? ", IPv4" : "");
756 send_update(ifp
, 0, NULL
, 0);
761 /* Reset the interface as it was new: it's not removed from the interface list,
762 and may be considered as a upped interface. */
764 interface_reset(struct interface
*ifp
)
767 struct ipv6_mreq mreq
;
768 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
770 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
773 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
774 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
776 flush_interface_routes(ifp
, 0);
777 babel_ifp
->buffered
= 0;
778 babel_ifp
->bufsize
= 0;
779 free(babel_ifp
->sendbuf
);
780 babel_ifp
->num_buffered_updates
= 0;
781 babel_ifp
->update_bufsize
= 0;
782 if(babel_ifp
->buffered_updates
)
783 free(babel_ifp
->buffered_updates
);
784 babel_ifp
->buffered_updates
= NULL
;
785 babel_ifp
->sendbuf
= NULL
;
787 if(ifp
->ifindex
> 0) {
788 memset(&mreq
, 0, sizeof(mreq
));
789 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
790 mreq
.ipv6mr_interface
= ifp
->ifindex
;
791 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
792 (char*)&mreq
, sizeof(mreq
));
794 flog_err_sys(EC_LIB_SOCKET
,
795 "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
796 ifp
->name
, safe_strerror(errno
));
799 update_interface_metric(ifp
);
801 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
803 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
805 babel_ifp
->ipv4
? ", IPv4" : "");
810 /* Send retraction to all, and reset all interfaces statistics. */
812 babel_interface_close_all(void)
814 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
815 struct interface
*ifp
= NULL
;
817 FOR_ALL_INTERFACES(vrf
, ifp
) {
820 send_wildcard_retraction(ifp
);
821 /* Make sure that we expire quickly from our neighbours'
822 association caches. */
823 send_hello_noupdate(ifp
, 10);
825 usleep(roughly(1000));
828 FOR_ALL_INTERFACES(vrf
, ifp
) {
831 /* Make sure they got it. */
832 send_wildcard_retraction(ifp
);
833 send_hello_noupdate(ifp
, 1);
835 usleep(roughly(10000));
837 interface_reset(ifp
);
841 /* return "true" if address is one of our ipv6 addresses */
843 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
845 struct connected
*connected
;
846 struct listnode
*node
;
851 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
852 if(connected
->address
->family
== AF_INET6
&&
853 memcmp(&connected
->address
->u
.prefix6
, address
, 16) == 0)
861 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
864 babel_interface_nfo
*babel_ifp
;
866 vty_out (vty
, "%s is %s\n", ifp
->name
,
867 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
868 vty_out (vty
, " ifindex %u, MTU %u bytes %s\n",
869 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
873 vty_out (vty
, " Babel protocol is not enabled on this interface\n");
879 " Babel protocol is enabled, but not running on this interface\n");
882 babel_ifp
= babel_get_if_nfo (ifp
);
883 vty_out (vty
, " Babel protocol is running on this interface\n");
884 vty_out (vty
, " Operating mode is \"%s\"\n",
885 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
886 vty_out (vty
, " Split horizon mode is %s\n",
887 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
888 vty_out (vty
, " Hello interval is %u ms\n", babel_ifp
->hello_interval
);
889 vty_out (vty
, " Update interval is %u ms\n", babel_ifp
->update_interval
);
890 vty_out (vty
, " Rxcost multiplier is %u\n", babel_ifp
->cost
);
893 DEFUN (show_babel_interface
,
894 show_babel_interface_cmd
,
895 "show babel interface [IFNAME]",
897 "Babel information\n"
898 "Interface information\n"
901 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
902 struct interface
*ifp
;
906 FOR_ALL_INTERFACES (vrf
, ifp
)
907 show_babel_interface_sub (vty
, ifp
);
910 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
912 vty_out (vty
, "No such interface name\n");
915 show_babel_interface_sub (vty
, ifp
);
920 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
923 "Neighbour %s dev %s reach %04x rxcost %d txcost %d "
924 "rtt %s rttcost %d%s.\n",
925 format_address(neigh
->address
),
928 neighbour_rxcost(neigh
),
930 format_thousands(neigh
->rtt
),
931 neighbour_rttcost(neigh
),
932 if_up(neigh
->ifp
) ? "" : " (down)");
935 DEFUN (show_babel_neighbour
,
936 show_babel_neighbour_cmd
,
937 "show babel neighbor [IFNAME]",
939 "Babel information\n"
943 struct neighbour
*neigh
;
944 struct interface
*ifp
;
947 FOR_ALL_NEIGHBOURS(neigh
) {
948 show_babel_neighbour_sub(vty
, neigh
);
952 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
954 vty_out (vty
, "No such interface name\n");
957 FOR_ALL_NEIGHBOURS(neigh
) {
958 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
959 show_babel_neighbour_sub(vty
, neigh
);
966 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
968 if(prefix
->family
== AF_INET6
) {
969 if(prefix
->prefixlen
!= plen
||
970 memcmp(&prefix
->u
.prefix6
, p
, 16) != 0)
972 } else if(prefix
->family
== AF_INET
) {
973 if(plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96 ||
974 memcmp(&prefix
->u
.prefix4
, p
+ 12, 4) != 0)
984 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
985 struct prefix
*prefix
)
987 const unsigned char *nexthop
=
988 memcmp(route
->nexthop
, route
->neigh
->address
, 16) == 0 ?
989 NULL
: route
->nexthop
;
992 if(prefix
&& !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
995 if(route
->channels
[0] == 0)
999 snprintf(channels
, 100, " chan (");
1000 j
= strlen(channels
);
1001 for(k
= 0; k
< DIVERSITY_HOPS
; k
++) {
1002 if(route
->channels
[k
] == 0)
1005 channels
[j
++] = ',';
1006 snprintf(channels
+ j
, 100 - j
, "%u", route
->channels
[k
]);
1007 j
= strlen(channels
);
1009 snprintf(channels
+ j
, 100 - j
, ")");
1015 "%s metric %d refmetric %d id %s seqno %d%s age %d "
1016 "via %s neigh %s%s%s%s\n",
1017 format_prefix(route
->src
->prefix
, route
->src
->plen
),
1018 route_metric(route
), route
->refmetric
,
1019 format_eui64(route
->src
->id
),
1022 (int)(babel_now
.tv_sec
- route
->time
),
1023 route
->neigh
->ifp
->name
,
1024 format_address(route
->neigh
->address
),
1025 nexthop
? " nexthop " : "",
1026 nexthop
? format_address(nexthop
) : "",
1027 route
->installed
? " (installed)" : route_feasible(route
) ? " (feasible)" : "");
1031 show_babel_xroutes_sub (struct xroute
*xroute
, struct vty
*vty
,
1032 struct prefix
*prefix
)
1034 if(prefix
&& !babel_prefix_eq(prefix
, xroute
->prefix
, xroute
->plen
))
1037 vty_out (vty
, "%s metric %d (exported)\n",
1038 format_prefix(xroute
->prefix
, xroute
->plen
),
1042 DEFUN (show_babel_route
,
1043 show_babel_route_cmd
,
1046 "Babel information\n"
1047 "Babel internal routing table\n")
1049 struct route_stream
*routes
= NULL
;
1050 struct xroute_stream
*xroutes
= NULL
;
1051 routes
= route_stream(0);
1054 struct babel_route
*route
= route_stream_next(routes
);
1057 show_babel_routes_sub(route
, vty
, NULL
);
1059 route_stream_done(routes
);
1061 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1063 xroutes
= xroute_stream();
1066 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1069 show_babel_xroutes_sub(xroute
, vty
, NULL
);
1071 xroute_stream_done(xroutes
);
1073 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1078 DEFUN (show_babel_route_prefix
,
1079 show_babel_route_prefix_cmd
,
1080 "show babel route <A.B.C.D/M|X:X::X:X/M>",
1082 "Babel information\n"
1083 "Babel internal routing table\n"
1084 "IPv4 prefix <network>/<length>\n"
1085 "IPv6 prefix <network>/<length>\n")
1087 struct route_stream
*routes
= NULL
;
1088 struct xroute_stream
*xroutes
= NULL
;
1089 struct prefix prefix
;
1092 ret
= str2prefix(argv
[3]->arg
, &prefix
);
1094 vty_out (vty
, "%% Malformed address\n");
1098 routes
= route_stream(0);
1101 struct babel_route
*route
= route_stream_next(routes
);
1104 show_babel_routes_sub(route
, vty
, &prefix
);
1106 route_stream_done(routes
);
1108 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1110 xroutes
= xroute_stream();
1113 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1116 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1118 xroute_stream_done(xroutes
);
1120 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1126 DEFUN (show_babel_route_addr
,
1127 show_babel_route_addr_cmd
,
1128 "show babel route A.B.C.D",
1130 "Babel information\n"
1131 "Babel internal routing table\n"
1132 "IPv4 address <network>/<length>\n")
1134 struct in_addr addr
;
1135 char buf
[INET_ADDRSTRLEN
+ 8];
1136 struct route_stream
*routes
= NULL
;
1137 struct xroute_stream
*xroutes
= NULL
;
1138 struct prefix prefix
;
1141 ret
= inet_aton (argv
[3]->arg
, &addr
);
1143 vty_out (vty
, "%% Malformed address\n");
1147 /* Quagga has no convenient prefix constructors. */
1148 snprintf(buf
, sizeof(buf
), "%s/%d", inet_ntoa(addr
), 32);
1150 ret
= str2prefix(buf
, &prefix
);
1152 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1156 routes
= route_stream(0);
1159 struct babel_route
*route
= route_stream_next(routes
);
1162 show_babel_routes_sub(route
, vty
, &prefix
);
1164 route_stream_done(routes
);
1166 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1168 xroutes
= xroute_stream();
1171 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1174 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1176 xroute_stream_done(xroutes
);
1178 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1183 DEFUN (show_babel_route_addr6
,
1184 show_babel_route_addr6_cmd
,
1185 "show babel route X:X::X:X",
1187 "Babel information\n"
1188 "Babel internal routing table\n"
1189 "IPv6 address <network>/<length>\n")
1191 struct in6_addr addr
;
1192 char buf1
[INET6_ADDRSTRLEN
];
1193 char buf
[INET6_ADDRSTRLEN
+ 8];
1194 struct route_stream
*routes
= NULL
;
1195 struct xroute_stream
*xroutes
= NULL
;
1196 struct prefix prefix
;
1199 ret
= inet_pton (AF_INET6
, argv
[3]->arg
, &addr
);
1201 vty_out (vty
, "%% Malformed address\n");
1205 /* Quagga has no convenient prefix constructors. */
1206 snprintf(buf
, sizeof(buf
), "%s/%d",
1207 inet_ntop(AF_INET6
, &addr
, buf1
, sizeof(buf1
)), 128);
1209 ret
= str2prefix(buf
, &prefix
);
1211 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1215 routes
= route_stream(0);
1218 struct babel_route
*route
= route_stream_next(routes
);
1221 show_babel_routes_sub(route
, vty
, &prefix
);
1223 route_stream_done(routes
);
1225 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1227 xroutes
= xroute_stream();
1230 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1233 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1235 xroute_stream_done(xroutes
);
1237 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1242 DEFUN (show_babel_parameters
,
1243 show_babel_parameters_cmd
,
1244 "show babel parameters",
1246 "Babel information\n"
1247 "Configuration information\n")
1249 struct babel
*babel_ctx
;
1251 vty_out (vty
, " -- Babel running configuration --\n");
1252 show_babel_main_configuration(vty
);
1254 babel_ctx
= babel_lookup();
1256 vty_out (vty
, " -- distribution lists --\n");
1257 config_show_distribute(vty
, babel_ctx
->distribute_ctx
);
1265 /* initialize interface list */
1266 hook_register_prio(if_add
, 0, babel_if_new_hook
);
1267 hook_register_prio(if_del
, 0, babel_if_delete_hook
);
1269 babel_enable_if
= vector_init (1);
1271 /* install interface node and commands */
1272 install_node (&babel_interface_node
, interface_config_write
);
1275 install_element(BABEL_NODE
, &babel_network_cmd
);
1276 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1277 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1278 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1279 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1280 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1281 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1282 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1283 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1284 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1285 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1286 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1287 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1288 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1289 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1290 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1291 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1292 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1294 /* "show babel ..." commands */
1295 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1296 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1297 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1298 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1299 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1300 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1301 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1304 /* hooks: functions called respectively when struct interface is
1305 created or deleted. */
1307 babel_if_new_hook (struct interface
*ifp
)
1309 ifp
->info
= babel_interface_allocate();
1314 babel_if_delete_hook (struct interface
*ifp
)
1316 babel_interface_free(ifp
->info
);
1321 /* Output an "interface" section for each of the known interfaces with
1322 babeld-specific statement lines where appropriate. */
1324 interface_config_write (struct vty
*vty
)
1326 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1327 struct interface
*ifp
;
1330 FOR_ALL_INTERFACES (vrf
, ifp
) {
1331 vty_frame (vty
, "interface %s\n",ifp
->name
);
1333 vty_out (vty
, " description %s\n",ifp
->desc
);
1334 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1335 /* wireless is the default*/
1336 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1338 vty_out (vty
, " babel wired\n");
1341 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1343 vty_out (vty
, " babel hello-interval %u\n",
1344 babel_ifp
->hello_interval
);
1347 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1349 vty_out (vty
, " babel update-interval %u\n",
1350 babel_ifp
->update_interval
);
1353 /* Some parameters have different defaults for wired/wireless. */
1354 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
)) {
1355 if (!CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1356 vty_out (vty
, " no babel split-horizon\n");
1359 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRED
) {
1360 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1363 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_INTERFERING
) {
1364 vty_out (vty
, " babel channel interfering\n");
1366 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_NONINTERFERING
) {
1367 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1371 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1372 vty_out (vty
, " babel split-horizon\n");
1375 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRELESS
) {
1376 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1379 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_NONINTERFERING
) {
1380 vty_out (vty
, " babel channel noninterfering\n");
1382 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_INTERFERING
) {
1383 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1387 vty_endframe (vty
, "!\n");
1393 /* Output a "network" statement line for each of the enabled interfaces. */
1395 babel_enable_if_config_write (struct vty
* vty
)
1397 unsigned int i
, lines
= 0;
1400 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
1401 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
1403 vty_out (vty
, " network %s\n", str
);
1409 /* functions to allocate or free memory for a babel_interface_nfo, filling
1411 static babel_interface_nfo
*
1412 babel_interface_allocate (void)
1414 babel_interface_nfo
*babel_ifp
;
1415 babel_ifp
= XCALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1416 /* All flags are unset */
1417 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1418 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1419 babel_ifp
->hello_seqno
= (random() & 0xFFFF);
1420 babel_ifp
->rtt_min
= 10000;
1421 babel_ifp
->rtt_max
= 120000;
1422 babel_ifp
->max_rtt_penalty
= 150;
1423 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1424 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1425 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1426 babel_set_wired_internal(babel_ifp
, 0);
1432 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1434 XFREE(MTYPE_BABEL_IF
, babel_ifp
);