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_interface_down (ZAPI_CALLBACK_ARGS
)
91 struct stream
*s
= NULL
;
92 struct interface
*ifp
= NULL
;
94 debugf(BABEL_DEBUG_IF
, "receive a 'interface down'");
97 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
103 interface_reset(ifp
);
108 babel_interface_add (ZAPI_CALLBACK_ARGS
)
110 struct interface
*ifp
= NULL
;
112 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
114 /* read and add the interface in the iflist. */
115 ifp
= zebra_interface_add_read (zclient
->ibuf
, vrf_id
);
121 interface_recalculate(ifp
);
126 babel_interface_delete (ZAPI_CALLBACK_ARGS
)
128 struct interface
*ifp
;
131 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
134 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
140 interface_reset(ifp
);
142 /* To support pseudo interface do not free interface structure. */
143 /* if_delete(ifp); */
144 if_set_index(ifp
, IFINDEX_INTERNAL
);
150 babel_interface_address_add (ZAPI_CALLBACK_ARGS
)
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
,
159 zclient
->ibuf
, vrf_id
);
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 (ZAPI_CALLBACK_ARGS
)
188 babel_interface_nfo
*babel_ifp
;
189 struct connected
*ifc
;
190 struct prefix
*prefix
;
192 debugf(BABEL_DEBUG_IF
, "receive a 'interface address delete'");
194 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE
,
195 zclient
->ibuf
, vrf_id
);
200 prefix
= ifc
->address
;
202 if (prefix
->family
== AF_INET
) {
203 flush_interface_routes(ifc
->ifp
, 0);
204 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
205 if (babel_ifp
->ipv4
!= NULL
206 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4) == 0) {
207 free(babel_ifp
->ipv4
);
208 babel_ifp
->ipv4
= NULL
;
212 send_request(ifc
->ifp
, NULL
, 0);
213 send_update(ifc
->ifp
, 0, NULL
, 0);
218 /* Lookup function. */
220 babel_enable_if_lookup (const char *ifname
)
225 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
226 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
227 if (strcmp (str
, ifname
) == 0)
232 /* Add interface to babel_enable_if. */
234 babel_enable_if_add (const char *ifname
)
237 struct interface
*ifp
= NULL
;
239 ret
= babel_enable_if_lookup (ifname
);
243 vector_set (babel_enable_if
, strdup (ifname
));
245 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
247 interface_recalculate(ifp
);
252 /* Delete interface from babel_enable_if. */
254 babel_enable_if_delete (const char *ifname
)
256 int babel_enable_if_index
;
258 struct interface
*ifp
= NULL
;
260 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
261 if (babel_enable_if_index
< 0)
264 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
266 vector_unset (babel_enable_if
, babel_enable_if_index
);
268 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
270 interface_reset(ifp
);
275 /* [Babel Command] Babel enable on specified interface or matched network. */
276 DEFUN (babel_network
,
278 "network IF_OR_ADDR",
279 "Enable Babel protocol on specified interface or network.\n"
280 "Interface or address\n")
285 ret
= str2prefix (argv
[1]->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_add (argv
[1]->arg
);
294 vty_out (vty
, "There is same network configuration %s\n",
302 /* [Babel Command] Babel enable on specified interface or matched network. */
303 DEFUN (no_babel_network
,
304 no_babel_network_cmd
,
305 "no network IF_OR_ADDR",
307 "Disable Babel protocol on specified interface or network.\n"
308 "Interface or address\n")
313 ret
= str2prefix (argv
[2]->arg
, &p
);
315 /* Given string is: */
316 if (ret
) /* an IPv4 or v6 network */
317 return CMD_ERR_NO_MATCH
; /* not implemented yet */
318 else /* an interface name */
319 ret
= babel_enable_if_delete (argv
[2]->arg
);
322 vty_out (vty
, "can't find network %s\n",argv
[2]->arg
);
323 return CMD_WARNING_CONFIG_FAILED
;
329 /* There are a number of interface parameters that must be changed when
330 an interface becomes wired/wireless. In Quagga, they cannot be
331 configured separately. */
334 babel_set_wired_internal(babel_interface_nfo
*babel_ifp
, int wired
)
337 babel_ifp
->flags
|= BABEL_IF_WIRED
;
338 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
339 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRED
;
340 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
341 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
343 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
344 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
345 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRELESS
;
346 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
347 babel_ifp
->flags
|= BABEL_IF_LQ
;
352 /* [Interface Command] Tell the interface is wire. */
353 DEFUN (babel_set_wired
,
356 "Babel interface commands\n"
357 "Enable wired optimizations\n")
359 VTY_DECLVAR_CONTEXT(interface
, ifp
);
360 babel_interface_nfo
*babel_ifp
;
362 babel_ifp
= babel_get_if_nfo(ifp
);
364 assert (babel_ifp
!= NULL
);
365 babel_set_wired_internal(babel_ifp
, 1);
369 /* [Interface Command] Tell the interface is wireless (default). */
370 DEFUN (babel_set_wireless
,
371 babel_set_wireless_cmd
,
373 "Babel interface commands\n"
374 "Disable wired optimizations (assume wireless)\n")
376 VTY_DECLVAR_CONTEXT(interface
, ifp
);
377 babel_interface_nfo
*babel_ifp
;
379 babel_ifp
= babel_get_if_nfo(ifp
);
381 assert (babel_ifp
!= NULL
);
382 babel_set_wired_internal(babel_ifp
, 0);
386 /* [Interface Command] Enable split horizon. */
387 DEFUN (babel_split_horizon
,
388 babel_split_horizon_cmd
,
389 "babel split-horizon",
390 "Babel interface commands\n"
391 "Enable split horizon processing\n")
393 VTY_DECLVAR_CONTEXT(interface
, ifp
);
394 babel_interface_nfo
*babel_ifp
;
396 babel_ifp
= babel_get_if_nfo(ifp
);
398 assert (babel_ifp
!= NULL
);
399 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
403 /* [Interface Command] Disable split horizon (default). */
404 DEFUN (no_babel_split_horizon
,
405 no_babel_split_horizon_cmd
,
406 "no babel split-horizon",
408 "Babel interface commands\n"
409 "Disable split horizon processing\n")
411 VTY_DECLVAR_CONTEXT(interface
, ifp
);
412 babel_interface_nfo
*babel_ifp
;
414 babel_ifp
= babel_get_if_nfo(ifp
);
416 assert (babel_ifp
!= NULL
);
417 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
421 /* [Interface Command]. */
422 DEFUN (babel_set_hello_interval
,
423 babel_set_hello_interval_cmd
,
424 "babel hello-interval (20-655340)",
425 "Babel interface commands\n"
426 "Time between scheduled hellos\n"
429 VTY_DECLVAR_CONTEXT(interface
, ifp
);
430 babel_interface_nfo
*babel_ifp
;
433 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
435 babel_ifp
= babel_get_if_nfo(ifp
);
436 assert (babel_ifp
!= NULL
);
438 babel_ifp
->hello_interval
= interval
;
442 /* [Interface Command]. */
443 DEFUN (babel_set_update_interval
,
444 babel_set_update_interval_cmd
,
445 "babel update-interval (20-655340)",
446 "Babel interface commands\n"
447 "Time between scheduled updates\n"
450 VTY_DECLVAR_CONTEXT(interface
, ifp
);
451 babel_interface_nfo
*babel_ifp
;
454 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
456 babel_ifp
= babel_get_if_nfo(ifp
);
457 assert (babel_ifp
!= NULL
);
459 babel_ifp
->update_interval
= interval
;
463 DEFUN (babel_set_rxcost
,
464 babel_set_rxcost_cmd
,
465 "babel rxcost (1-65534)",
466 "Babel interface commands\n"
467 "Rxcost multiplier\n"
470 VTY_DECLVAR_CONTEXT(interface
, ifp
);
471 babel_interface_nfo
*babel_ifp
;
474 rxcost
= strtoul(argv
[2]->arg
, NULL
, 10);
476 babel_ifp
= babel_get_if_nfo(ifp
);
477 assert (babel_ifp
!= NULL
);
479 babel_ifp
->cost
= rxcost
;
483 DEFUN (babel_set_rtt_decay
,
484 babel_set_rtt_decay_cmd
,
485 "babel rtt-decay (1-256)",
486 "Babel interface commands\n"
487 "Decay factor for exponential moving average of RTT samples\n"
490 VTY_DECLVAR_CONTEXT(interface
, ifp
);
491 babel_interface_nfo
*babel_ifp
;
494 decay
= strtoul(argv
[2]->arg
, NULL
, 10);
496 babel_ifp
= babel_get_if_nfo(ifp
);
497 assert (babel_ifp
!= NULL
);
499 babel_ifp
->rtt_decay
= decay
;
503 DEFUN (babel_set_rtt_min
,
504 babel_set_rtt_min_cmd
,
505 "babel rtt-min (1-65535)",
506 "Babel interface commands\n"
507 "Minimum RTT starting for increasing cost\n"
510 VTY_DECLVAR_CONTEXT(interface
, ifp
);
511 babel_interface_nfo
*babel_ifp
;
514 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
516 babel_ifp
= babel_get_if_nfo(ifp
);
517 assert (babel_ifp
!= NULL
);
519 babel_ifp
->rtt_min
= rtt
;
523 DEFUN (babel_set_rtt_max
,
524 babel_set_rtt_max_cmd
,
525 "babel rtt-max (1-65535)",
526 "Babel interface commands\n"
530 VTY_DECLVAR_CONTEXT(interface
, ifp
);
531 babel_interface_nfo
*babel_ifp
;
534 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
536 babel_ifp
= babel_get_if_nfo(ifp
);
537 assert (babel_ifp
!= NULL
);
539 babel_ifp
->rtt_max
= rtt
;
543 DEFUN (babel_set_max_rtt_penalty
,
544 babel_set_max_rtt_penalty_cmd
,
545 "babel max-rtt-penalty (0-65535)",
546 "Babel interface commands\n"
547 "Maximum additional cost due to RTT\n"
550 VTY_DECLVAR_CONTEXT(interface
, ifp
);
551 babel_interface_nfo
*babel_ifp
;
554 penalty
= strtoul(argv
[2]->arg
, NULL
, 10);
556 babel_ifp
= babel_get_if_nfo(ifp
);
557 assert (babel_ifp
!= NULL
);
559 babel_ifp
->max_rtt_penalty
= penalty
;
563 DEFUN (babel_set_enable_timestamps
,
564 babel_set_enable_timestamps_cmd
,
565 "babel enable-timestamps",
566 "Babel interface commands\n"
567 "Enable timestamps\n")
569 VTY_DECLVAR_CONTEXT(interface
, ifp
);
570 babel_interface_nfo
*babel_ifp
;
572 babel_ifp
= babel_get_if_nfo(ifp
);
573 assert (babel_ifp
!= NULL
);
575 babel_ifp
->flags
|= BABEL_IF_TIMESTAMPS
;
579 DEFUN (no_babel_set_enable_timestamps
,
580 no_babel_set_enable_timestamps_cmd
,
581 "no babel enable-timestamps",
583 "Babel interface commands\n"
584 "Disable timestamps\n")
586 VTY_DECLVAR_CONTEXT(interface
, ifp
);
587 babel_interface_nfo
*babel_ifp
;
589 babel_ifp
= babel_get_if_nfo(ifp
);
590 assert (babel_ifp
!= NULL
);
592 babel_ifp
->flags
&= ~BABEL_IF_TIMESTAMPS
;
596 DEFUN (babel_set_channel
,
597 babel_set_channel_cmd
,
598 "babel channel (1-254)",
599 "Babel interface commands\n"
600 "Channel number for diversity routing\n"
603 VTY_DECLVAR_CONTEXT(interface
, ifp
);
604 babel_interface_nfo
*babel_ifp
;
607 channel
= strtoul(argv
[2]->arg
, NULL
, 10);
609 babel_ifp
= babel_get_if_nfo(ifp
);
610 assert (babel_ifp
!= NULL
);
612 babel_ifp
->channel
= channel
;
616 DEFUN (babel_set_channel_interfering
,
617 babel_set_channel_interfering_cmd
,
618 "babel channel interfering",
619 "Babel interface commands\n"
620 "Channel number for diversity routing\n"
621 "Mark channel as interfering\n")
623 VTY_DECLVAR_CONTEXT(interface
, ifp
);
624 babel_interface_nfo
*babel_ifp
;
626 babel_ifp
= babel_get_if_nfo(ifp
);
627 assert (babel_ifp
!= NULL
);
629 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
633 DEFUN (babel_set_channel_noninterfering
,
634 babel_set_channel_noninterfering_cmd
,
635 "babel channel noninterfering",
636 "Babel interface commands\n"
637 "Channel number for diversity routing\n"
638 "Mark channel as noninterfering\n")
640 VTY_DECLVAR_CONTEXT(interface
, ifp
);
641 babel_interface_nfo
*babel_ifp
;
643 babel_ifp
= babel_get_if_nfo(ifp
);
644 assert (babel_ifp
!= NULL
);
646 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
650 /* This should be no more than half the hello interval, so that hellos
651 aren't sent late. The result is in milliseconds. */
653 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
655 unsigned interval
= babel_ifp
->hello_interval
;
657 interval
= MIN(interval
, 100);
659 interval
= MIN(interval
, 4000);
660 return roughly(interval
) / 4;
664 update_jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
666 unsigned interval
= babel_ifp
->hello_interval
;
668 interval
= MIN(interval
, 100);
670 interval
= MIN(interval
, 4000);
671 return roughly(interval
);
674 /* calculate babeld's specific datas of an interface (change when the interface
677 interface_recalculate(struct interface
*ifp
)
679 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
680 unsigned char *tmp
= NULL
;
682 struct ipv6_mreq mreq
;
687 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
688 interface_reset(ifp
);
692 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
694 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
696 /* We need to be able to fit at least two messages into a packet,
697 so MTUs below 116 require lower layer fragmentation. */
698 /* In IPv6, the minimum MTU is 1280, and every host must be able
699 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
701 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
702 mtu
, ifp
->name
, ifp
->ifindex
);
706 /* 4 for Babel header; 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
707 babel_ifp
->bufsize
= mtu
- 4 - 60;
708 tmp
= babel_ifp
->sendbuf
;
709 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
710 if(babel_ifp
->sendbuf
== NULL
) {
711 flog_err(EC_BABEL_MEMORY
, "Couldn't reallocate sendbuf.");
713 babel_ifp
->bufsize
= 0;
718 rc
= resize_receive_buffer(mtu
);
720 zlog_warn("couldn't resize "
721 "receive buffer for interface %s (%d) (%d bytes).\n",
722 ifp
->name
, ifp
->ifindex
, mtu
);
724 memset(&mreq
, 0, sizeof(mreq
));
725 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
726 mreq
.ipv6mr_interface
= ifp
->ifindex
;
728 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
729 (char*)&mreq
, sizeof(mreq
));
731 flog_err_sys(EC_LIB_SOCKET
,
732 "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
733 ifp
->name
, safe_strerror(errno
));
734 /* This is probably due to a missing link-local address,
735 so down this interface, and wait until the main loop
736 tries to up it again. */
737 interface_reset(ifp
);
741 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
742 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
744 send_request(ifp
, NULL
, 0);
746 update_interface_metric(ifp
);
748 debugf(BABEL_DEBUG_COMMON
,
749 "Upped interface %s (%s, cost=%d, channel=%d%s).",
751 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
754 babel_ifp
->ipv4
? ", IPv4" : "");
757 send_update(ifp
, 0, NULL
, 0);
762 /* Reset the interface as it was new: it's not removed from the interface list,
763 and may be considered as a upped interface. */
765 interface_reset(struct interface
*ifp
)
768 struct ipv6_mreq mreq
;
769 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
771 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
774 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
775 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
777 flush_interface_routes(ifp
, 0);
778 babel_ifp
->buffered
= 0;
779 babel_ifp
->bufsize
= 0;
780 free(babel_ifp
->sendbuf
);
781 babel_ifp
->num_buffered_updates
= 0;
782 babel_ifp
->update_bufsize
= 0;
783 if(babel_ifp
->buffered_updates
)
784 free(babel_ifp
->buffered_updates
);
785 babel_ifp
->buffered_updates
= NULL
;
786 babel_ifp
->sendbuf
= NULL
;
788 if(ifp
->ifindex
> 0) {
789 memset(&mreq
, 0, sizeof(mreq
));
790 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
791 mreq
.ipv6mr_interface
= ifp
->ifindex
;
792 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
793 (char*)&mreq
, sizeof(mreq
));
795 flog_err_sys(EC_LIB_SOCKET
,
796 "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
797 ifp
->name
, safe_strerror(errno
));
800 update_interface_metric(ifp
);
802 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
804 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
806 babel_ifp
->ipv4
? ", IPv4" : "");
811 /* Send retraction to all, and reset all interfaces statistics. */
813 babel_interface_close_all(void)
815 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
816 struct interface
*ifp
= NULL
;
818 FOR_ALL_INTERFACES(vrf
, ifp
) {
821 send_wildcard_retraction(ifp
);
822 /* Make sure that we expire quickly from our neighbours'
823 association caches. */
824 send_hello_noupdate(ifp
, 10);
826 usleep(roughly(1000));
829 FOR_ALL_INTERFACES(vrf
, ifp
) {
832 /* Make sure they got it. */
833 send_wildcard_retraction(ifp
);
834 send_hello_noupdate(ifp
, 1);
836 usleep(roughly(10000));
838 interface_reset(ifp
);
842 /* return "true" if address is one of our ipv6 addresses */
844 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
846 struct connected
*connected
;
847 struct listnode
*node
;
852 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
853 if(connected
->address
->family
== AF_INET6
&&
854 memcmp(&connected
->address
->u
.prefix6
, address
, 16) == 0)
862 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
865 babel_interface_nfo
*babel_ifp
;
867 vty_out (vty
, "%s is %s\n", ifp
->name
,
868 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
869 vty_out (vty
, " ifindex %u, MTU %u bytes %s\n",
870 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
874 vty_out (vty
, " Babel protocol is not enabled on this interface\n");
880 " Babel protocol is enabled, but not running on this interface\n");
883 babel_ifp
= babel_get_if_nfo (ifp
);
884 vty_out (vty
, " Babel protocol is running on this interface\n");
885 vty_out (vty
, " Operating mode is \"%s\"\n",
886 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
887 vty_out (vty
, " Split horizon mode is %s\n",
888 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
889 vty_out (vty
, " Hello interval is %u ms\n", babel_ifp
->hello_interval
);
890 vty_out (vty
, " Update interval is %u ms\n", babel_ifp
->update_interval
);
891 vty_out (vty
, " Rxcost multiplier is %u\n", babel_ifp
->cost
);
894 DEFUN (show_babel_interface
,
895 show_babel_interface_cmd
,
896 "show babel interface [IFNAME]",
898 "Babel information\n"
899 "Interface information\n"
902 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
903 struct interface
*ifp
;
907 FOR_ALL_INTERFACES (vrf
, ifp
)
908 show_babel_interface_sub (vty
, ifp
);
911 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
913 vty_out (vty
, "No such interface name\n");
916 show_babel_interface_sub (vty
, ifp
);
921 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
924 "Neighbour %s dev %s reach %04x rxcost %d txcost %d "
925 "rtt %s rttcost %d%s.\n",
926 format_address(neigh
->address
),
929 neighbour_rxcost(neigh
),
931 format_thousands(neigh
->rtt
),
932 neighbour_rttcost(neigh
),
933 if_up(neigh
->ifp
) ? "" : " (down)");
936 DEFUN (show_babel_neighbour
,
937 show_babel_neighbour_cmd
,
938 "show babel neighbor [IFNAME]",
940 "Babel information\n"
944 struct neighbour
*neigh
;
945 struct interface
*ifp
;
948 FOR_ALL_NEIGHBOURS(neigh
) {
949 show_babel_neighbour_sub(vty
, neigh
);
953 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
955 vty_out (vty
, "No such interface name\n");
958 FOR_ALL_NEIGHBOURS(neigh
) {
959 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
960 show_babel_neighbour_sub(vty
, neigh
);
967 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
969 if(prefix
->family
== AF_INET6
) {
970 if(prefix
->prefixlen
!= plen
||
971 memcmp(&prefix
->u
.prefix6
, p
, 16) != 0)
973 } else if(prefix
->family
== AF_INET
) {
974 if(plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96 ||
975 memcmp(&prefix
->u
.prefix4
, p
+ 12, 4) != 0)
985 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
986 struct prefix
*prefix
)
988 const unsigned char *nexthop
=
989 memcmp(route
->nexthop
, route
->neigh
->address
, 16) == 0 ?
990 NULL
: route
->nexthop
;
993 if(prefix
&& !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
996 if(route
->channels
[0] == 0)
1000 snprintf(channels
, 100, " chan (");
1001 j
= strlen(channels
);
1002 for(k
= 0; k
< DIVERSITY_HOPS
; k
++) {
1003 if(route
->channels
[k
] == 0)
1006 channels
[j
++] = ',';
1007 snprintf(channels
+ j
, 100 - j
, "%u", route
->channels
[k
]);
1008 j
= strlen(channels
);
1010 snprintf(channels
+ j
, 100 - j
, ")");
1016 "%s metric %d refmetric %d id %s seqno %d%s age %d "
1017 "via %s neigh %s%s%s%s\n",
1018 format_prefix(route
->src
->prefix
, route
->src
->plen
),
1019 route_metric(route
), route
->refmetric
,
1020 format_eui64(route
->src
->id
),
1023 (int)(babel_now
.tv_sec
- route
->time
),
1024 route
->neigh
->ifp
->name
,
1025 format_address(route
->neigh
->address
),
1026 nexthop
? " nexthop " : "",
1027 nexthop
? format_address(nexthop
) : "",
1028 route
->installed
? " (installed)" : route_feasible(route
) ? " (feasible)" : "");
1032 show_babel_xroutes_sub (struct xroute
*xroute
, struct vty
*vty
,
1033 struct prefix
*prefix
)
1035 if(prefix
&& !babel_prefix_eq(prefix
, xroute
->prefix
, xroute
->plen
))
1038 vty_out (vty
, "%s metric %d (exported)\n",
1039 format_prefix(xroute
->prefix
, xroute
->plen
),
1043 DEFUN (show_babel_route
,
1044 show_babel_route_cmd
,
1047 "Babel information\n"
1048 "Babel internal routing table\n")
1050 struct route_stream
*routes
= NULL
;
1051 struct xroute_stream
*xroutes
= NULL
;
1052 routes
= route_stream(0);
1055 struct babel_route
*route
= route_stream_next(routes
);
1058 show_babel_routes_sub(route
, vty
, NULL
);
1060 route_stream_done(routes
);
1062 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1064 xroutes
= xroute_stream();
1067 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1070 show_babel_xroutes_sub(xroute
, vty
, NULL
);
1072 xroute_stream_done(xroutes
);
1074 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1079 DEFUN (show_babel_route_prefix
,
1080 show_babel_route_prefix_cmd
,
1081 "show babel route <A.B.C.D/M|X:X::X:X/M>",
1083 "Babel information\n"
1084 "Babel internal routing table\n"
1085 "IPv4 prefix <network>/<length>\n"
1086 "IPv6 prefix <network>/<length>\n")
1088 struct route_stream
*routes
= NULL
;
1089 struct xroute_stream
*xroutes
= NULL
;
1090 struct prefix prefix
;
1093 ret
= str2prefix(argv
[3]->arg
, &prefix
);
1095 vty_out (vty
, "%% Malformed address\n");
1099 routes
= route_stream(0);
1102 struct babel_route
*route
= route_stream_next(routes
);
1105 show_babel_routes_sub(route
, vty
, &prefix
);
1107 route_stream_done(routes
);
1109 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1111 xroutes
= xroute_stream();
1114 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1117 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1119 xroute_stream_done(xroutes
);
1121 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1127 DEFUN (show_babel_route_addr
,
1128 show_babel_route_addr_cmd
,
1129 "show babel route A.B.C.D",
1131 "Babel information\n"
1132 "Babel internal routing table\n"
1133 "IPv4 address <network>/<length>\n")
1135 struct in_addr addr
;
1136 char buf
[INET_ADDRSTRLEN
+ 8];
1137 struct route_stream
*routes
= NULL
;
1138 struct xroute_stream
*xroutes
= NULL
;
1139 struct prefix prefix
;
1142 ret
= inet_aton (argv
[3]->arg
, &addr
);
1144 vty_out (vty
, "%% Malformed address\n");
1148 /* Quagga has no convenient prefix constructors. */
1149 snprintf(buf
, sizeof(buf
), "%s/%d", inet_ntoa(addr
), 32);
1151 ret
= str2prefix(buf
, &prefix
);
1153 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1157 routes
= route_stream(0);
1160 struct babel_route
*route
= route_stream_next(routes
);
1163 show_babel_routes_sub(route
, vty
, &prefix
);
1165 route_stream_done(routes
);
1167 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1169 xroutes
= xroute_stream();
1172 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1175 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1177 xroute_stream_done(xroutes
);
1179 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1184 DEFUN (show_babel_route_addr6
,
1185 show_babel_route_addr6_cmd
,
1186 "show babel route X:X::X:X",
1188 "Babel information\n"
1189 "Babel internal routing table\n"
1190 "IPv6 address <network>/<length>\n")
1192 struct in6_addr addr
;
1193 char buf1
[INET6_ADDRSTRLEN
];
1194 char buf
[INET6_ADDRSTRLEN
+ 8];
1195 struct route_stream
*routes
= NULL
;
1196 struct xroute_stream
*xroutes
= NULL
;
1197 struct prefix prefix
;
1200 ret
= inet_pton (AF_INET6
, argv
[3]->arg
, &addr
);
1202 vty_out (vty
, "%% Malformed address\n");
1206 /* Quagga has no convenient prefix constructors. */
1207 snprintf(buf
, sizeof(buf
), "%s/%d",
1208 inet_ntop(AF_INET6
, &addr
, buf1
, sizeof(buf1
)), 128);
1210 ret
= str2prefix(buf
, &prefix
);
1212 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1216 routes
= route_stream(0);
1219 struct babel_route
*route
= route_stream_next(routes
);
1222 show_babel_routes_sub(route
, vty
, &prefix
);
1224 route_stream_done(routes
);
1226 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1228 xroutes
= xroute_stream();
1231 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1234 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1236 xroute_stream_done(xroutes
);
1238 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1243 DEFUN (show_babel_parameters
,
1244 show_babel_parameters_cmd
,
1245 "show babel parameters",
1247 "Babel information\n"
1248 "Configuration information\n")
1250 struct babel
*babel_ctx
;
1252 vty_out (vty
, " -- Babel running configuration --\n");
1253 show_babel_main_configuration(vty
);
1255 babel_ctx
= babel_lookup();
1257 vty_out (vty
, " -- distribution lists --\n");
1258 config_show_distribute(vty
, babel_ctx
->distribute_ctx
);
1266 /* initialize interface list */
1267 hook_register_prio(if_add
, 0, babel_if_new_hook
);
1268 hook_register_prio(if_del
, 0, babel_if_delete_hook
);
1270 babel_enable_if
= vector_init (1);
1272 /* install interface node and commands */
1273 install_node (&babel_interface_node
, interface_config_write
);
1276 install_element(BABEL_NODE
, &babel_network_cmd
);
1277 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1278 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1279 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1280 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1281 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1282 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1283 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1284 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1285 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1286 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1287 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1288 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1289 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1290 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1291 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1292 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1293 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1295 /* "show babel ..." commands */
1296 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1297 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1298 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1299 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1300 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1301 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1302 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1305 /* hooks: functions called respectively when struct interface is
1306 created or deleted. */
1308 babel_if_new_hook (struct interface
*ifp
)
1310 ifp
->info
= babel_interface_allocate();
1315 babel_if_delete_hook (struct interface
*ifp
)
1317 babel_interface_free(ifp
->info
);
1322 /* Output an "interface" section for each of the known interfaces with
1323 babeld-specific statement lines where appropriate. */
1325 interface_config_write (struct vty
*vty
)
1327 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1328 struct interface
*ifp
;
1331 FOR_ALL_INTERFACES (vrf
, ifp
) {
1332 vty_frame (vty
, "interface %s\n",ifp
->name
);
1334 vty_out (vty
, " description %s\n",ifp
->desc
);
1335 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1336 /* wireless is the default*/
1337 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1339 vty_out (vty
, " babel wired\n");
1342 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1344 vty_out (vty
, " babel hello-interval %u\n",
1345 babel_ifp
->hello_interval
);
1348 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1350 vty_out (vty
, " babel update-interval %u\n",
1351 babel_ifp
->update_interval
);
1354 /* Some parameters have different defaults for wired/wireless. */
1355 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
)) {
1356 if (!CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1357 vty_out (vty
, " no babel split-horizon\n");
1360 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRED
) {
1361 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1364 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_INTERFERING
) {
1365 vty_out (vty
, " babel channel interfering\n");
1367 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_NONINTERFERING
) {
1368 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1372 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1373 vty_out (vty
, " babel split-horizon\n");
1376 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRELESS
) {
1377 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1380 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_NONINTERFERING
) {
1381 vty_out (vty
, " babel channel noninterfering\n");
1383 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_INTERFERING
) {
1384 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1388 vty_endframe (vty
, "!\n");
1394 /* Output a "network" statement line for each of the enabled interfaces. */
1396 babel_enable_if_config_write (struct vty
* vty
)
1398 unsigned int i
, lines
= 0;
1401 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
1402 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
1404 vty_out (vty
, " network %s\n", str
);
1410 /* functions to allocate or free memory for a babel_interface_nfo, filling
1412 static babel_interface_nfo
*
1413 babel_interface_allocate (void)
1415 babel_interface_nfo
*babel_ifp
;
1416 babel_ifp
= XCALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1417 /* All flags are unset */
1418 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1419 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1420 babel_ifp
->hello_seqno
= (random() & 0xFFFF);
1421 babel_ifp
->rtt_min
= 10000;
1422 babel_ifp
->rtt_max
= 120000;
1423 babel_ifp
->max_rtt_penalty
= 150;
1424 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1425 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1426 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1427 babel_set_wired_internal(babel_ifp
, 0);
1433 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1435 XFREE(MTYPE_BABEL_IF
, babel_ifp
);