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 (int cmd
, struct zclient
*client
, zebra_size_t length
, vrf_id_t vrf
)
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
); /* it updates iflist */
83 interface_recalculate(ifp
);
88 babel_interface_down (int cmd
, struct zclient
*client
, zebra_size_t length
, vrf_id_t vrf
)
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
); /* it updates iflist */
102 interface_reset(ifp
);
107 babel_interface_add (int cmd
, struct zclient
*client
, zebra_size_t length
, vrf_id_t vrf
)
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
);
120 interface_recalculate(ifp
);
125 babel_interface_delete (int cmd
, struct zclient
*client
, zebra_size_t length
, vrf_id_t vrf
)
127 struct interface
*ifp
;
130 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
133 ifp
= zebra_interface_state_read(s
, vrf
); /* 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 (int cmd
, struct zclient
*client
,
150 zebra_size_t length
, vrf_id_t vrf
)
152 babel_interface_nfo
*babel_ifp
;
153 struct connected
*ifc
;
154 struct prefix
*prefix
;
156 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
158 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
164 prefix
= ifc
->address
;
166 if (prefix
->family
== AF_INET
) {
167 flush_interface_routes(ifc
->ifp
, 0);
168 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
169 if (babel_ifp
->ipv4
== NULL
) {
170 babel_ifp
->ipv4
= malloc(4);
171 if (babel_ifp
->ipv4
== NULL
) {
172 flog_err(EC_BABEL_MEMORY
, "not enough memory");
174 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
179 send_request(ifc
->ifp
, NULL
, 0);
180 send_update(ifc
->ifp
, 0, NULL
, 0);
186 babel_interface_address_delete (int cmd
, struct zclient
*client
,
187 zebra_size_t length
, vrf_id_t vrf
)
189 babel_interface_nfo
*babel_ifp
;
190 struct connected
*ifc
;
191 struct prefix
*prefix
;
193 debugf(BABEL_DEBUG_IF
, "receive a 'interface address delete'");
195 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE
,
201 prefix
= ifc
->address
;
203 if (prefix
->family
== AF_INET
) {
204 flush_interface_routes(ifc
->ifp
, 0);
205 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
206 if (babel_ifp
->ipv4
!= NULL
207 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4) == 0) {
208 free(babel_ifp
->ipv4
);
209 babel_ifp
->ipv4
= NULL
;
213 send_request(ifc
->ifp
, NULL
, 0);
214 send_update(ifc
->ifp
, 0, NULL
, 0);
219 /* Lookup function. */
221 babel_enable_if_lookup (const char *ifname
)
226 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
227 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
228 if (strcmp (str
, ifname
) == 0)
233 /* Add interface to babel_enable_if. */
235 babel_enable_if_add (const char *ifname
)
238 struct interface
*ifp
= NULL
;
240 ret
= babel_enable_if_lookup (ifname
);
244 vector_set (babel_enable_if
, strdup (ifname
));
246 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
248 interface_recalculate(ifp
);
253 /* Delete interface from babel_enable_if. */
255 babel_enable_if_delete (const char *ifname
)
257 int babel_enable_if_index
;
259 struct interface
*ifp
= NULL
;
261 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
262 if (babel_enable_if_index
< 0)
265 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
267 vector_unset (babel_enable_if
, babel_enable_if_index
);
269 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
271 interface_reset(ifp
);
276 /* [Babel Command] Babel enable on specified interface or matched network. */
277 DEFUN (babel_network
,
279 "network IF_OR_ADDR",
280 "Enable Babel protocol on specified interface or network.\n"
281 "Interface or address\n")
286 ret
= str2prefix (argv
[1]->arg
, &p
);
288 /* Given string is: */
289 if (ret
) /* an IPv4 or v6 network */
290 return CMD_ERR_NO_MATCH
; /* not implemented yet */
291 else /* an interface name */
292 ret
= babel_enable_if_add (argv
[1]->arg
);
295 vty_out (vty
, "There is same network configuration %s\n",
303 /* [Babel Command] Babel enable on specified interface or matched network. */
304 DEFUN (no_babel_network
,
305 no_babel_network_cmd
,
306 "no network IF_OR_ADDR",
308 "Disable Babel protocol on specified interface or network.\n"
309 "Interface or address\n")
314 ret
= str2prefix (argv
[2]->arg
, &p
);
316 /* Given string is: */
317 if (ret
) /* an IPv4 or v6 network */
318 return CMD_ERR_NO_MATCH
; /* not implemented yet */
319 else /* an interface name */
320 ret
= babel_enable_if_delete (argv
[2]->arg
);
323 vty_out (vty
, "can't find network %s\n",argv
[2]->arg
);
324 return CMD_WARNING_CONFIG_FAILED
;
330 /* There are a number of interface parameters that must be changed when
331 an interface becomes wired/wireless. In Quagga, they cannot be
332 configured separately. */
335 babel_set_wired_internal(babel_interface_nfo
*babel_ifp
, int wired
)
338 babel_ifp
->flags
|= BABEL_IF_WIRED
;
339 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
340 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRED
;
341 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
342 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
344 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
345 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
346 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRELESS
;
347 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
348 babel_ifp
->flags
|= BABEL_IF_LQ
;
353 /* [Interface Command] Tell the interface is wire. */
354 DEFUN (babel_set_wired
,
357 "Babel interface commands\n"
358 "Enable wired optimizations\n")
360 VTY_DECLVAR_CONTEXT(interface
, ifp
);
361 babel_interface_nfo
*babel_ifp
;
363 babel_ifp
= babel_get_if_nfo(ifp
);
365 assert (babel_ifp
!= NULL
);
366 babel_set_wired_internal(babel_ifp
, 1);
370 /* [Interface Command] Tell the interface is wireless (default). */
371 DEFUN (babel_set_wireless
,
372 babel_set_wireless_cmd
,
374 "Babel interface commands\n"
375 "Disable wired optimizations (assume wireless)\n")
377 VTY_DECLVAR_CONTEXT(interface
, ifp
);
378 babel_interface_nfo
*babel_ifp
;
380 babel_ifp
= babel_get_if_nfo(ifp
);
382 assert (babel_ifp
!= NULL
);
383 babel_set_wired_internal(babel_ifp
, 0);
387 /* [Interface Command] Enable split horizon. */
388 DEFUN (babel_split_horizon
,
389 babel_split_horizon_cmd
,
390 "babel split-horizon",
391 "Babel interface commands\n"
392 "Enable split horizon processing\n")
394 VTY_DECLVAR_CONTEXT(interface
, ifp
);
395 babel_interface_nfo
*babel_ifp
;
397 babel_ifp
= babel_get_if_nfo(ifp
);
399 assert (babel_ifp
!= NULL
);
400 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
404 /* [Interface Command] Disable split horizon (default). */
405 DEFUN (no_babel_split_horizon
,
406 no_babel_split_horizon_cmd
,
407 "no babel split-horizon",
409 "Babel interface commands\n"
410 "Disable split horizon processing\n")
412 VTY_DECLVAR_CONTEXT(interface
, ifp
);
413 babel_interface_nfo
*babel_ifp
;
415 babel_ifp
= babel_get_if_nfo(ifp
);
417 assert (babel_ifp
!= NULL
);
418 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
422 /* [Interface Command]. */
423 DEFUN (babel_set_hello_interval
,
424 babel_set_hello_interval_cmd
,
425 "babel hello-interval (20-655340)",
426 "Babel interface commands\n"
427 "Time between scheduled hellos\n"
430 VTY_DECLVAR_CONTEXT(interface
, ifp
);
431 babel_interface_nfo
*babel_ifp
;
434 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
436 babel_ifp
= babel_get_if_nfo(ifp
);
437 assert (babel_ifp
!= NULL
);
439 babel_ifp
->hello_interval
= interval
;
443 /* [Interface Command]. */
444 DEFUN (babel_set_update_interval
,
445 babel_set_update_interval_cmd
,
446 "babel update-interval (20-655340)",
447 "Babel interface commands\n"
448 "Time between scheduled updates\n"
451 VTY_DECLVAR_CONTEXT(interface
, ifp
);
452 babel_interface_nfo
*babel_ifp
;
455 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
457 babel_ifp
= babel_get_if_nfo(ifp
);
458 assert (babel_ifp
!= NULL
);
460 babel_ifp
->update_interval
= interval
;
464 DEFUN (babel_set_rxcost
,
465 babel_set_rxcost_cmd
,
466 "babel rxcost (1-65534)",
467 "Babel interface commands\n"
468 "Rxcost multiplier\n"
471 VTY_DECLVAR_CONTEXT(interface
, ifp
);
472 babel_interface_nfo
*babel_ifp
;
475 rxcost
= strtoul(argv
[2]->arg
, NULL
, 10);
477 babel_ifp
= babel_get_if_nfo(ifp
);
478 assert (babel_ifp
!= NULL
);
480 babel_ifp
->cost
= rxcost
;
484 DEFUN (babel_set_rtt_decay
,
485 babel_set_rtt_decay_cmd
,
486 "babel rtt-decay (1-256)",
487 "Babel interface commands\n"
488 "Decay factor for exponential moving average of RTT samples\n"
491 VTY_DECLVAR_CONTEXT(interface
, ifp
);
492 babel_interface_nfo
*babel_ifp
;
495 decay
= strtoul(argv
[2]->arg
, NULL
, 10);
497 babel_ifp
= babel_get_if_nfo(ifp
);
498 assert (babel_ifp
!= NULL
);
500 babel_ifp
->rtt_decay
= decay
;
504 DEFUN (babel_set_rtt_min
,
505 babel_set_rtt_min_cmd
,
506 "babel rtt-min (1-65535)",
507 "Babel interface commands\n"
508 "Minimum RTT starting for increasing cost\n"
511 VTY_DECLVAR_CONTEXT(interface
, ifp
);
512 babel_interface_nfo
*babel_ifp
;
515 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
517 babel_ifp
= babel_get_if_nfo(ifp
);
518 assert (babel_ifp
!= NULL
);
520 babel_ifp
->rtt_min
= rtt
;
524 DEFUN (babel_set_rtt_max
,
525 babel_set_rtt_max_cmd
,
526 "babel rtt-max (1-65535)",
527 "Babel interface commands\n"
531 VTY_DECLVAR_CONTEXT(interface
, ifp
);
532 babel_interface_nfo
*babel_ifp
;
535 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
537 babel_ifp
= babel_get_if_nfo(ifp
);
538 assert (babel_ifp
!= NULL
);
540 babel_ifp
->rtt_max
= rtt
;
544 DEFUN (babel_set_max_rtt_penalty
,
545 babel_set_max_rtt_penalty_cmd
,
546 "babel max-rtt-penalty (0-65535)",
547 "Babel interface commands\n"
548 "Maximum additional cost due to RTT\n"
551 VTY_DECLVAR_CONTEXT(interface
, ifp
);
552 babel_interface_nfo
*babel_ifp
;
555 penalty
= strtoul(argv
[2]->arg
, NULL
, 10);
557 babel_ifp
= babel_get_if_nfo(ifp
);
558 assert (babel_ifp
!= NULL
);
560 babel_ifp
->max_rtt_penalty
= penalty
;
564 DEFUN (babel_set_enable_timestamps
,
565 babel_set_enable_timestamps_cmd
,
566 "babel enable-timestamps",
567 "Babel interface commands\n"
568 "Enable timestamps\n")
570 VTY_DECLVAR_CONTEXT(interface
, ifp
);
571 babel_interface_nfo
*babel_ifp
;
573 babel_ifp
= babel_get_if_nfo(ifp
);
574 assert (babel_ifp
!= NULL
);
576 babel_ifp
->flags
|= BABEL_IF_TIMESTAMPS
;
580 DEFUN (no_babel_set_enable_timestamps
,
581 no_babel_set_enable_timestamps_cmd
,
582 "no babel enable-timestamps",
584 "Babel interface commands\n"
585 "Disable timestamps\n")
587 VTY_DECLVAR_CONTEXT(interface
, ifp
);
588 babel_interface_nfo
*babel_ifp
;
590 babel_ifp
= babel_get_if_nfo(ifp
);
591 assert (babel_ifp
!= NULL
);
593 babel_ifp
->flags
&= ~BABEL_IF_TIMESTAMPS
;
597 DEFUN (babel_set_channel
,
598 babel_set_channel_cmd
,
599 "babel channel (1-254)",
600 "Babel interface commands\n"
601 "Channel number for diversity routing\n"
604 VTY_DECLVAR_CONTEXT(interface
, ifp
);
605 babel_interface_nfo
*babel_ifp
;
608 channel
= strtoul(argv
[2]->arg
, NULL
, 10);
610 babel_ifp
= babel_get_if_nfo(ifp
);
611 assert (babel_ifp
!= NULL
);
613 babel_ifp
->channel
= channel
;
617 DEFUN (babel_set_channel_interfering
,
618 babel_set_channel_interfering_cmd
,
619 "babel channel interfering",
620 "Babel interface commands\n"
621 "Channel number for diversity routing\n"
622 "Mark channel as interfering\n")
624 VTY_DECLVAR_CONTEXT(interface
, ifp
);
625 babel_interface_nfo
*babel_ifp
;
627 babel_ifp
= babel_get_if_nfo(ifp
);
628 assert (babel_ifp
!= NULL
);
630 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
634 DEFUN (babel_set_channel_noninterfering
,
635 babel_set_channel_noninterfering_cmd
,
636 "babel channel noninterfering",
637 "Babel interface commands\n"
638 "Channel number for diversity routing\n"
639 "Mark channel as noninterfering\n")
641 VTY_DECLVAR_CONTEXT(interface
, ifp
);
642 babel_interface_nfo
*babel_ifp
;
644 babel_ifp
= babel_get_if_nfo(ifp
);
645 assert (babel_ifp
!= NULL
);
647 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
651 /* This should be no more than half the hello interval, so that hellos
652 aren't sent late. The result is in milliseconds. */
654 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
656 unsigned interval
= babel_ifp
->hello_interval
;
658 interval
= MIN(interval
, 100);
660 interval
= MIN(interval
, 4000);
661 return roughly(interval
) / 4;
665 update_jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
667 unsigned interval
= babel_ifp
->hello_interval
;
669 interval
= MIN(interval
, 100);
671 interval
= MIN(interval
, 4000);
672 return roughly(interval
);
675 /* calculate babeld's specific datas of an interface (change when the interface
678 interface_recalculate(struct interface
*ifp
)
680 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
681 unsigned char *tmp
= NULL
;
683 struct ipv6_mreq mreq
;
688 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
689 interface_reset(ifp
);
693 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
695 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
697 /* We need to be able to fit at least two messages into a packet,
698 so MTUs below 116 require lower layer fragmentation. */
699 /* In IPv6, the minimum MTU is 1280, and every host must be able
700 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
702 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
703 mtu
, ifp
->name
, ifp
->ifindex
);
707 /* 4 for Babel header; 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
708 babel_ifp
->bufsize
= mtu
- 4 - 60;
709 tmp
= babel_ifp
->sendbuf
;
710 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
711 if(babel_ifp
->sendbuf
== NULL
) {
712 flog_err(EC_BABEL_MEMORY
, "Couldn't reallocate sendbuf.");
714 babel_ifp
->bufsize
= 0;
719 rc
= resize_receive_buffer(mtu
);
721 zlog_warn("couldn't resize "
722 "receive buffer for interface %s (%d) (%d bytes).\n",
723 ifp
->name
, ifp
->ifindex
, mtu
);
725 memset(&mreq
, 0, sizeof(mreq
));
726 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
727 mreq
.ipv6mr_interface
= ifp
->ifindex
;
729 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
730 (char*)&mreq
, sizeof(mreq
));
732 flog_err_sys(EC_LIB_SOCKET
,
733 "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
734 ifp
->name
, safe_strerror(errno
));
735 /* This is probably due to a missing link-local address,
736 so down this interface, and wait until the main loop
737 tries to up it again. */
738 interface_reset(ifp
);
742 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
743 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
745 send_request(ifp
, NULL
, 0);
747 update_interface_metric(ifp
);
749 debugf(BABEL_DEBUG_COMMON
,
750 "Upped interface %s (%s, cost=%d, channel=%d%s).",
752 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
755 babel_ifp
->ipv4
? ", IPv4" : "");
758 send_update(ifp
, 0, NULL
, 0);
763 /* Reset the interface as it was new: it's not removed from the interface list,
764 and may be considered as a upped interface. */
766 interface_reset(struct interface
*ifp
)
769 struct ipv6_mreq mreq
;
770 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
772 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
775 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
776 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
778 flush_interface_routes(ifp
, 0);
779 babel_ifp
->buffered
= 0;
780 babel_ifp
->bufsize
= 0;
781 free(babel_ifp
->sendbuf
);
782 babel_ifp
->num_buffered_updates
= 0;
783 babel_ifp
->update_bufsize
= 0;
784 if(babel_ifp
->buffered_updates
)
785 free(babel_ifp
->buffered_updates
);
786 babel_ifp
->buffered_updates
= NULL
;
787 babel_ifp
->sendbuf
= NULL
;
789 if(ifp
->ifindex
> 0) {
790 memset(&mreq
, 0, sizeof(mreq
));
791 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
792 mreq
.ipv6mr_interface
= ifp
->ifindex
;
793 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
794 (char*)&mreq
, sizeof(mreq
));
796 flog_err_sys(EC_LIB_SOCKET
,
797 "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
798 ifp
->name
, safe_strerror(errno
));
801 update_interface_metric(ifp
);
803 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
805 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
807 babel_ifp
->ipv4
? ", IPv4" : "");
812 /* Send retraction to all, and reset all interfaces statistics. */
814 babel_interface_close_all(void)
816 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
817 struct interface
*ifp
= NULL
;
819 FOR_ALL_INTERFACES(vrf
, ifp
) {
822 send_wildcard_retraction(ifp
);
823 /* Make sure that we expire quickly from our neighbours'
824 association caches. */
825 send_hello_noupdate(ifp
, 10);
827 usleep(roughly(1000));
830 FOR_ALL_INTERFACES(vrf
, ifp
) {
833 /* Make sure they got it. */
834 send_wildcard_retraction(ifp
);
835 send_hello_noupdate(ifp
, 1);
837 usleep(roughly(10000));
839 interface_reset(ifp
);
843 /* return "true" if address is one of our ipv6 addresses */
845 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
847 struct connected
*connected
;
848 struct listnode
*node
;
853 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
854 if(connected
->address
->family
== AF_INET6
&&
855 memcmp(&connected
->address
->u
.prefix6
, address
, 16) == 0)
863 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
866 babel_interface_nfo
*babel_ifp
;
868 vty_out (vty
, "%s is %s\n", ifp
->name
,
869 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
870 vty_out (vty
, " ifindex %u, MTU %u bytes %s\n",
871 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
875 vty_out (vty
, " Babel protocol is not enabled on this interface\n");
881 " Babel protocol is enabled, but not running on this interface\n");
884 babel_ifp
= babel_get_if_nfo (ifp
);
885 vty_out (vty
, " Babel protocol is running on this interface\n");
886 vty_out (vty
, " Operating mode is \"%s\"\n",
887 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
888 vty_out (vty
, " Split horizon mode is %s\n",
889 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
890 vty_out (vty
, " Hello interval is %u ms\n", babel_ifp
->hello_interval
);
891 vty_out (vty
, " Update interval is %u ms\n", babel_ifp
->update_interval
);
892 vty_out (vty
, " Rxcost multiplier is %u\n", babel_ifp
->cost
);
895 DEFUN (show_babel_interface
,
896 show_babel_interface_cmd
,
897 "show babel interface [IFNAME]",
899 "Babel information\n"
900 "Interface information\n"
903 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
904 struct interface
*ifp
;
908 FOR_ALL_INTERFACES (vrf
, ifp
)
909 show_babel_interface_sub (vty
, ifp
);
912 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
914 vty_out (vty
, "No such interface name\n");
917 show_babel_interface_sub (vty
, ifp
);
922 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
925 "Neighbour %s dev %s reach %04x rxcost %d txcost %d "
926 "rtt %s rttcost %d%s.\n",
927 format_address(neigh
->address
),
930 neighbour_rxcost(neigh
),
932 format_thousands(neigh
->rtt
),
933 neighbour_rttcost(neigh
),
934 if_up(neigh
->ifp
) ? "" : " (down)");
937 DEFUN (show_babel_neighbour
,
938 show_babel_neighbour_cmd
,
939 "show babel neighbor [IFNAME]",
941 "Babel information\n"
945 struct neighbour
*neigh
;
946 struct interface
*ifp
;
949 FOR_ALL_NEIGHBOURS(neigh
) {
950 show_babel_neighbour_sub(vty
, neigh
);
954 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
956 vty_out (vty
, "No such interface name\n");
959 FOR_ALL_NEIGHBOURS(neigh
) {
960 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
961 show_babel_neighbour_sub(vty
, neigh
);
968 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
970 if(prefix
->family
== AF_INET6
) {
971 if(prefix
->prefixlen
!= plen
||
972 memcmp(&prefix
->u
.prefix6
, p
, 16) != 0)
974 } else if(prefix
->family
== AF_INET
) {
975 if(plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96 ||
976 memcmp(&prefix
->u
.prefix4
, p
+ 12, 4) != 0)
986 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
987 struct prefix
*prefix
)
989 const unsigned char *nexthop
=
990 memcmp(route
->nexthop
, route
->neigh
->address
, 16) == 0 ?
991 NULL
: route
->nexthop
;
994 if(prefix
&& !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
997 if(route
->channels
[0] == 0)
1001 snprintf(channels
, 100, " chan (");
1002 j
= strlen(channels
);
1003 for(k
= 0; k
< DIVERSITY_HOPS
; k
++) {
1004 if(route
->channels
[k
] == 0)
1007 channels
[j
++] = ',';
1008 snprintf(channels
+ j
, 100 - j
, "%u", route
->channels
[k
]);
1009 j
= strlen(channels
);
1011 snprintf(channels
+ j
, 100 - j
, ")");
1017 "%s metric %d refmetric %d id %s seqno %d%s age %d "
1018 "via %s neigh %s%s%s%s\n",
1019 format_prefix(route
->src
->prefix
, route
->src
->plen
),
1020 route_metric(route
), route
->refmetric
,
1021 format_eui64(route
->src
->id
),
1024 (int)(babel_now
.tv_sec
- route
->time
),
1025 route
->neigh
->ifp
->name
,
1026 format_address(route
->neigh
->address
),
1027 nexthop
? " nexthop " : "",
1028 nexthop
? format_address(nexthop
) : "",
1029 route
->installed
? " (installed)" : route_feasible(route
) ? " (feasible)" : "");
1033 show_babel_xroutes_sub (struct xroute
*xroute
, struct vty
*vty
,
1034 struct prefix
*prefix
)
1036 if(prefix
&& !babel_prefix_eq(prefix
, xroute
->prefix
, xroute
->plen
))
1039 vty_out (vty
, "%s metric %d (exported)\n",
1040 format_prefix(xroute
->prefix
, xroute
->plen
),
1044 DEFUN (show_babel_route
,
1045 show_babel_route_cmd
,
1048 "Babel information\n"
1049 "Babel internal routing table\n")
1051 struct route_stream
*routes
= NULL
;
1052 struct xroute_stream
*xroutes
= NULL
;
1053 routes
= route_stream(0);
1056 struct babel_route
*route
= route_stream_next(routes
);
1059 show_babel_routes_sub(route
, vty
, NULL
);
1061 route_stream_done(routes
);
1063 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1065 xroutes
= xroute_stream();
1068 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1071 show_babel_xroutes_sub(xroute
, vty
, NULL
);
1073 xroute_stream_done(xroutes
);
1075 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1080 DEFUN (show_babel_route_prefix
,
1081 show_babel_route_prefix_cmd
,
1082 "show babel route <A.B.C.D/M|X:X::X:X/M>",
1084 "Babel information\n"
1085 "Babel internal routing table\n"
1086 "IPv4 prefix <network>/<length>\n"
1087 "IPv6 prefix <network>/<length>\n")
1089 struct route_stream
*routes
= NULL
;
1090 struct xroute_stream
*xroutes
= NULL
;
1091 struct prefix prefix
;
1094 ret
= str2prefix(argv
[3]->arg
, &prefix
);
1096 vty_out (vty
, "%% Malformed address\n");
1100 routes
= route_stream(0);
1103 struct babel_route
*route
= route_stream_next(routes
);
1106 show_babel_routes_sub(route
, vty
, &prefix
);
1108 route_stream_done(routes
);
1110 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1112 xroutes
= xroute_stream();
1115 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1118 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1120 xroute_stream_done(xroutes
);
1122 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1128 DEFUN (show_babel_route_addr
,
1129 show_babel_route_addr_cmd
,
1130 "show babel route A.B.C.D",
1132 "Babel information\n"
1133 "Babel internal routing table\n"
1134 "IPv4 address <network>/<length>\n")
1136 struct in_addr addr
;
1137 char buf
[INET_ADDRSTRLEN
+ 8];
1138 struct route_stream
*routes
= NULL
;
1139 struct xroute_stream
*xroutes
= NULL
;
1140 struct prefix prefix
;
1143 ret
= inet_aton (argv
[3]->arg
, &addr
);
1145 vty_out (vty
, "%% Malformed address\n");
1149 /* Quagga has no convenient prefix constructors. */
1150 snprintf(buf
, sizeof(buf
), "%s/%d", inet_ntoa(addr
), 32);
1152 ret
= str2prefix(buf
, &prefix
);
1154 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1158 routes
= route_stream(0);
1161 struct babel_route
*route
= route_stream_next(routes
);
1164 show_babel_routes_sub(route
, vty
, &prefix
);
1166 route_stream_done(routes
);
1168 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1170 xroutes
= xroute_stream();
1173 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1176 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1178 xroute_stream_done(xroutes
);
1180 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1185 DEFUN (show_babel_route_addr6
,
1186 show_babel_route_addr6_cmd
,
1187 "show babel route X:X::X:X",
1189 "Babel information\n"
1190 "Babel internal routing table\n"
1191 "IPv6 address <network>/<length>\n")
1193 struct in6_addr addr
;
1194 char buf1
[INET6_ADDRSTRLEN
];
1195 char buf
[INET6_ADDRSTRLEN
+ 8];
1196 struct route_stream
*routes
= NULL
;
1197 struct xroute_stream
*xroutes
= NULL
;
1198 struct prefix prefix
;
1201 ret
= inet_pton (AF_INET6
, argv
[3]->arg
, &addr
);
1203 vty_out (vty
, "%% Malformed address\n");
1207 /* Quagga has no convenient prefix constructors. */
1208 snprintf(buf
, sizeof(buf
), "%s/%d",
1209 inet_ntop(AF_INET6
, &addr
, buf1
, sizeof(buf1
)), 128);
1211 ret
= str2prefix(buf
, &prefix
);
1213 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1217 routes
= route_stream(0);
1220 struct babel_route
*route
= route_stream_next(routes
);
1223 show_babel_routes_sub(route
, vty
, &prefix
);
1225 route_stream_done(routes
);
1227 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1229 xroutes
= xroute_stream();
1232 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1235 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1237 xroute_stream_done(xroutes
);
1239 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1244 DEFUN (show_babel_parameters
,
1245 show_babel_parameters_cmd
,
1246 "show babel parameters",
1248 "Babel information\n"
1249 "Configuration information\n")
1251 vty_out (vty
, " -- Babel running configuration --\n");
1252 show_babel_main_configuration(vty
);
1253 vty_out (vty
, " -- distribution lists --\n");
1254 config_show_distribute(vty
);
1262 /* initialize interface list */
1263 hook_register_prio(if_add
, 0, babel_if_new_hook
);
1264 hook_register_prio(if_del
, 0, babel_if_delete_hook
);
1266 babel_enable_if
= vector_init (1);
1268 /* install interface node and commands */
1269 install_node (&babel_interface_node
, interface_config_write
);
1272 install_element(BABEL_NODE
, &babel_network_cmd
);
1273 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1274 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1275 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1276 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1277 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1278 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1279 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1280 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1281 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1282 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1283 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1284 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1285 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1286 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1287 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1288 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1289 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1291 /* "show babel ..." commands */
1292 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1293 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1294 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1295 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1296 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1297 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1298 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1301 /* hooks: functions called respectively when struct interface is
1302 created or deleted. */
1304 babel_if_new_hook (struct interface
*ifp
)
1306 ifp
->info
= babel_interface_allocate();
1311 babel_if_delete_hook (struct interface
*ifp
)
1313 babel_interface_free(ifp
->info
);
1318 /* Output an "interface" section for each of the known interfaces with
1319 babeld-specific statement lines where appropriate. */
1321 interface_config_write (struct vty
*vty
)
1323 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1324 struct interface
*ifp
;
1327 FOR_ALL_INTERFACES (vrf
, ifp
) {
1328 vty_frame (vty
, "interface %s\n",ifp
->name
);
1330 vty_out (vty
, " description %s\n",ifp
->desc
);
1331 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1332 /* wireless is the default*/
1333 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1335 vty_out (vty
, " babel wired\n");
1338 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1340 vty_out (vty
, " babel hello-interval %u\n",
1341 babel_ifp
->hello_interval
);
1344 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1346 vty_out (vty
, " babel update-interval %u\n",
1347 babel_ifp
->update_interval
);
1350 /* Some parameters have different defaults for wired/wireless. */
1351 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
)) {
1352 if (!CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1353 vty_out (vty
, " no babel split-horizon\n");
1356 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRED
) {
1357 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1360 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_INTERFERING
) {
1361 vty_out (vty
, " babel channel interfering\n");
1363 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_NONINTERFERING
) {
1364 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1368 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1369 vty_out (vty
, " babel split-horizon\n");
1372 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRELESS
) {
1373 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1376 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_NONINTERFERING
) {
1377 vty_out (vty
, " babel channel noninterfering\n");
1379 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_INTERFERING
) {
1380 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1384 vty_endframe (vty
, "!\n");
1390 /* Output a "network" statement line for each of the enabled interfaces. */
1392 babel_enable_if_config_write (struct vty
* vty
)
1394 unsigned int i
, lines
= 0;
1397 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
1398 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
1400 vty_out (vty
, " network %s\n", str
);
1406 /* functions to allocate or free memory for a babel_interface_nfo, filling
1408 static babel_interface_nfo
*
1409 babel_interface_allocate (void)
1411 babel_interface_nfo
*babel_ifp
;
1412 babel_ifp
= XMALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1413 if(babel_ifp
== NULL
)
1416 /* Here are set the default values for an interface. */
1417 memset(babel_ifp
, 0, sizeof(babel_interface_nfo
));
1418 /* All flags are unset */
1419 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1420 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1421 babel_ifp
->hello_seqno
= (random() & 0xFFFF);
1422 babel_ifp
->rtt_min
= 10000;
1423 babel_ifp
->rtt_max
= 120000;
1424 babel_ifp
->max_rtt_penalty
= 150;
1425 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1426 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1427 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1428 babel_set_wired_internal(babel_ifp
, 0);
1434 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1436 XFREE(MTYPE_BABEL_IF
, babel_ifp
);