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_errors.h"
44 DEFINE_MTYPE_STATIC(BABELD
, BABEL_IF
, "Babel Interface")
46 #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0)
48 static int babel_enable_if_lookup (const char *ifname
);
49 static int babel_enable_if_add (const char *ifname
);
50 static int babel_enable_if_delete (const char *ifname
);
51 static int interface_recalculate(struct interface
*ifp
);
52 static int interface_reset(struct interface
*ifp
);
53 static int babel_if_new_hook (struct interface
*ifp
);
54 static int babel_if_delete_hook (struct interface
*ifp
);
55 static int interface_config_write (struct vty
*vty
);
56 static babel_interface_nfo
* babel_interface_allocate (void);
57 static void babel_interface_free (babel_interface_nfo
*bi
);
60 static vector babel_enable_if
; /* enable interfaces (by cmd). */
61 static struct cmd_node babel_interface_node
= /* babeld's interface node. */
70 babel_interface_up (ZAPI_CALLBACK_ARGS
)
72 struct stream
*s
= NULL
;
73 struct interface
*ifp
= NULL
;
75 debugf(BABEL_DEBUG_IF
, "receive a 'interface up'");
78 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
84 interface_recalculate(ifp
);
89 babel_ifp_down(struct interface
*ifp
)
91 debugf(BABEL_DEBUG_IF
, "receive a 'interface down'");
101 int babel_ifp_create (struct interface
*ifp
)
103 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
105 interface_recalculate(ifp
);
111 babel_ifp_destroy(struct interface
*ifp
)
113 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
116 interface_reset(ifp
);
122 babel_interface_address_add (ZAPI_CALLBACK_ARGS
)
124 babel_interface_nfo
*babel_ifp
;
125 struct connected
*ifc
;
126 struct prefix
*prefix
;
128 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
130 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
131 zclient
->ibuf
, vrf_id
);
136 prefix
= ifc
->address
;
138 if (prefix
->family
== AF_INET
) {
139 flush_interface_routes(ifc
->ifp
, 0);
140 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
141 if (babel_ifp
->ipv4
== NULL
) {
142 babel_ifp
->ipv4
= malloc(4);
143 if (babel_ifp
->ipv4
== NULL
) {
144 flog_err(EC_BABEL_MEMORY
, "not enough memory");
146 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
151 send_request(ifc
->ifp
, NULL
, 0);
152 send_update(ifc
->ifp
, 0, NULL
, 0);
158 babel_interface_address_delete (ZAPI_CALLBACK_ARGS
)
160 babel_interface_nfo
*babel_ifp
;
161 struct connected
*ifc
;
162 struct prefix
*prefix
;
164 debugf(BABEL_DEBUG_IF
, "receive a 'interface address delete'");
166 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE
,
167 zclient
->ibuf
, vrf_id
);
172 prefix
= ifc
->address
;
174 if (prefix
->family
== AF_INET
) {
175 flush_interface_routes(ifc
->ifp
, 0);
176 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
177 if (babel_ifp
->ipv4
!= NULL
178 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4) == 0) {
179 free(babel_ifp
->ipv4
);
180 babel_ifp
->ipv4
= NULL
;
184 send_request(ifc
->ifp
, NULL
, 0);
185 send_update(ifc
->ifp
, 0, NULL
, 0);
190 /* Lookup function. */
192 babel_enable_if_lookup (const char *ifname
)
197 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
198 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
199 if (strcmp (str
, ifname
) == 0)
204 /* Add interface to babel_enable_if. */
206 babel_enable_if_add (const char *ifname
)
209 struct interface
*ifp
= NULL
;
211 ret
= babel_enable_if_lookup (ifname
);
215 vector_set (babel_enable_if
, strdup (ifname
));
217 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
219 interface_recalculate(ifp
);
224 /* Delete interface from babel_enable_if. */
226 babel_enable_if_delete (const char *ifname
)
228 int babel_enable_if_index
;
230 struct interface
*ifp
= NULL
;
232 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
233 if (babel_enable_if_index
< 0)
236 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
238 vector_unset (babel_enable_if
, babel_enable_if_index
);
240 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
242 interface_reset(ifp
);
247 /* [Babel Command] Babel enable on specified interface or matched network. */
248 DEFUN (babel_network
,
250 "network IF_OR_ADDR",
251 "Enable Babel protocol on specified interface or network.\n"
252 "Interface or address\n")
257 ret
= str2prefix (argv
[1]->arg
, &p
);
259 /* Given string is: */
260 if (ret
) /* an IPv4 or v6 network */
261 return CMD_ERR_NO_MATCH
; /* not implemented yet */
262 else /* an interface name */
263 ret
= babel_enable_if_add (argv
[1]->arg
);
266 vty_out (vty
, "There is same network configuration %s\n",
274 /* [Babel Command] Babel enable on specified interface or matched network. */
275 DEFUN (no_babel_network
,
276 no_babel_network_cmd
,
277 "no network IF_OR_ADDR",
279 "Disable Babel protocol on specified interface or network.\n"
280 "Interface or address\n")
285 ret
= str2prefix (argv
[2]->arg
, &p
);
287 /* Given string is: */
288 if (ret
) /* an IPv4 or v6 network */
289 return CMD_ERR_NO_MATCH
; /* not implemented yet */
290 else /* an interface name */
291 ret
= babel_enable_if_delete (argv
[2]->arg
);
294 vty_out (vty
, "can't find network %s\n",argv
[2]->arg
);
295 return CMD_WARNING_CONFIG_FAILED
;
301 /* There are a number of interface parameters that must be changed when
302 an interface becomes wired/wireless. In Quagga, they cannot be
303 configured separately. */
306 babel_set_wired_internal(babel_interface_nfo
*babel_ifp
, int wired
)
309 babel_ifp
->flags
|= BABEL_IF_WIRED
;
310 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
311 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRED
;
312 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
313 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
315 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
316 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
317 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRELESS
;
318 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
319 babel_ifp
->flags
|= BABEL_IF_LQ
;
324 /* [Interface Command] Tell the interface is wire. */
325 DEFUN (babel_set_wired
,
328 "Babel interface commands\n"
329 "Enable wired optimizations\n")
331 VTY_DECLVAR_CONTEXT(interface
, ifp
);
332 babel_interface_nfo
*babel_ifp
;
334 babel_ifp
= babel_get_if_nfo(ifp
);
336 assert (babel_ifp
!= NULL
);
337 babel_set_wired_internal(babel_ifp
, 1);
341 /* [Interface Command] Tell the interface is wireless (default). */
342 DEFUN (babel_set_wireless
,
343 babel_set_wireless_cmd
,
345 "Babel interface commands\n"
346 "Disable wired optimizations (assume wireless)\n")
348 VTY_DECLVAR_CONTEXT(interface
, ifp
);
349 babel_interface_nfo
*babel_ifp
;
351 babel_ifp
= babel_get_if_nfo(ifp
);
353 assert (babel_ifp
!= NULL
);
354 babel_set_wired_internal(babel_ifp
, 0);
358 /* [Interface Command] Enable split horizon. */
359 DEFUN (babel_split_horizon
,
360 babel_split_horizon_cmd
,
361 "babel split-horizon",
362 "Babel interface commands\n"
363 "Enable split horizon processing\n")
365 VTY_DECLVAR_CONTEXT(interface
, ifp
);
366 babel_interface_nfo
*babel_ifp
;
368 babel_ifp
= babel_get_if_nfo(ifp
);
370 assert (babel_ifp
!= NULL
);
371 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
375 /* [Interface Command] Disable split horizon (default). */
376 DEFUN (no_babel_split_horizon
,
377 no_babel_split_horizon_cmd
,
378 "no babel split-horizon",
380 "Babel interface commands\n"
381 "Disable split horizon processing\n")
383 VTY_DECLVAR_CONTEXT(interface
, ifp
);
384 babel_interface_nfo
*babel_ifp
;
386 babel_ifp
= babel_get_if_nfo(ifp
);
388 assert (babel_ifp
!= NULL
);
389 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
393 /* [Interface Command]. */
394 DEFUN (babel_set_hello_interval
,
395 babel_set_hello_interval_cmd
,
396 "babel hello-interval (20-655340)",
397 "Babel interface commands\n"
398 "Time between scheduled hellos\n"
401 VTY_DECLVAR_CONTEXT(interface
, ifp
);
402 babel_interface_nfo
*babel_ifp
;
405 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
407 babel_ifp
= babel_get_if_nfo(ifp
);
408 assert (babel_ifp
!= NULL
);
410 babel_ifp
->hello_interval
= interval
;
414 /* [Interface Command]. */
415 DEFUN (babel_set_update_interval
,
416 babel_set_update_interval_cmd
,
417 "babel update-interval (20-655340)",
418 "Babel interface commands\n"
419 "Time between scheduled updates\n"
422 VTY_DECLVAR_CONTEXT(interface
, ifp
);
423 babel_interface_nfo
*babel_ifp
;
426 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
428 babel_ifp
= babel_get_if_nfo(ifp
);
429 assert (babel_ifp
!= NULL
);
431 babel_ifp
->update_interval
= interval
;
435 DEFUN (babel_set_rxcost
,
436 babel_set_rxcost_cmd
,
437 "babel rxcost (1-65534)",
438 "Babel interface commands\n"
439 "Rxcost multiplier\n"
442 VTY_DECLVAR_CONTEXT(interface
, ifp
);
443 babel_interface_nfo
*babel_ifp
;
446 rxcost
= strtoul(argv
[2]->arg
, NULL
, 10);
448 babel_ifp
= babel_get_if_nfo(ifp
);
449 assert (babel_ifp
!= NULL
);
451 babel_ifp
->cost
= rxcost
;
455 DEFUN (babel_set_rtt_decay
,
456 babel_set_rtt_decay_cmd
,
457 "babel rtt-decay (1-256)",
458 "Babel interface commands\n"
459 "Decay factor for exponential moving average of RTT samples\n"
462 VTY_DECLVAR_CONTEXT(interface
, ifp
);
463 babel_interface_nfo
*babel_ifp
;
466 decay
= strtoul(argv
[2]->arg
, NULL
, 10);
468 babel_ifp
= babel_get_if_nfo(ifp
);
469 assert (babel_ifp
!= NULL
);
471 babel_ifp
->rtt_decay
= decay
;
475 DEFUN (babel_set_rtt_min
,
476 babel_set_rtt_min_cmd
,
477 "babel rtt-min (1-65535)",
478 "Babel interface commands\n"
479 "Minimum RTT starting for increasing cost\n"
482 VTY_DECLVAR_CONTEXT(interface
, ifp
);
483 babel_interface_nfo
*babel_ifp
;
486 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
488 babel_ifp
= babel_get_if_nfo(ifp
);
489 assert (babel_ifp
!= NULL
);
491 babel_ifp
->rtt_min
= rtt
;
495 DEFUN (babel_set_rtt_max
,
496 babel_set_rtt_max_cmd
,
497 "babel rtt-max (1-65535)",
498 "Babel interface commands\n"
502 VTY_DECLVAR_CONTEXT(interface
, ifp
);
503 babel_interface_nfo
*babel_ifp
;
506 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
508 babel_ifp
= babel_get_if_nfo(ifp
);
509 assert (babel_ifp
!= NULL
);
511 babel_ifp
->rtt_max
= rtt
;
515 DEFUN (babel_set_max_rtt_penalty
,
516 babel_set_max_rtt_penalty_cmd
,
517 "babel max-rtt-penalty (0-65535)",
518 "Babel interface commands\n"
519 "Maximum additional cost due to RTT\n"
522 VTY_DECLVAR_CONTEXT(interface
, ifp
);
523 babel_interface_nfo
*babel_ifp
;
526 penalty
= strtoul(argv
[2]->arg
, NULL
, 10);
528 babel_ifp
= babel_get_if_nfo(ifp
);
529 assert (babel_ifp
!= NULL
);
531 babel_ifp
->max_rtt_penalty
= penalty
;
535 DEFUN (babel_set_enable_timestamps
,
536 babel_set_enable_timestamps_cmd
,
537 "babel enable-timestamps",
538 "Babel interface commands\n"
539 "Enable timestamps\n")
541 VTY_DECLVAR_CONTEXT(interface
, ifp
);
542 babel_interface_nfo
*babel_ifp
;
544 babel_ifp
= babel_get_if_nfo(ifp
);
545 assert (babel_ifp
!= NULL
);
547 babel_ifp
->flags
|= BABEL_IF_TIMESTAMPS
;
551 DEFUN (no_babel_set_enable_timestamps
,
552 no_babel_set_enable_timestamps_cmd
,
553 "no babel enable-timestamps",
555 "Babel interface commands\n"
556 "Disable timestamps\n")
558 VTY_DECLVAR_CONTEXT(interface
, ifp
);
559 babel_interface_nfo
*babel_ifp
;
561 babel_ifp
= babel_get_if_nfo(ifp
);
562 assert (babel_ifp
!= NULL
);
564 babel_ifp
->flags
&= ~BABEL_IF_TIMESTAMPS
;
568 DEFUN (babel_set_channel
,
569 babel_set_channel_cmd
,
570 "babel channel (1-254)",
571 "Babel interface commands\n"
572 "Channel number for diversity routing\n"
575 VTY_DECLVAR_CONTEXT(interface
, ifp
);
576 babel_interface_nfo
*babel_ifp
;
579 channel
= strtoul(argv
[2]->arg
, NULL
, 10);
581 babel_ifp
= babel_get_if_nfo(ifp
);
582 assert (babel_ifp
!= NULL
);
584 babel_ifp
->channel
= channel
;
588 DEFUN (babel_set_channel_interfering
,
589 babel_set_channel_interfering_cmd
,
590 "babel channel interfering",
591 "Babel interface commands\n"
592 "Channel number for diversity routing\n"
593 "Mark channel as interfering\n")
595 VTY_DECLVAR_CONTEXT(interface
, ifp
);
596 babel_interface_nfo
*babel_ifp
;
598 babel_ifp
= babel_get_if_nfo(ifp
);
599 assert (babel_ifp
!= NULL
);
601 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
605 DEFUN (babel_set_channel_noninterfering
,
606 babel_set_channel_noninterfering_cmd
,
607 "babel channel noninterfering",
608 "Babel interface commands\n"
609 "Channel number for diversity routing\n"
610 "Mark channel as noninterfering\n")
612 VTY_DECLVAR_CONTEXT(interface
, ifp
);
613 babel_interface_nfo
*babel_ifp
;
615 babel_ifp
= babel_get_if_nfo(ifp
);
616 assert (babel_ifp
!= NULL
);
618 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
622 /* This should be no more than half the hello interval, so that hellos
623 aren't sent late. The result is in milliseconds. */
625 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
627 unsigned interval
= babel_ifp
->hello_interval
;
629 interval
= MIN(interval
, 100);
631 interval
= MIN(interval
, 4000);
632 return roughly(interval
) / 4;
636 update_jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
638 unsigned interval
= babel_ifp
->hello_interval
;
640 interval
= MIN(interval
, 100);
642 interval
= MIN(interval
, 4000);
643 return roughly(interval
);
646 /* calculate babeld's specific datas of an interface (change when the interface
649 interface_recalculate(struct interface
*ifp
)
651 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
652 unsigned char *tmp
= NULL
;
654 struct ipv6_mreq mreq
;
659 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
660 interface_reset(ifp
);
664 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
666 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
668 /* We need to be able to fit at least two messages into a packet,
669 so MTUs below 116 require lower layer fragmentation. */
670 /* In IPv6, the minimum MTU is 1280, and every host must be able
671 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
673 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
674 mtu
, ifp
->name
, ifp
->ifindex
);
678 /* 4 for Babel header; 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
679 babel_ifp
->bufsize
= mtu
- 4 - 60;
680 tmp
= babel_ifp
->sendbuf
;
681 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
682 if(babel_ifp
->sendbuf
== NULL
) {
683 flog_err(EC_BABEL_MEMORY
, "Couldn't reallocate sendbuf.");
685 babel_ifp
->bufsize
= 0;
690 rc
= resize_receive_buffer(mtu
);
692 zlog_warn("couldn't resize "
693 "receive buffer for interface %s (%d) (%d bytes).\n",
694 ifp
->name
, ifp
->ifindex
, mtu
);
696 memset(&mreq
, 0, sizeof(mreq
));
697 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
698 mreq
.ipv6mr_interface
= ifp
->ifindex
;
700 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
701 (char*)&mreq
, sizeof(mreq
));
703 flog_err_sys(EC_LIB_SOCKET
,
704 "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
705 ifp
->name
, safe_strerror(errno
));
706 /* This is probably due to a missing link-local address,
707 so down this interface, and wait until the main loop
708 tries to up it again. */
709 interface_reset(ifp
);
713 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
714 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
716 send_request(ifp
, NULL
, 0);
718 update_interface_metric(ifp
);
720 debugf(BABEL_DEBUG_COMMON
,
721 "Upped interface %s (%s, cost=%d, channel=%d%s).",
723 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
726 babel_ifp
->ipv4
? ", IPv4" : "");
729 send_update(ifp
, 0, NULL
, 0);
734 /* Reset the interface as it was new: it's not removed from the interface list,
735 and may be considered as a upped interface. */
737 interface_reset(struct interface
*ifp
)
740 struct ipv6_mreq mreq
;
741 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
743 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
746 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
747 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
749 flush_interface_routes(ifp
, 0);
750 babel_ifp
->buffered
= 0;
751 babel_ifp
->bufsize
= 0;
752 free(babel_ifp
->sendbuf
);
753 babel_ifp
->num_buffered_updates
= 0;
754 babel_ifp
->update_bufsize
= 0;
755 if(babel_ifp
->buffered_updates
)
756 free(babel_ifp
->buffered_updates
);
757 babel_ifp
->buffered_updates
= NULL
;
758 babel_ifp
->sendbuf
= NULL
;
760 if(ifp
->ifindex
> 0) {
761 memset(&mreq
, 0, sizeof(mreq
));
762 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
763 mreq
.ipv6mr_interface
= ifp
->ifindex
;
764 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
765 (char*)&mreq
, sizeof(mreq
));
767 flog_err_sys(EC_LIB_SOCKET
,
768 "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
769 ifp
->name
, safe_strerror(errno
));
772 update_interface_metric(ifp
);
774 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
776 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
778 babel_ifp
->ipv4
? ", IPv4" : "");
783 /* Send retraction to all, and reset all interfaces statistics. */
785 babel_interface_close_all(void)
787 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
788 struct interface
*ifp
= NULL
;
790 FOR_ALL_INTERFACES(vrf
, ifp
) {
793 send_wildcard_retraction(ifp
);
794 /* Make sure that we expire quickly from our neighbours'
795 association caches. */
796 send_hello_noupdate(ifp
, 10);
798 usleep(roughly(1000));
801 FOR_ALL_INTERFACES(vrf
, ifp
) {
804 /* Make sure they got it. */
805 send_wildcard_retraction(ifp
);
806 send_hello_noupdate(ifp
, 1);
808 usleep(roughly(10000));
810 interface_reset(ifp
);
814 /* return "true" if address is one of our ipv6 addresses */
816 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
818 struct connected
*connected
;
819 struct listnode
*node
;
824 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
825 if(connected
->address
->family
== AF_INET6
&&
826 memcmp(&connected
->address
->u
.prefix6
, address
, 16) == 0)
834 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
837 babel_interface_nfo
*babel_ifp
;
839 vty_out (vty
, "%s is %s\n", ifp
->name
,
840 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
841 vty_out (vty
, " ifindex %u, MTU %u bytes %s\n",
842 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
846 vty_out (vty
, " Babel protocol is not enabled on this interface\n");
852 " Babel protocol is enabled, but not running on this interface\n");
855 babel_ifp
= babel_get_if_nfo (ifp
);
856 vty_out (vty
, " Babel protocol is running on this interface\n");
857 vty_out (vty
, " Operating mode is \"%s\"\n",
858 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
859 vty_out (vty
, " Split horizon mode is %s\n",
860 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
861 vty_out (vty
, " Hello interval is %u ms\n", babel_ifp
->hello_interval
);
862 vty_out (vty
, " Update interval is %u ms\n", babel_ifp
->update_interval
);
863 vty_out (vty
, " Rxcost multiplier is %u\n", babel_ifp
->cost
);
866 DEFUN (show_babel_interface
,
867 show_babel_interface_cmd
,
868 "show babel interface [IFNAME]",
870 "Babel information\n"
871 "Interface information\n"
874 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
875 struct interface
*ifp
;
879 FOR_ALL_INTERFACES (vrf
, ifp
)
880 show_babel_interface_sub (vty
, ifp
);
883 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
885 vty_out (vty
, "No such interface name\n");
888 show_babel_interface_sub (vty
, ifp
);
893 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
896 "Neighbour %s dev %s reach %04x rxcost %d txcost %d "
897 "rtt %s rttcost %d%s.\n",
898 format_address(neigh
->address
),
901 neighbour_rxcost(neigh
),
903 format_thousands(neigh
->rtt
),
904 neighbour_rttcost(neigh
),
905 if_up(neigh
->ifp
) ? "" : " (down)");
908 DEFUN (show_babel_neighbour
,
909 show_babel_neighbour_cmd
,
910 "show babel neighbor [IFNAME]",
912 "Babel information\n"
916 struct neighbour
*neigh
;
917 struct interface
*ifp
;
920 FOR_ALL_NEIGHBOURS(neigh
) {
921 show_babel_neighbour_sub(vty
, neigh
);
925 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
927 vty_out (vty
, "No such interface name\n");
930 FOR_ALL_NEIGHBOURS(neigh
) {
931 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
932 show_babel_neighbour_sub(vty
, neigh
);
939 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
941 if(prefix
->family
== AF_INET6
) {
942 if(prefix
->prefixlen
!= plen
||
943 memcmp(&prefix
->u
.prefix6
, p
, 16) != 0)
945 } else if(prefix
->family
== AF_INET
) {
946 if(plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96 ||
947 memcmp(&prefix
->u
.prefix4
, p
+ 12, 4) != 0)
957 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
958 struct prefix
*prefix
)
960 const unsigned char *nexthop
=
961 memcmp(route
->nexthop
, route
->neigh
->address
, 16) == 0 ?
962 NULL
: route
->nexthop
;
965 if(prefix
&& !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
968 if(route
->channels
[0] == 0)
972 snprintf(channels
, 100, " chan (");
973 j
= strlen(channels
);
974 for(k
= 0; k
< DIVERSITY_HOPS
; k
++) {
975 if(route
->channels
[k
] == 0)
979 snprintf(channels
+ j
, 100 - j
, "%u", route
->channels
[k
]);
980 j
= strlen(channels
);
982 snprintf(channels
+ j
, 100 - j
, ")");
988 "%s metric %d refmetric %d id %s seqno %d%s age %d "
989 "via %s neigh %s%s%s%s\n",
990 format_prefix(route
->src
->prefix
, route
->src
->plen
),
991 route_metric(route
), route
->refmetric
,
992 format_eui64(route
->src
->id
),
995 (int)(babel_now
.tv_sec
- route
->time
),
996 route
->neigh
->ifp
->name
,
997 format_address(route
->neigh
->address
),
998 nexthop
? " nexthop " : "",
999 nexthop
? format_address(nexthop
) : "",
1000 route
->installed
? " (installed)" : route_feasible(route
) ? " (feasible)" : "");
1004 show_babel_xroutes_sub (struct xroute
*xroute
, struct vty
*vty
,
1005 struct prefix
*prefix
)
1007 if(prefix
&& !babel_prefix_eq(prefix
, xroute
->prefix
, xroute
->plen
))
1010 vty_out (vty
, "%s metric %d (exported)\n",
1011 format_prefix(xroute
->prefix
, xroute
->plen
),
1015 DEFUN (show_babel_route
,
1016 show_babel_route_cmd
,
1019 "Babel information\n"
1020 "Babel internal routing table\n")
1022 struct route_stream
*routes
= NULL
;
1023 struct xroute_stream
*xroutes
= NULL
;
1024 routes
= route_stream(0);
1027 struct babel_route
*route
= route_stream_next(routes
);
1030 show_babel_routes_sub(route
, vty
, NULL
);
1032 route_stream_done(routes
);
1034 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1036 xroutes
= xroute_stream();
1039 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1042 show_babel_xroutes_sub(xroute
, vty
, NULL
);
1044 xroute_stream_done(xroutes
);
1046 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1051 DEFUN (show_babel_route_prefix
,
1052 show_babel_route_prefix_cmd
,
1053 "show babel route <A.B.C.D/M|X:X::X:X/M>",
1055 "Babel information\n"
1056 "Babel internal routing table\n"
1057 "IPv4 prefix <network>/<length>\n"
1058 "IPv6 prefix <network>/<length>\n")
1060 struct route_stream
*routes
= NULL
;
1061 struct xroute_stream
*xroutes
= NULL
;
1062 struct prefix prefix
;
1065 ret
= str2prefix(argv
[3]->arg
, &prefix
);
1067 vty_out (vty
, "%% Malformed address\n");
1071 routes
= route_stream(0);
1074 struct babel_route
*route
= route_stream_next(routes
);
1077 show_babel_routes_sub(route
, vty
, &prefix
);
1079 route_stream_done(routes
);
1081 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1083 xroutes
= xroute_stream();
1086 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1089 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1091 xroute_stream_done(xroutes
);
1093 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1099 DEFUN (show_babel_route_addr
,
1100 show_babel_route_addr_cmd
,
1101 "show babel route A.B.C.D",
1103 "Babel information\n"
1104 "Babel internal routing table\n"
1105 "IPv4 address <network>/<length>\n")
1107 struct in_addr addr
;
1108 char buf
[INET_ADDRSTRLEN
+ 8];
1109 struct route_stream
*routes
= NULL
;
1110 struct xroute_stream
*xroutes
= NULL
;
1111 struct prefix prefix
;
1114 ret
= inet_aton (argv
[3]->arg
, &addr
);
1116 vty_out (vty
, "%% Malformed address\n");
1120 /* Quagga has no convenient prefix constructors. */
1121 snprintf(buf
, sizeof(buf
), "%s/%d", inet_ntoa(addr
), 32);
1123 ret
= str2prefix(buf
, &prefix
);
1125 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1129 routes
= route_stream(0);
1132 struct babel_route
*route
= route_stream_next(routes
);
1135 show_babel_routes_sub(route
, vty
, &prefix
);
1137 route_stream_done(routes
);
1139 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1141 xroutes
= xroute_stream();
1144 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1147 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1149 xroute_stream_done(xroutes
);
1151 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1156 DEFUN (show_babel_route_addr6
,
1157 show_babel_route_addr6_cmd
,
1158 "show babel route X:X::X:X",
1160 "Babel information\n"
1161 "Babel internal routing table\n"
1162 "IPv6 address <network>/<length>\n")
1164 struct in6_addr addr
;
1165 char buf1
[INET6_ADDRSTRLEN
];
1166 char buf
[INET6_ADDRSTRLEN
+ 8];
1167 struct route_stream
*routes
= NULL
;
1168 struct xroute_stream
*xroutes
= NULL
;
1169 struct prefix prefix
;
1172 ret
= inet_pton (AF_INET6
, argv
[3]->arg
, &addr
);
1174 vty_out (vty
, "%% Malformed address\n");
1178 /* Quagga has no convenient prefix constructors. */
1179 snprintf(buf
, sizeof(buf
), "%s/%d",
1180 inet_ntop(AF_INET6
, &addr
, buf1
, sizeof(buf1
)), 128);
1182 ret
= str2prefix(buf
, &prefix
);
1184 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1188 routes
= route_stream(0);
1191 struct babel_route
*route
= route_stream_next(routes
);
1194 show_babel_routes_sub(route
, vty
, &prefix
);
1196 route_stream_done(routes
);
1198 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1200 xroutes
= xroute_stream();
1203 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1206 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1208 xroute_stream_done(xroutes
);
1210 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1215 DEFUN (show_babel_parameters
,
1216 show_babel_parameters_cmd
,
1217 "show babel parameters",
1219 "Babel information\n"
1220 "Configuration information\n")
1222 struct babel
*babel_ctx
;
1224 vty_out (vty
, " -- Babel running configuration --\n");
1225 show_babel_main_configuration(vty
);
1227 babel_ctx
= babel_lookup();
1229 vty_out (vty
, " -- distribution lists --\n");
1230 config_show_distribute(vty
, babel_ctx
->distribute_ctx
);
1235 int babel_ifp_up(struct interface
*ifp
)
1243 /* initialize interface list */
1244 hook_register_prio(if_add
, 0, babel_if_new_hook
);
1245 hook_register_prio(if_del
, 0, babel_if_delete_hook
);
1247 babel_enable_if
= vector_init (1);
1249 /* install interface node and commands */
1250 install_node (&babel_interface_node
, interface_config_write
);
1253 install_element(BABEL_NODE
, &babel_network_cmd
);
1254 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1255 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1256 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1257 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1258 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1259 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1260 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1261 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1262 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1263 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1264 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1265 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1266 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1267 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1268 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1269 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1270 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1272 /* "show babel ..." commands */
1273 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1274 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1275 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1276 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1277 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1278 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1279 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1282 /* hooks: functions called respectively when struct interface is
1283 created or deleted. */
1285 babel_if_new_hook (struct interface
*ifp
)
1287 ifp
->info
= babel_interface_allocate();
1292 babel_if_delete_hook (struct interface
*ifp
)
1294 babel_interface_free(ifp
->info
);
1299 /* Output an "interface" section for each of the known interfaces with
1300 babeld-specific statement lines where appropriate. */
1302 interface_config_write (struct vty
*vty
)
1304 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1305 struct interface
*ifp
;
1308 FOR_ALL_INTERFACES (vrf
, ifp
) {
1309 vty_frame (vty
, "interface %s\n",ifp
->name
);
1311 vty_out (vty
, " description %s\n",ifp
->desc
);
1312 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1313 /* wireless is the default*/
1314 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1316 vty_out (vty
, " babel wired\n");
1319 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1321 vty_out (vty
, " babel hello-interval %u\n",
1322 babel_ifp
->hello_interval
);
1325 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1327 vty_out (vty
, " babel update-interval %u\n",
1328 babel_ifp
->update_interval
);
1331 /* Some parameters have different defaults for wired/wireless. */
1332 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
)) {
1333 if (!CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1334 vty_out (vty
, " no babel split-horizon\n");
1337 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRED
) {
1338 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1341 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_INTERFERING
) {
1342 vty_out (vty
, " babel channel interfering\n");
1344 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_NONINTERFERING
) {
1345 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1349 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1350 vty_out (vty
, " babel split-horizon\n");
1353 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRELESS
) {
1354 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1357 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_NONINTERFERING
) {
1358 vty_out (vty
, " babel channel noninterfering\n");
1360 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_INTERFERING
) {
1361 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1365 vty_endframe (vty
, "!\n");
1371 /* Output a "network" statement line for each of the enabled interfaces. */
1373 babel_enable_if_config_write (struct vty
* vty
)
1375 unsigned int i
, lines
= 0;
1378 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
1379 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
1381 vty_out (vty
, " network %s\n", str
);
1387 /* functions to allocate or free memory for a babel_interface_nfo, filling
1389 static babel_interface_nfo
*
1390 babel_interface_allocate (void)
1392 babel_interface_nfo
*babel_ifp
;
1393 babel_ifp
= XCALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1394 /* All flags are unset */
1395 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1396 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1397 babel_ifp
->hello_seqno
= (random() & 0xFFFF);
1398 babel_ifp
->rtt_min
= 10000;
1399 babel_ifp
->rtt_max
= 120000;
1400 babel_ifp
->max_rtt_penalty
= 150;
1401 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1402 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1403 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1404 babel_set_wired_internal(babel_ifp
, 0);
1410 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1412 XFREE(MTYPE_BABEL_IF
, babel_ifp
);