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"
31 #include "babel_main.h"
34 #include "babel_interface.h"
37 #include "babel_zebra.h"
38 #include "neighbour.h"
41 #include "babel_memory.h"
43 #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0)
45 static int babel_enable_if_lookup (const char *ifname
);
46 static int babel_enable_if_add (const char *ifname
);
47 static int babel_enable_if_delete (const char *ifname
);
48 static int interface_recalculate(struct interface
*ifp
);
49 static int interface_reset(struct interface
*ifp
);
50 static int babel_if_new_hook (struct interface
*ifp
);
51 static int babel_if_delete_hook (struct interface
*ifp
);
52 static int interface_config_write (struct vty
*vty
);
53 static babel_interface_nfo
* babel_interface_allocate (void);
54 static void babel_interface_free (babel_interface_nfo
*bi
);
57 static vector babel_enable_if
; /* enable interfaces (by cmd). */
58 static struct cmd_node babel_interface_node
= /* babeld's interface node. */
67 babel_interface_up (int cmd
, struct zclient
*client
, zebra_size_t length
, vrf_id_t vrf
)
69 struct stream
*s
= NULL
;
70 struct interface
*ifp
= NULL
;
72 debugf(BABEL_DEBUG_IF
, "receive a 'interface up'");
75 ifp
= zebra_interface_state_read(s
, vrf
); /* it updates iflist */
81 interface_recalculate(ifp
);
86 babel_interface_down (int cmd
, struct zclient
*client
, zebra_size_t length
, vrf_id_t vrf
)
88 struct stream
*s
= NULL
;
89 struct interface
*ifp
= NULL
;
91 debugf(BABEL_DEBUG_IF
, "receive a 'interface down'");
94 ifp
= zebra_interface_state_read(s
, vrf
); /* it updates iflist */
100 interface_reset(ifp
);
105 babel_interface_add (int cmd
, struct zclient
*client
, zebra_size_t length
, vrf_id_t vrf
)
107 struct interface
*ifp
= NULL
;
109 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
111 /* read and add the interface in the iflist. */
112 ifp
= zebra_interface_add_read (zclient
->ibuf
, vrf
);
118 interface_recalculate(ifp
);
123 babel_interface_delete (int cmd
, struct zclient
*client
, zebra_size_t length
, vrf_id_t vrf
)
125 struct interface
*ifp
;
128 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
131 ifp
= zebra_interface_state_read(s
, vrf
); /* it updates iflist */
137 interface_reset(ifp
);
139 /* To support pseudo interface do not free interface structure. */
140 /* if_delete(ifp); */
141 ifp
->ifindex
= IFINDEX_INTERNAL
;
147 babel_interface_address_add (int cmd
, struct zclient
*client
,
148 zebra_size_t length
, vrf_id_t vrf
)
150 babel_interface_nfo
*babel_ifp
;
151 struct connected
*ifc
;
152 struct prefix
*prefix
;
154 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
156 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
162 prefix
= ifc
->address
;
164 if (prefix
->family
== AF_INET
) {
165 flush_interface_routes(ifc
->ifp
, 0);
166 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
167 if (babel_ifp
->ipv4
== NULL
) {
168 babel_ifp
->ipv4
= malloc(4);
169 if (babel_ifp
->ipv4
== NULL
) {
170 zlog_err("not einough memory");
172 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
177 send_request(ifc
->ifp
, NULL
, 0);
178 send_update(ifc
->ifp
, 0, NULL
, 0);
184 babel_interface_address_delete (int cmd
, struct zclient
*client
,
185 zebra_size_t length
, vrf_id_t vrf
)
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
,
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_outln (vty
, "There is same network configuration %s",
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_outln (vty
, "can't find network %s",argv
[2]->arg
);
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 zlog_err("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 zlog_err("setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
731 ifp
->name
, safe_strerror(errno
));
732 /* This is probably due to a missing link-local address,
733 so down this interface, and wait until the main loop
734 tries to up it again. */
735 interface_reset(ifp
);
739 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
740 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
742 send_request(ifp
, NULL
, 0);
744 update_interface_metric(ifp
);
746 debugf(BABEL_DEBUG_COMMON
,
747 "Upped interface %s (%s, cost=%d, channel=%d%s).",
749 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
752 babel_ifp
->ipv4
? ", IPv4" : "");
755 send_update(ifp
, 0, NULL
, 0);
760 /* Reset the interface as it was new: it's not removed from the interface list,
761 and may be considered as a upped interface. */
763 interface_reset(struct interface
*ifp
)
766 struct ipv6_mreq mreq
;
767 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
769 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
772 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
773 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
775 flush_interface_routes(ifp
, 0);
776 babel_ifp
->buffered
= 0;
777 babel_ifp
->bufsize
= 0;
778 free(babel_ifp
->sendbuf
);
779 babel_ifp
->num_buffered_updates
= 0;
780 babel_ifp
->update_bufsize
= 0;
781 if(babel_ifp
->buffered_updates
)
782 free(babel_ifp
->buffered_updates
);
783 babel_ifp
->buffered_updates
= NULL
;
784 babel_ifp
->sendbuf
= NULL
;
786 if(ifp
->ifindex
> 0) {
787 memset(&mreq
, 0, sizeof(mreq
));
788 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
789 mreq
.ipv6mr_interface
= ifp
->ifindex
;
790 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
791 (char*)&mreq
, sizeof(mreq
));
793 zlog_err("setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
794 ifp
->name
, safe_strerror(errno
));
797 update_interface_metric(ifp
);
799 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
801 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
803 babel_ifp
->ipv4
? ", IPv4" : "");
808 /* Send retraction to all, and reset all interfaces statistics. */
810 babel_interface_close_all(void)
812 struct interface
*ifp
= NULL
;
813 struct listnode
*linklist_node
= NULL
;
815 FOR_ALL_INTERFACES(ifp
, linklist_node
) {
818 send_wildcard_retraction(ifp
);
819 /* Make sure that we expire quickly from our neighbours'
820 association caches. */
821 send_hello_noupdate(ifp
, 10);
823 usleep(roughly(1000));
826 FOR_ALL_INTERFACES(ifp
, linklist_node
) {
829 /* Make sure they got it. */
830 send_wildcard_retraction(ifp
);
831 send_hello_noupdate(ifp
, 1);
833 usleep(roughly(10000));
835 interface_reset(ifp
);
839 /* return "true" if address is one of our ipv6 addresses */
841 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
843 struct connected
*connected
;
844 struct listnode
*node
;
849 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
850 if(connected
->address
->family
== AF_INET6
&&
851 memcmp(&connected
->address
->u
.prefix6
, address
, 16) == 0)
859 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
862 babel_interface_nfo
*babel_ifp
;
864 vty_outln (vty
, "%s is %s", ifp
->name
,
865 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
866 vty_outln (vty
, " ifindex %u, MTU %u bytes %s",
867 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
871 vty_outln (vty
, " Babel protocol is not enabled on this interface");
877 " Babel protocol is enabled, but not running on this interface");
880 babel_ifp
= babel_get_if_nfo (ifp
);
881 vty_outln (vty
, " Babel protocol is running on this interface");
882 vty_outln (vty
, " Operating mode is \"%s\"",
883 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
884 vty_outln (vty
, " Split horizon mode is %s",
885 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
886 vty_outln (vty
, " Hello interval is %u ms", babel_ifp
->hello_interval
);
887 vty_outln (vty
, " Update interval is %u ms", babel_ifp
->update_interval
);
888 vty_outln (vty
, " Rxcost multiplier is %u", babel_ifp
->cost
);
891 DEFUN (show_babel_interface
,
892 show_babel_interface_cmd
,
893 "show babel interface [IFNAME]",
895 "Babel information\n"
896 "Interface information\n"
899 struct interface
*ifp
;
900 struct listnode
*node
;
904 for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT
), node
, ifp
))
905 show_babel_interface_sub (vty
, ifp
);
908 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
910 vty_outln (vty
, "No such interface name");
913 show_babel_interface_sub (vty
, ifp
);
918 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
921 "Neighbour %s dev %s reach %04x rxcost %d txcost %d "
922 "rtt %s rttcost %d%s.",
923 format_address(neigh
->address
),
926 neighbour_rxcost(neigh
),
928 format_thousands(neigh
->rtt
),
929 neighbour_rttcost(neigh
),
930 if_up(neigh
->ifp
) ? "" : " (down)");
933 DEFUN (show_babel_neighbour
,
934 show_babel_neighbour_cmd
,
935 "show babel neighbor [IFNAME]",
937 "Babel information\n"
941 struct neighbour
*neigh
;
942 struct interface
*ifp
;
945 FOR_ALL_NEIGHBOURS(neigh
) {
946 show_babel_neighbour_sub(vty
, neigh
);
950 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
952 vty_outln (vty
, "No such interface name");
955 FOR_ALL_NEIGHBOURS(neigh
) {
956 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
957 show_babel_neighbour_sub(vty
, neigh
);
964 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
966 if(prefix
->family
== AF_INET6
) {
967 if(prefix
->prefixlen
!= plen
||
968 memcmp(&prefix
->u
.prefix6
, p
, 16) != 0)
970 } else if(prefix
->family
== AF_INET
) {
971 if(plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96 ||
972 memcmp(&prefix
->u
.prefix4
, p
+ 12, 4) != 0)
982 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
983 struct prefix
*prefix
)
985 const unsigned char *nexthop
=
986 memcmp(route
->nexthop
, route
->neigh
->address
, 16) == 0 ?
987 NULL
: route
->nexthop
;
990 if(prefix
&& !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
993 if(route
->channels
[0] == 0)
997 snprintf(channels
, 100, " chan (");
998 j
= strlen(channels
);
999 for(k
= 0; k
< DIVERSITY_HOPS
; k
++) {
1000 if(route
->channels
[k
] == 0)
1003 channels
[j
++] = ',';
1004 snprintf(channels
+ j
, 100 - j
, "%d", route
->channels
[k
]);
1005 j
= strlen(channels
);
1007 snprintf(channels
+ j
, 100 - j
, ")");
1013 "%s metric %d refmetric %d id %s seqno %d%s age %d "
1014 "via %s neigh %s%s%s%s",
1015 format_prefix(route
->src
->prefix
, route
->src
->plen
),
1016 route_metric(route
), route
->refmetric
,
1017 format_eui64(route
->src
->id
),
1020 (int)(babel_now
.tv_sec
- route
->time
),
1021 route
->neigh
->ifp
->name
,
1022 format_address(route
->neigh
->address
),
1023 nexthop
? " nexthop " : "",
1024 nexthop
? format_address(nexthop
) : "",
1025 route
->installed
? " (installed)" : route_feasible(route
) ? " (feasible)" : "");
1029 show_babel_xroutes_sub (struct xroute
*xroute
, struct vty
*vty
,
1030 struct prefix
*prefix
)
1032 if(prefix
&& !babel_prefix_eq(prefix
, xroute
->prefix
, xroute
->plen
))
1035 vty_outln (vty
, "%s metric %d (exported)",
1036 format_prefix(xroute
->prefix
, xroute
->plen
),
1040 DEFUN (show_babel_route
,
1041 show_babel_route_cmd
,
1044 "Babel information\n"
1045 "Babel internal routing table\n")
1047 struct route_stream
*routes
= NULL
;
1048 struct xroute_stream
*xroutes
= NULL
;
1049 routes
= route_stream(0);
1052 struct babel_route
*route
= route_stream_next(routes
);
1055 show_babel_routes_sub(route
, vty
, NULL
);
1057 route_stream_done(routes
);
1059 zlog_err("Couldn't allocate route stream.");
1061 xroutes
= xroute_stream();
1064 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1067 show_babel_xroutes_sub(xroute
, vty
, NULL
);
1069 xroute_stream_done(xroutes
);
1071 zlog_err("Couldn't allocate route stream.");
1076 DEFUN (show_babel_route_prefix
,
1077 show_babel_route_prefix_cmd
,
1078 "show babel route <A.B.C.D/M|X:X::X:X/M>",
1080 "Babel information\n"
1081 "Babel internal routing table\n"
1082 "IPv4 prefix <network>/<length>\n"
1083 "IPv6 prefix <network>/<length>\n")
1085 struct route_stream
*routes
= NULL
;
1086 struct xroute_stream
*xroutes
= NULL
;
1087 struct prefix prefix
;
1090 ret
= str2prefix(argv
[3]->arg
, &prefix
);
1092 vty_outln (vty
, "%% Malformed address");
1096 routes
= route_stream(0);
1099 struct babel_route
*route
= route_stream_next(routes
);
1102 show_babel_routes_sub(route
, vty
, &prefix
);
1104 route_stream_done(routes
);
1106 zlog_err("Couldn't allocate route stream.");
1108 xroutes
= xroute_stream();
1111 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1114 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1116 xroute_stream_done(xroutes
);
1118 zlog_err("Couldn't allocate route stream.");
1124 DEFUN (show_babel_route_addr
,
1125 show_babel_route_addr_cmd
,
1126 "show babel route A.B.C.D",
1128 "Babel information\n"
1129 "Babel internal routing table\n"
1130 "IPv4 address <network>/<length>\n")
1132 struct in_addr addr
;
1133 char buf
[INET_ADDRSTRLEN
+ 8];
1134 struct route_stream
*routes
= NULL
;
1135 struct xroute_stream
*xroutes
= NULL
;
1136 struct prefix prefix
;
1139 ret
= inet_aton (argv
[3]->arg
, &addr
);
1141 vty_outln (vty
, "%% Malformed address");
1145 /* Quagga has no convenient prefix constructors. */
1146 snprintf(buf
, sizeof(buf
), "%s/%d", inet_ntoa(addr
), 32);
1148 ret
= str2prefix(buf
, &prefix
);
1150 vty_outln (vty
, "%% Parse error -- this shouldn't happen");
1154 routes
= route_stream(0);
1157 struct babel_route
*route
= route_stream_next(routes
);
1160 show_babel_routes_sub(route
, vty
, &prefix
);
1162 route_stream_done(routes
);
1164 zlog_err("Couldn't allocate route stream.");
1166 xroutes
= xroute_stream();
1169 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1172 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1174 xroute_stream_done(xroutes
);
1176 zlog_err("Couldn't allocate route stream.");
1181 DEFUN (show_babel_route_addr6
,
1182 show_babel_route_addr6_cmd
,
1183 "show babel route X:X::X:X",
1185 "Babel information\n"
1186 "Babel internal routing table\n"
1187 "IPv6 address <network>/<length>\n")
1189 struct in6_addr addr
;
1190 char buf1
[INET6_ADDRSTRLEN
];
1191 char buf
[INET6_ADDRSTRLEN
+ 8];
1192 struct route_stream
*routes
= NULL
;
1193 struct xroute_stream
*xroutes
= NULL
;
1194 struct prefix prefix
;
1197 ret
= inet_pton (AF_INET6
, argv
[3]->arg
, &addr
);
1199 vty_outln (vty
, "%% Malformed address");
1203 /* Quagga has no convenient prefix constructors. */
1204 snprintf(buf
, sizeof(buf
), "%s/%d",
1205 inet_ntop(AF_INET6
, &addr
, buf1
, sizeof(buf1
)), 128);
1207 ret
= str2prefix(buf
, &prefix
);
1209 vty_outln (vty
, "%% Parse error -- this shouldn't happen");
1213 routes
= route_stream(0);
1216 struct babel_route
*route
= route_stream_next(routes
);
1219 show_babel_routes_sub(route
, vty
, &prefix
);
1221 route_stream_done(routes
);
1223 zlog_err("Couldn't allocate route stream.");
1225 xroutes
= xroute_stream();
1228 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1231 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1233 xroute_stream_done(xroutes
);
1235 zlog_err("Couldn't allocate route stream.");
1240 DEFUN (show_babel_parameters
,
1241 show_babel_parameters_cmd
,
1242 "show babel parameters",
1244 "Babel information\n"
1245 "Configuration information\n")
1247 vty_outln (vty
, " -- Babel running configuration --");
1248 show_babel_main_configuration(vty
);
1249 vty_outln (vty
, " -- distribution lists --");
1250 config_show_distribute(vty
);
1258 /* initialize interface list */
1259 if_add_hook (IF_NEW_HOOK
, babel_if_new_hook
);
1260 if_add_hook (IF_DELETE_HOOK
, babel_if_delete_hook
);
1262 babel_enable_if
= vector_init (1);
1264 /* install interface node and commands */
1265 install_node (&babel_interface_node
, interface_config_write
);
1268 install_element(BABEL_NODE
, &babel_network_cmd
);
1269 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1270 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1271 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1272 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1273 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1274 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1275 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1276 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1277 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1278 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1279 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1280 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1281 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1282 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1283 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1284 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1285 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1287 /* "show babel ..." commands */
1288 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1289 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1290 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1291 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1292 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1293 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1294 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1297 /* hooks: functions called respectively when struct interface is
1298 created or deleted. */
1300 babel_if_new_hook (struct interface
*ifp
)
1302 ifp
->info
= babel_interface_allocate();
1307 babel_if_delete_hook (struct interface
*ifp
)
1309 babel_interface_free(ifp
->info
);
1314 /* Output an "interface" section for each of the known interfaces with
1315 babeld-specific statement lines where appropriate. */
1317 interface_config_write (struct vty
*vty
)
1319 struct listnode
*node
;
1320 struct interface
*ifp
;
1323 for (ALL_LIST_ELEMENTS_RO (vrf_iflist(VRF_DEFAULT
), node
, ifp
)) {
1324 vty_outln (vty
, "interface %s",ifp
->name
);
1326 vty_outln (vty
, " description %s",ifp
->desc
);
1327 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1328 /* wireless is the default*/
1329 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1331 vty_outln (vty
, " babel wired");
1334 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1336 vty_outln (vty
, " babel hello-interval %u",
1337 babel_ifp
->hello_interval
);
1340 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1342 vty_outln (vty
, " babel update-interval %u",
1343 babel_ifp
->update_interval
);
1346 /* Some parameters have different defaults for wired/wireless. */
1347 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
)) {
1348 if (!CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1349 vty_outln (vty
, " no babel split-horizon");
1352 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRED
) {
1353 vty_outln (vty
, " babel rxcost %u", babel_ifp
->cost
);
1356 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_INTERFERING
) {
1357 vty_outln (vty
, " babel channel interfering");
1359 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_NONINTERFERING
) {
1360 vty_outln (vty
, " babel channel %d",babel_ifp
->channel
);
1364 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1365 vty_outln (vty
, " babel split-horizon");
1368 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRELESS
) {
1369 vty_outln (vty
, " babel rxcost %u", babel_ifp
->cost
);
1372 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_NONINTERFERING
) {
1373 vty_outln (vty
, " babel channel noninterfering");
1375 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_INTERFERING
) {
1376 vty_outln (vty
, " babel channel %d",babel_ifp
->channel
);
1380 vty_outln (vty
, "!");
1386 /* Output a "network" statement line for each of the enabled interfaces. */
1388 babel_enable_if_config_write (struct vty
* vty
)
1390 unsigned int i
, lines
= 0;
1393 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
1394 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
1396 vty_outln (vty
, " network %s", str
);
1402 /* functions to allocate or free memory for a babel_interface_nfo, filling
1404 static babel_interface_nfo
*
1405 babel_interface_allocate (void)
1407 babel_interface_nfo
*babel_ifp
;
1408 babel_ifp
= XMALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1409 if(babel_ifp
== NULL
)
1412 /* Here are set the default values for an interface. */
1413 memset(babel_ifp
, 0, sizeof(babel_interface_nfo
));
1414 /* All flags are unset */
1415 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1416 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1417 babel_ifp
->hello_seqno
= (random() & 0xFFFF);
1418 babel_ifp
->rtt_min
= 10000;
1419 babel_ifp
->rtt_max
= 120000;
1420 babel_ifp
->max_rtt_penalty
= 150;
1421 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1422 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1423 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1424 babel_set_wired_internal(babel_ifp
, 0);
1430 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1432 XFREE(MTYPE_BABEL_IF
, babel_ifp
);