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
);
107 int babel_ifp_create (struct interface
*ifp
)
109 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
111 interface_recalculate(ifp
);
117 babel_interface_delete (ZAPI_CALLBACK_ARGS
)
119 struct interface
*ifp
;
122 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
125 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
131 interface_reset(ifp
);
133 /* To support pseudo interface do not free interface structure. */
134 /* if_delete(ifp); */
135 if_set_index(ifp
, IFINDEX_INTERNAL
);
141 babel_interface_address_add (ZAPI_CALLBACK_ARGS
)
143 babel_interface_nfo
*babel_ifp
;
144 struct connected
*ifc
;
145 struct prefix
*prefix
;
147 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
149 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
150 zclient
->ibuf
, vrf_id
);
155 prefix
= ifc
->address
;
157 if (prefix
->family
== AF_INET
) {
158 flush_interface_routes(ifc
->ifp
, 0);
159 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
160 if (babel_ifp
->ipv4
== NULL
) {
161 babel_ifp
->ipv4
= malloc(4);
162 if (babel_ifp
->ipv4
== NULL
) {
163 flog_err(EC_BABEL_MEMORY
, "not enough memory");
165 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
170 send_request(ifc
->ifp
, NULL
, 0);
171 send_update(ifc
->ifp
, 0, NULL
, 0);
177 babel_interface_address_delete (ZAPI_CALLBACK_ARGS
)
179 babel_interface_nfo
*babel_ifp
;
180 struct connected
*ifc
;
181 struct prefix
*prefix
;
183 debugf(BABEL_DEBUG_IF
, "receive a 'interface address delete'");
185 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE
,
186 zclient
->ibuf
, vrf_id
);
191 prefix
= ifc
->address
;
193 if (prefix
->family
== AF_INET
) {
194 flush_interface_routes(ifc
->ifp
, 0);
195 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
196 if (babel_ifp
->ipv4
!= NULL
197 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4) == 0) {
198 free(babel_ifp
->ipv4
);
199 babel_ifp
->ipv4
= NULL
;
203 send_request(ifc
->ifp
, NULL
, 0);
204 send_update(ifc
->ifp
, 0, NULL
, 0);
209 /* Lookup function. */
211 babel_enable_if_lookup (const char *ifname
)
216 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
217 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
218 if (strcmp (str
, ifname
) == 0)
223 /* Add interface to babel_enable_if. */
225 babel_enable_if_add (const char *ifname
)
228 struct interface
*ifp
= NULL
;
230 ret
= babel_enable_if_lookup (ifname
);
234 vector_set (babel_enable_if
, strdup (ifname
));
236 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
238 interface_recalculate(ifp
);
243 /* Delete interface from babel_enable_if. */
245 babel_enable_if_delete (const char *ifname
)
247 int babel_enable_if_index
;
249 struct interface
*ifp
= NULL
;
251 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
252 if (babel_enable_if_index
< 0)
255 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
257 vector_unset (babel_enable_if
, babel_enable_if_index
);
259 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
261 interface_reset(ifp
);
266 /* [Babel Command] Babel enable on specified interface or matched network. */
267 DEFUN (babel_network
,
269 "network IF_OR_ADDR",
270 "Enable Babel protocol on specified interface or network.\n"
271 "Interface or address\n")
276 ret
= str2prefix (argv
[1]->arg
, &p
);
278 /* Given string is: */
279 if (ret
) /* an IPv4 or v6 network */
280 return CMD_ERR_NO_MATCH
; /* not implemented yet */
281 else /* an interface name */
282 ret
= babel_enable_if_add (argv
[1]->arg
);
285 vty_out (vty
, "There is same network configuration %s\n",
293 /* [Babel Command] Babel enable on specified interface or matched network. */
294 DEFUN (no_babel_network
,
295 no_babel_network_cmd
,
296 "no network IF_OR_ADDR",
298 "Disable Babel protocol on specified interface or network.\n"
299 "Interface or address\n")
304 ret
= str2prefix (argv
[2]->arg
, &p
);
306 /* Given string is: */
307 if (ret
) /* an IPv4 or v6 network */
308 return CMD_ERR_NO_MATCH
; /* not implemented yet */
309 else /* an interface name */
310 ret
= babel_enable_if_delete (argv
[2]->arg
);
313 vty_out (vty
, "can't find network %s\n",argv
[2]->arg
);
314 return CMD_WARNING_CONFIG_FAILED
;
320 /* There are a number of interface parameters that must be changed when
321 an interface becomes wired/wireless. In Quagga, they cannot be
322 configured separately. */
325 babel_set_wired_internal(babel_interface_nfo
*babel_ifp
, int wired
)
328 babel_ifp
->flags
|= BABEL_IF_WIRED
;
329 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
330 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRED
;
331 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
332 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
334 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
335 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
336 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRELESS
;
337 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
338 babel_ifp
->flags
|= BABEL_IF_LQ
;
343 /* [Interface Command] Tell the interface is wire. */
344 DEFUN (babel_set_wired
,
347 "Babel interface commands\n"
348 "Enable wired optimizations\n")
350 VTY_DECLVAR_CONTEXT(interface
, ifp
);
351 babel_interface_nfo
*babel_ifp
;
353 babel_ifp
= babel_get_if_nfo(ifp
);
355 assert (babel_ifp
!= NULL
);
356 babel_set_wired_internal(babel_ifp
, 1);
360 /* [Interface Command] Tell the interface is wireless (default). */
361 DEFUN (babel_set_wireless
,
362 babel_set_wireless_cmd
,
364 "Babel interface commands\n"
365 "Disable wired optimizations (assume wireless)\n")
367 VTY_DECLVAR_CONTEXT(interface
, ifp
);
368 babel_interface_nfo
*babel_ifp
;
370 babel_ifp
= babel_get_if_nfo(ifp
);
372 assert (babel_ifp
!= NULL
);
373 babel_set_wired_internal(babel_ifp
, 0);
377 /* [Interface Command] Enable split horizon. */
378 DEFUN (babel_split_horizon
,
379 babel_split_horizon_cmd
,
380 "babel split-horizon",
381 "Babel interface commands\n"
382 "Enable split horizon processing\n")
384 VTY_DECLVAR_CONTEXT(interface
, ifp
);
385 babel_interface_nfo
*babel_ifp
;
387 babel_ifp
= babel_get_if_nfo(ifp
);
389 assert (babel_ifp
!= NULL
);
390 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
394 /* [Interface Command] Disable split horizon (default). */
395 DEFUN (no_babel_split_horizon
,
396 no_babel_split_horizon_cmd
,
397 "no babel split-horizon",
399 "Babel interface commands\n"
400 "Disable split horizon processing\n")
402 VTY_DECLVAR_CONTEXT(interface
, ifp
);
403 babel_interface_nfo
*babel_ifp
;
405 babel_ifp
= babel_get_if_nfo(ifp
);
407 assert (babel_ifp
!= NULL
);
408 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
412 /* [Interface Command]. */
413 DEFUN (babel_set_hello_interval
,
414 babel_set_hello_interval_cmd
,
415 "babel hello-interval (20-655340)",
416 "Babel interface commands\n"
417 "Time between scheduled hellos\n"
420 VTY_DECLVAR_CONTEXT(interface
, ifp
);
421 babel_interface_nfo
*babel_ifp
;
424 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
426 babel_ifp
= babel_get_if_nfo(ifp
);
427 assert (babel_ifp
!= NULL
);
429 babel_ifp
->hello_interval
= interval
;
433 /* [Interface Command]. */
434 DEFUN (babel_set_update_interval
,
435 babel_set_update_interval_cmd
,
436 "babel update-interval (20-655340)",
437 "Babel interface commands\n"
438 "Time between scheduled updates\n"
441 VTY_DECLVAR_CONTEXT(interface
, ifp
);
442 babel_interface_nfo
*babel_ifp
;
445 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
447 babel_ifp
= babel_get_if_nfo(ifp
);
448 assert (babel_ifp
!= NULL
);
450 babel_ifp
->update_interval
= interval
;
454 DEFUN (babel_set_rxcost
,
455 babel_set_rxcost_cmd
,
456 "babel rxcost (1-65534)",
457 "Babel interface commands\n"
458 "Rxcost multiplier\n"
461 VTY_DECLVAR_CONTEXT(interface
, ifp
);
462 babel_interface_nfo
*babel_ifp
;
465 rxcost
= strtoul(argv
[2]->arg
, NULL
, 10);
467 babel_ifp
= babel_get_if_nfo(ifp
);
468 assert (babel_ifp
!= NULL
);
470 babel_ifp
->cost
= rxcost
;
474 DEFUN (babel_set_rtt_decay
,
475 babel_set_rtt_decay_cmd
,
476 "babel rtt-decay (1-256)",
477 "Babel interface commands\n"
478 "Decay factor for exponential moving average of RTT samples\n"
481 VTY_DECLVAR_CONTEXT(interface
, ifp
);
482 babel_interface_nfo
*babel_ifp
;
485 decay
= strtoul(argv
[2]->arg
, NULL
, 10);
487 babel_ifp
= babel_get_if_nfo(ifp
);
488 assert (babel_ifp
!= NULL
);
490 babel_ifp
->rtt_decay
= decay
;
494 DEFUN (babel_set_rtt_min
,
495 babel_set_rtt_min_cmd
,
496 "babel rtt-min (1-65535)",
497 "Babel interface commands\n"
498 "Minimum RTT starting for increasing cost\n"
501 VTY_DECLVAR_CONTEXT(interface
, ifp
);
502 babel_interface_nfo
*babel_ifp
;
505 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
507 babel_ifp
= babel_get_if_nfo(ifp
);
508 assert (babel_ifp
!= NULL
);
510 babel_ifp
->rtt_min
= rtt
;
514 DEFUN (babel_set_rtt_max
,
515 babel_set_rtt_max_cmd
,
516 "babel rtt-max (1-65535)",
517 "Babel interface commands\n"
521 VTY_DECLVAR_CONTEXT(interface
, ifp
);
522 babel_interface_nfo
*babel_ifp
;
525 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
527 babel_ifp
= babel_get_if_nfo(ifp
);
528 assert (babel_ifp
!= NULL
);
530 babel_ifp
->rtt_max
= rtt
;
534 DEFUN (babel_set_max_rtt_penalty
,
535 babel_set_max_rtt_penalty_cmd
,
536 "babel max-rtt-penalty (0-65535)",
537 "Babel interface commands\n"
538 "Maximum additional cost due to RTT\n"
541 VTY_DECLVAR_CONTEXT(interface
, ifp
);
542 babel_interface_nfo
*babel_ifp
;
545 penalty
= strtoul(argv
[2]->arg
, NULL
, 10);
547 babel_ifp
= babel_get_if_nfo(ifp
);
548 assert (babel_ifp
!= NULL
);
550 babel_ifp
->max_rtt_penalty
= penalty
;
554 DEFUN (babel_set_enable_timestamps
,
555 babel_set_enable_timestamps_cmd
,
556 "babel enable-timestamps",
557 "Babel interface commands\n"
558 "Enable timestamps\n")
560 VTY_DECLVAR_CONTEXT(interface
, ifp
);
561 babel_interface_nfo
*babel_ifp
;
563 babel_ifp
= babel_get_if_nfo(ifp
);
564 assert (babel_ifp
!= NULL
);
566 babel_ifp
->flags
|= BABEL_IF_TIMESTAMPS
;
570 DEFUN (no_babel_set_enable_timestamps
,
571 no_babel_set_enable_timestamps_cmd
,
572 "no babel enable-timestamps",
574 "Babel interface commands\n"
575 "Disable timestamps\n")
577 VTY_DECLVAR_CONTEXT(interface
, ifp
);
578 babel_interface_nfo
*babel_ifp
;
580 babel_ifp
= babel_get_if_nfo(ifp
);
581 assert (babel_ifp
!= NULL
);
583 babel_ifp
->flags
&= ~BABEL_IF_TIMESTAMPS
;
587 DEFUN (babel_set_channel
,
588 babel_set_channel_cmd
,
589 "babel channel (1-254)",
590 "Babel interface commands\n"
591 "Channel number for diversity routing\n"
594 VTY_DECLVAR_CONTEXT(interface
, ifp
);
595 babel_interface_nfo
*babel_ifp
;
598 channel
= strtoul(argv
[2]->arg
, NULL
, 10);
600 babel_ifp
= babel_get_if_nfo(ifp
);
601 assert (babel_ifp
!= NULL
);
603 babel_ifp
->channel
= channel
;
607 DEFUN (babel_set_channel_interfering
,
608 babel_set_channel_interfering_cmd
,
609 "babel channel interfering",
610 "Babel interface commands\n"
611 "Channel number for diversity routing\n"
612 "Mark channel as interfering\n")
614 VTY_DECLVAR_CONTEXT(interface
, ifp
);
615 babel_interface_nfo
*babel_ifp
;
617 babel_ifp
= babel_get_if_nfo(ifp
);
618 assert (babel_ifp
!= NULL
);
620 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
624 DEFUN (babel_set_channel_noninterfering
,
625 babel_set_channel_noninterfering_cmd
,
626 "babel channel noninterfering",
627 "Babel interface commands\n"
628 "Channel number for diversity routing\n"
629 "Mark channel as noninterfering\n")
631 VTY_DECLVAR_CONTEXT(interface
, ifp
);
632 babel_interface_nfo
*babel_ifp
;
634 babel_ifp
= babel_get_if_nfo(ifp
);
635 assert (babel_ifp
!= NULL
);
637 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
641 /* This should be no more than half the hello interval, so that hellos
642 aren't sent late. The result is in milliseconds. */
644 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
646 unsigned interval
= babel_ifp
->hello_interval
;
648 interval
= MIN(interval
, 100);
650 interval
= MIN(interval
, 4000);
651 return roughly(interval
) / 4;
655 update_jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
657 unsigned interval
= babel_ifp
->hello_interval
;
659 interval
= MIN(interval
, 100);
661 interval
= MIN(interval
, 4000);
662 return roughly(interval
);
665 /* calculate babeld's specific datas of an interface (change when the interface
668 interface_recalculate(struct interface
*ifp
)
670 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
671 unsigned char *tmp
= NULL
;
673 struct ipv6_mreq mreq
;
678 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
679 interface_reset(ifp
);
683 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
685 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
687 /* We need to be able to fit at least two messages into a packet,
688 so MTUs below 116 require lower layer fragmentation. */
689 /* In IPv6, the minimum MTU is 1280, and every host must be able
690 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
692 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
693 mtu
, ifp
->name
, ifp
->ifindex
);
697 /* 4 for Babel header; 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
698 babel_ifp
->bufsize
= mtu
- 4 - 60;
699 tmp
= babel_ifp
->sendbuf
;
700 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
701 if(babel_ifp
->sendbuf
== NULL
) {
702 flog_err(EC_BABEL_MEMORY
, "Couldn't reallocate sendbuf.");
704 babel_ifp
->bufsize
= 0;
709 rc
= resize_receive_buffer(mtu
);
711 zlog_warn("couldn't resize "
712 "receive buffer for interface %s (%d) (%d bytes).\n",
713 ifp
->name
, ifp
->ifindex
, mtu
);
715 memset(&mreq
, 0, sizeof(mreq
));
716 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
717 mreq
.ipv6mr_interface
= ifp
->ifindex
;
719 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
720 (char*)&mreq
, sizeof(mreq
));
722 flog_err_sys(EC_LIB_SOCKET
,
723 "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
724 ifp
->name
, safe_strerror(errno
));
725 /* This is probably due to a missing link-local address,
726 so down this interface, and wait until the main loop
727 tries to up it again. */
728 interface_reset(ifp
);
732 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
733 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
735 send_request(ifp
, NULL
, 0);
737 update_interface_metric(ifp
);
739 debugf(BABEL_DEBUG_COMMON
,
740 "Upped interface %s (%s, cost=%d, channel=%d%s).",
742 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
745 babel_ifp
->ipv4
? ", IPv4" : "");
748 send_update(ifp
, 0, NULL
, 0);
753 /* Reset the interface as it was new: it's not removed from the interface list,
754 and may be considered as a upped interface. */
756 interface_reset(struct interface
*ifp
)
759 struct ipv6_mreq mreq
;
760 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
762 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
765 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
766 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
768 flush_interface_routes(ifp
, 0);
769 babel_ifp
->buffered
= 0;
770 babel_ifp
->bufsize
= 0;
771 free(babel_ifp
->sendbuf
);
772 babel_ifp
->num_buffered_updates
= 0;
773 babel_ifp
->update_bufsize
= 0;
774 if(babel_ifp
->buffered_updates
)
775 free(babel_ifp
->buffered_updates
);
776 babel_ifp
->buffered_updates
= NULL
;
777 babel_ifp
->sendbuf
= NULL
;
779 if(ifp
->ifindex
> 0) {
780 memset(&mreq
, 0, sizeof(mreq
));
781 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
782 mreq
.ipv6mr_interface
= ifp
->ifindex
;
783 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
784 (char*)&mreq
, sizeof(mreq
));
786 flog_err_sys(EC_LIB_SOCKET
,
787 "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
788 ifp
->name
, safe_strerror(errno
));
791 update_interface_metric(ifp
);
793 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
795 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
797 babel_ifp
->ipv4
? ", IPv4" : "");
802 /* Send retraction to all, and reset all interfaces statistics. */
804 babel_interface_close_all(void)
806 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
807 struct interface
*ifp
= NULL
;
809 FOR_ALL_INTERFACES(vrf
, ifp
) {
812 send_wildcard_retraction(ifp
);
813 /* Make sure that we expire quickly from our neighbours'
814 association caches. */
815 send_hello_noupdate(ifp
, 10);
817 usleep(roughly(1000));
820 FOR_ALL_INTERFACES(vrf
, ifp
) {
823 /* Make sure they got it. */
824 send_wildcard_retraction(ifp
);
825 send_hello_noupdate(ifp
, 1);
827 usleep(roughly(10000));
829 interface_reset(ifp
);
833 /* return "true" if address is one of our ipv6 addresses */
835 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
837 struct connected
*connected
;
838 struct listnode
*node
;
843 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
844 if(connected
->address
->family
== AF_INET6
&&
845 memcmp(&connected
->address
->u
.prefix6
, address
, 16) == 0)
853 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
856 babel_interface_nfo
*babel_ifp
;
858 vty_out (vty
, "%s is %s\n", ifp
->name
,
859 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
860 vty_out (vty
, " ifindex %u, MTU %u bytes %s\n",
861 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
865 vty_out (vty
, " Babel protocol is not enabled on this interface\n");
871 " Babel protocol is enabled, but not running on this interface\n");
874 babel_ifp
= babel_get_if_nfo (ifp
);
875 vty_out (vty
, " Babel protocol is running on this interface\n");
876 vty_out (vty
, " Operating mode is \"%s\"\n",
877 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
878 vty_out (vty
, " Split horizon mode is %s\n",
879 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
880 vty_out (vty
, " Hello interval is %u ms\n", babel_ifp
->hello_interval
);
881 vty_out (vty
, " Update interval is %u ms\n", babel_ifp
->update_interval
);
882 vty_out (vty
, " Rxcost multiplier is %u\n", babel_ifp
->cost
);
885 DEFUN (show_babel_interface
,
886 show_babel_interface_cmd
,
887 "show babel interface [IFNAME]",
889 "Babel information\n"
890 "Interface information\n"
893 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
894 struct interface
*ifp
;
898 FOR_ALL_INTERFACES (vrf
, ifp
)
899 show_babel_interface_sub (vty
, ifp
);
902 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
904 vty_out (vty
, "No such interface name\n");
907 show_babel_interface_sub (vty
, ifp
);
912 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
915 "Neighbour %s dev %s reach %04x rxcost %d txcost %d "
916 "rtt %s rttcost %d%s.\n",
917 format_address(neigh
->address
),
920 neighbour_rxcost(neigh
),
922 format_thousands(neigh
->rtt
),
923 neighbour_rttcost(neigh
),
924 if_up(neigh
->ifp
) ? "" : " (down)");
927 DEFUN (show_babel_neighbour
,
928 show_babel_neighbour_cmd
,
929 "show babel neighbor [IFNAME]",
931 "Babel information\n"
935 struct neighbour
*neigh
;
936 struct interface
*ifp
;
939 FOR_ALL_NEIGHBOURS(neigh
) {
940 show_babel_neighbour_sub(vty
, neigh
);
944 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
946 vty_out (vty
, "No such interface name\n");
949 FOR_ALL_NEIGHBOURS(neigh
) {
950 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
951 show_babel_neighbour_sub(vty
, neigh
);
958 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
960 if(prefix
->family
== AF_INET6
) {
961 if(prefix
->prefixlen
!= plen
||
962 memcmp(&prefix
->u
.prefix6
, p
, 16) != 0)
964 } else if(prefix
->family
== AF_INET
) {
965 if(plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96 ||
966 memcmp(&prefix
->u
.prefix4
, p
+ 12, 4) != 0)
976 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
977 struct prefix
*prefix
)
979 const unsigned char *nexthop
=
980 memcmp(route
->nexthop
, route
->neigh
->address
, 16) == 0 ?
981 NULL
: route
->nexthop
;
984 if(prefix
&& !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
987 if(route
->channels
[0] == 0)
991 snprintf(channels
, 100, " chan (");
992 j
= strlen(channels
);
993 for(k
= 0; k
< DIVERSITY_HOPS
; k
++) {
994 if(route
->channels
[k
] == 0)
998 snprintf(channels
+ j
, 100 - j
, "%u", route
->channels
[k
]);
999 j
= strlen(channels
);
1001 snprintf(channels
+ j
, 100 - j
, ")");
1007 "%s metric %d refmetric %d id %s seqno %d%s age %d "
1008 "via %s neigh %s%s%s%s\n",
1009 format_prefix(route
->src
->prefix
, route
->src
->plen
),
1010 route_metric(route
), route
->refmetric
,
1011 format_eui64(route
->src
->id
),
1014 (int)(babel_now
.tv_sec
- route
->time
),
1015 route
->neigh
->ifp
->name
,
1016 format_address(route
->neigh
->address
),
1017 nexthop
? " nexthop " : "",
1018 nexthop
? format_address(nexthop
) : "",
1019 route
->installed
? " (installed)" : route_feasible(route
) ? " (feasible)" : "");
1023 show_babel_xroutes_sub (struct xroute
*xroute
, struct vty
*vty
,
1024 struct prefix
*prefix
)
1026 if(prefix
&& !babel_prefix_eq(prefix
, xroute
->prefix
, xroute
->plen
))
1029 vty_out (vty
, "%s metric %d (exported)\n",
1030 format_prefix(xroute
->prefix
, xroute
->plen
),
1034 DEFUN (show_babel_route
,
1035 show_babel_route_cmd
,
1038 "Babel information\n"
1039 "Babel internal routing table\n")
1041 struct route_stream
*routes
= NULL
;
1042 struct xroute_stream
*xroutes
= NULL
;
1043 routes
= route_stream(0);
1046 struct babel_route
*route
= route_stream_next(routes
);
1049 show_babel_routes_sub(route
, vty
, NULL
);
1051 route_stream_done(routes
);
1053 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1055 xroutes
= xroute_stream();
1058 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1061 show_babel_xroutes_sub(xroute
, vty
, NULL
);
1063 xroute_stream_done(xroutes
);
1065 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1070 DEFUN (show_babel_route_prefix
,
1071 show_babel_route_prefix_cmd
,
1072 "show babel route <A.B.C.D/M|X:X::X:X/M>",
1074 "Babel information\n"
1075 "Babel internal routing table\n"
1076 "IPv4 prefix <network>/<length>\n"
1077 "IPv6 prefix <network>/<length>\n")
1079 struct route_stream
*routes
= NULL
;
1080 struct xroute_stream
*xroutes
= NULL
;
1081 struct prefix prefix
;
1084 ret
= str2prefix(argv
[3]->arg
, &prefix
);
1086 vty_out (vty
, "%% Malformed address\n");
1090 routes
= route_stream(0);
1093 struct babel_route
*route
= route_stream_next(routes
);
1096 show_babel_routes_sub(route
, vty
, &prefix
);
1098 route_stream_done(routes
);
1100 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1102 xroutes
= xroute_stream();
1105 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1108 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1110 xroute_stream_done(xroutes
);
1112 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1118 DEFUN (show_babel_route_addr
,
1119 show_babel_route_addr_cmd
,
1120 "show babel route A.B.C.D",
1122 "Babel information\n"
1123 "Babel internal routing table\n"
1124 "IPv4 address <network>/<length>\n")
1126 struct in_addr addr
;
1127 char buf
[INET_ADDRSTRLEN
+ 8];
1128 struct route_stream
*routes
= NULL
;
1129 struct xroute_stream
*xroutes
= NULL
;
1130 struct prefix prefix
;
1133 ret
= inet_aton (argv
[3]->arg
, &addr
);
1135 vty_out (vty
, "%% Malformed address\n");
1139 /* Quagga has no convenient prefix constructors. */
1140 snprintf(buf
, sizeof(buf
), "%s/%d", inet_ntoa(addr
), 32);
1142 ret
= str2prefix(buf
, &prefix
);
1144 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1148 routes
= route_stream(0);
1151 struct babel_route
*route
= route_stream_next(routes
);
1154 show_babel_routes_sub(route
, vty
, &prefix
);
1156 route_stream_done(routes
);
1158 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1160 xroutes
= xroute_stream();
1163 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1166 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1168 xroute_stream_done(xroutes
);
1170 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1175 DEFUN (show_babel_route_addr6
,
1176 show_babel_route_addr6_cmd
,
1177 "show babel route X:X::X:X",
1179 "Babel information\n"
1180 "Babel internal routing table\n"
1181 "IPv6 address <network>/<length>\n")
1183 struct in6_addr addr
;
1184 char buf1
[INET6_ADDRSTRLEN
];
1185 char buf
[INET6_ADDRSTRLEN
+ 8];
1186 struct route_stream
*routes
= NULL
;
1187 struct xroute_stream
*xroutes
= NULL
;
1188 struct prefix prefix
;
1191 ret
= inet_pton (AF_INET6
, argv
[3]->arg
, &addr
);
1193 vty_out (vty
, "%% Malformed address\n");
1197 /* Quagga has no convenient prefix constructors. */
1198 snprintf(buf
, sizeof(buf
), "%s/%d",
1199 inet_ntop(AF_INET6
, &addr
, buf1
, sizeof(buf1
)), 128);
1201 ret
= str2prefix(buf
, &prefix
);
1203 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1207 routes
= route_stream(0);
1210 struct babel_route
*route
= route_stream_next(routes
);
1213 show_babel_routes_sub(route
, vty
, &prefix
);
1215 route_stream_done(routes
);
1217 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1219 xroutes
= xroute_stream();
1222 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1225 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1227 xroute_stream_done(xroutes
);
1229 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1234 DEFUN (show_babel_parameters
,
1235 show_babel_parameters_cmd
,
1236 "show babel parameters",
1238 "Babel information\n"
1239 "Configuration information\n")
1241 struct babel
*babel_ctx
;
1243 vty_out (vty
, " -- Babel running configuration --\n");
1244 show_babel_main_configuration(vty
);
1246 babel_ctx
= babel_lookup();
1248 vty_out (vty
, " -- distribution lists --\n");
1249 config_show_distribute(vty
, babel_ctx
->distribute_ctx
);
1254 int babel_ifp_up(struct interface
*ifp
)
1259 int babel_ifp_down(struct interface
*ifp
)
1264 int babel_ifp_destroy(struct interface
*ifp
)
1272 /* initialize interface list */
1273 hook_register_prio(if_add
, 0, babel_if_new_hook
);
1274 hook_register_prio(if_del
, 0, babel_if_delete_hook
);
1276 babel_enable_if
= vector_init (1);
1278 /* install interface node and commands */
1279 install_node (&babel_interface_node
, interface_config_write
);
1282 install_element(BABEL_NODE
, &babel_network_cmd
);
1283 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1284 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1285 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1286 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1287 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1288 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1289 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1290 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1291 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1292 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1293 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1294 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1295 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1296 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1297 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1298 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1299 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1301 /* "show babel ..." commands */
1302 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1303 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1304 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1305 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1306 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1307 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1308 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1311 /* hooks: functions called respectively when struct interface is
1312 created or deleted. */
1314 babel_if_new_hook (struct interface
*ifp
)
1316 ifp
->info
= babel_interface_allocate();
1321 babel_if_delete_hook (struct interface
*ifp
)
1323 babel_interface_free(ifp
->info
);
1328 /* Output an "interface" section for each of the known interfaces with
1329 babeld-specific statement lines where appropriate. */
1331 interface_config_write (struct vty
*vty
)
1333 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1334 struct interface
*ifp
;
1337 FOR_ALL_INTERFACES (vrf
, ifp
) {
1338 vty_frame (vty
, "interface %s\n",ifp
->name
);
1340 vty_out (vty
, " description %s\n",ifp
->desc
);
1341 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1342 /* wireless is the default*/
1343 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1345 vty_out (vty
, " babel wired\n");
1348 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1350 vty_out (vty
, " babel hello-interval %u\n",
1351 babel_ifp
->hello_interval
);
1354 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1356 vty_out (vty
, " babel update-interval %u\n",
1357 babel_ifp
->update_interval
);
1360 /* Some parameters have different defaults for wired/wireless. */
1361 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
)) {
1362 if (!CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1363 vty_out (vty
, " no babel split-horizon\n");
1366 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRED
) {
1367 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1370 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_INTERFERING
) {
1371 vty_out (vty
, " babel channel interfering\n");
1373 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_NONINTERFERING
) {
1374 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1378 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1379 vty_out (vty
, " babel split-horizon\n");
1382 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRELESS
) {
1383 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1386 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_NONINTERFERING
) {
1387 vty_out (vty
, " babel channel noninterfering\n");
1389 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_INTERFERING
) {
1390 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1394 vty_endframe (vty
, "!\n");
1400 /* Output a "network" statement line for each of the enabled interfaces. */
1402 babel_enable_if_config_write (struct vty
* vty
)
1404 unsigned int i
, lines
= 0;
1407 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
1408 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
1410 vty_out (vty
, " network %s\n", str
);
1416 /* functions to allocate or free memory for a babel_interface_nfo, filling
1418 static babel_interface_nfo
*
1419 babel_interface_allocate (void)
1421 babel_interface_nfo
*babel_ifp
;
1422 babel_ifp
= XCALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1423 /* All flags are unset */
1424 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1425 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1426 babel_ifp
->hello_seqno
= (random() & 0xFFFF);
1427 babel_ifp
->rtt_min
= 10000;
1428 babel_ifp
->rtt_max
= 120000;
1429 babel_ifp
->max_rtt_penalty
= 150;
1430 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1431 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1432 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1433 babel_set_wired_internal(babel_ifp
, 0);
1439 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1441 XFREE(MTYPE_BABEL_IF
, babel_ifp
);