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"
33 #include "babel_main.h"
36 #include "babel_interface.h"
39 #include "babel_zebra.h"
40 #include "neighbour.h"
43 #include "babel_errors.h"
45 DEFINE_MTYPE_STATIC(BABELD
, BABEL_IF
, "Babel Interface");
47 #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0)
49 static int babel_enable_if_lookup (const char *ifname
);
50 static int babel_enable_if_add (const char *ifname
);
51 static int babel_enable_if_delete (const char *ifname
);
52 static int interface_recalculate(struct interface
*ifp
);
53 static int interface_reset(struct interface
*ifp
);
54 static int babel_if_new_hook (struct interface
*ifp
);
55 static int babel_if_delete_hook (struct interface
*ifp
);
56 static int interface_config_write (struct vty
*vty
);
57 static babel_interface_nfo
* babel_interface_allocate (void);
58 static void babel_interface_free (babel_interface_nfo
*bi
);
61 static vector babel_enable_if
; /* enable interfaces (by cmd). */
62 static int interface_config_write(struct vty
*vty
);
63 static struct cmd_node babel_interface_node
= {
65 .node
= INTERFACE_NODE
,
66 .parent_node
= CONFIG_NODE
,
67 .prompt
= "%s(config-if)# ",
68 .config_write
= interface_config_write
,
73 babel_interface_up (ZAPI_CALLBACK_ARGS
)
75 struct stream
*s
= NULL
;
76 struct interface
*ifp
= NULL
;
78 debugf(BABEL_DEBUG_IF
, "receive a 'interface up'");
81 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
87 interface_recalculate(ifp
);
92 babel_ifp_down(struct interface
*ifp
)
94 debugf(BABEL_DEBUG_IF
, "receive a 'interface down'");
100 interface_reset(ifp
);
104 int babel_ifp_create (struct interface
*ifp
)
106 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
108 interface_recalculate(ifp
);
114 babel_ifp_destroy(struct interface
*ifp
)
116 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
119 interface_reset(ifp
);
125 babel_interface_address_add (ZAPI_CALLBACK_ARGS
)
127 babel_interface_nfo
*babel_ifp
;
128 struct connected
*ifc
;
129 struct prefix
*prefix
;
131 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
133 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
134 zclient
->ibuf
, vrf_id
);
139 prefix
= ifc
->address
;
141 if (prefix
->family
== AF_INET
) {
142 flush_interface_routes(ifc
->ifp
, 0);
143 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
144 if (babel_ifp
->ipv4
== NULL
) {
145 babel_ifp
->ipv4
= malloc(4);
146 if (babel_ifp
->ipv4
== NULL
) {
147 flog_err(EC_BABEL_MEMORY
, "not enough memory");
149 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
154 send_request(ifc
->ifp
, NULL
, 0);
155 send_update(ifc
->ifp
, 0, NULL
, 0);
161 babel_interface_address_delete (ZAPI_CALLBACK_ARGS
)
163 babel_interface_nfo
*babel_ifp
;
164 struct connected
*ifc
;
165 struct prefix
*prefix
;
167 debugf(BABEL_DEBUG_IF
, "receive a 'interface address delete'");
169 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE
,
170 zclient
->ibuf
, vrf_id
);
175 prefix
= ifc
->address
;
177 if (prefix
->family
== AF_INET
) {
178 flush_interface_routes(ifc
->ifp
, 0);
179 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
180 if (babel_ifp
->ipv4
!= NULL
181 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4) == 0) {
182 free(babel_ifp
->ipv4
);
183 babel_ifp
->ipv4
= NULL
;
187 send_request(ifc
->ifp
, NULL
, 0);
188 send_update(ifc
->ifp
, 0, NULL
, 0);
190 connected_free(&ifc
);
194 /* Lookup function. */
196 babel_enable_if_lookup (const char *ifname
)
201 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
202 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
203 if (strcmp (str
, ifname
) == 0)
208 /* Add interface to babel_enable_if. */
210 babel_enable_if_add (const char *ifname
)
213 struct interface
*ifp
= NULL
;
215 ret
= babel_enable_if_lookup (ifname
);
219 vector_set (babel_enable_if
, strdup (ifname
));
221 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
223 interface_recalculate(ifp
);
228 /* Delete interface from babel_enable_if. */
230 babel_enable_if_delete (const char *ifname
)
232 int babel_enable_if_index
;
234 struct interface
*ifp
= NULL
;
236 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
237 if (babel_enable_if_index
< 0)
240 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
242 vector_unset (babel_enable_if
, babel_enable_if_index
);
244 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
246 interface_reset(ifp
);
251 /* [Babel Command] Babel enable on specified interface or matched network. */
252 DEFUN (babel_network
,
254 "network IF_OR_ADDR",
255 "Enable Babel protocol on specified interface or network.\n"
256 "Interface or address\n")
261 ret
= str2prefix (argv
[1]->arg
, &p
);
263 /* Given string is: */
264 if (ret
) /* an IPv4 or v6 network */
265 return CMD_ERR_NO_MATCH
; /* not implemented yet */
266 else /* an interface name */
267 ret
= babel_enable_if_add (argv
[1]->arg
);
270 vty_out (vty
, "There is same network configuration %s\n",
278 /* [Babel Command] Babel enable on specified interface or matched network. */
279 DEFUN (no_babel_network
,
280 no_babel_network_cmd
,
281 "no network IF_OR_ADDR",
283 "Disable Babel protocol on specified interface or network.\n"
284 "Interface or address\n")
289 ret
= str2prefix (argv
[2]->arg
, &p
);
291 /* Given string is: */
292 if (ret
) /* an IPv4 or v6 network */
293 return CMD_ERR_NO_MATCH
; /* not implemented yet */
294 else /* an interface name */
295 ret
= babel_enable_if_delete (argv
[2]->arg
);
298 vty_out (vty
, "can't find network %s\n",argv
[2]->arg
);
299 return CMD_WARNING_CONFIG_FAILED
;
305 /* There are a number of interface parameters that must be changed when
306 an interface becomes wired/wireless. In Quagga, they cannot be
307 configured separately. */
310 babel_set_wired_internal(babel_interface_nfo
*babel_ifp
, int wired
)
313 babel_ifp
->flags
|= BABEL_IF_WIRED
;
314 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
315 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRED
;
316 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
317 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
319 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
320 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
321 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRELESS
;
322 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
323 babel_ifp
->flags
|= BABEL_IF_LQ
;
328 /* [Interface Command] Tell the interface is wire. */
329 DEFUN (babel_set_wired
,
332 "Babel interface commands\n"
333 "Enable wired optimizations\n")
335 VTY_DECLVAR_CONTEXT(interface
, ifp
);
336 babel_interface_nfo
*babel_ifp
;
338 babel_ifp
= babel_get_if_nfo(ifp
);
340 assert (babel_ifp
!= NULL
);
341 babel_set_wired_internal(babel_ifp
, 1);
345 /* [Interface Command] Tell the interface is wireless (default). */
346 DEFUN (babel_set_wireless
,
347 babel_set_wireless_cmd
,
349 "Babel interface commands\n"
350 "Disable wired optimizations (assume wireless)\n")
352 VTY_DECLVAR_CONTEXT(interface
, ifp
);
353 babel_interface_nfo
*babel_ifp
;
355 babel_ifp
= babel_get_if_nfo(ifp
);
357 assert (babel_ifp
!= NULL
);
358 babel_set_wired_internal(babel_ifp
, 0);
362 /* [Interface Command] Enable split horizon. */
363 DEFUN (babel_split_horizon
,
364 babel_split_horizon_cmd
,
365 "babel split-horizon",
366 "Babel interface commands\n"
367 "Enable split horizon processing\n")
369 VTY_DECLVAR_CONTEXT(interface
, ifp
);
370 babel_interface_nfo
*babel_ifp
;
372 babel_ifp
= babel_get_if_nfo(ifp
);
374 assert (babel_ifp
!= NULL
);
375 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
379 /* [Interface Command] Disable split horizon (default). */
380 DEFUN (no_babel_split_horizon
,
381 no_babel_split_horizon_cmd
,
382 "no babel split-horizon",
384 "Babel interface commands\n"
385 "Disable split horizon processing\n")
387 VTY_DECLVAR_CONTEXT(interface
, ifp
);
388 babel_interface_nfo
*babel_ifp
;
390 babel_ifp
= babel_get_if_nfo(ifp
);
392 assert (babel_ifp
!= NULL
);
393 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
397 /* [Interface Command]. */
398 DEFUN (babel_set_hello_interval
,
399 babel_set_hello_interval_cmd
,
400 "babel hello-interval (20-655340)",
401 "Babel interface commands\n"
402 "Time between scheduled hellos\n"
405 VTY_DECLVAR_CONTEXT(interface
, ifp
);
406 babel_interface_nfo
*babel_ifp
;
409 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
411 babel_ifp
= babel_get_if_nfo(ifp
);
412 assert (babel_ifp
!= NULL
);
414 babel_ifp
->hello_interval
= interval
;
418 /* [Interface Command]. */
419 DEFUN (babel_set_update_interval
,
420 babel_set_update_interval_cmd
,
421 "babel update-interval (20-655340)",
422 "Babel interface commands\n"
423 "Time between scheduled updates\n"
426 VTY_DECLVAR_CONTEXT(interface
, ifp
);
427 babel_interface_nfo
*babel_ifp
;
430 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
432 babel_ifp
= babel_get_if_nfo(ifp
);
433 assert (babel_ifp
!= NULL
);
435 babel_ifp
->update_interval
= interval
;
439 DEFUN (babel_set_rxcost
,
440 babel_set_rxcost_cmd
,
441 "babel rxcost (1-65534)",
442 "Babel interface commands\n"
443 "Rxcost multiplier\n"
446 VTY_DECLVAR_CONTEXT(interface
, ifp
);
447 babel_interface_nfo
*babel_ifp
;
450 rxcost
= strtoul(argv
[2]->arg
, NULL
, 10);
452 babel_ifp
= babel_get_if_nfo(ifp
);
453 assert (babel_ifp
!= NULL
);
455 babel_ifp
->cost
= rxcost
;
459 DEFUN (babel_set_rtt_decay
,
460 babel_set_rtt_decay_cmd
,
461 "babel rtt-decay (1-256)",
462 "Babel interface commands\n"
463 "Decay factor for exponential moving average of RTT samples\n"
466 VTY_DECLVAR_CONTEXT(interface
, ifp
);
467 babel_interface_nfo
*babel_ifp
;
470 decay
= strtoul(argv
[2]->arg
, NULL
, 10);
472 babel_ifp
= babel_get_if_nfo(ifp
);
473 assert (babel_ifp
!= NULL
);
475 babel_ifp
->rtt_decay
= decay
;
479 DEFUN (babel_set_rtt_min
,
480 babel_set_rtt_min_cmd
,
481 "babel rtt-min (1-65535)",
482 "Babel interface commands\n"
483 "Minimum RTT starting for increasing cost\n"
486 VTY_DECLVAR_CONTEXT(interface
, ifp
);
487 babel_interface_nfo
*babel_ifp
;
490 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
492 babel_ifp
= babel_get_if_nfo(ifp
);
493 assert (babel_ifp
!= NULL
);
495 babel_ifp
->rtt_min
= rtt
;
499 DEFUN (babel_set_rtt_max
,
500 babel_set_rtt_max_cmd
,
501 "babel rtt-max (1-65535)",
502 "Babel interface commands\n"
506 VTY_DECLVAR_CONTEXT(interface
, ifp
);
507 babel_interface_nfo
*babel_ifp
;
510 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
512 babel_ifp
= babel_get_if_nfo(ifp
);
513 assert (babel_ifp
!= NULL
);
515 babel_ifp
->rtt_max
= rtt
;
519 DEFUN (babel_set_max_rtt_penalty
,
520 babel_set_max_rtt_penalty_cmd
,
521 "babel max-rtt-penalty (0-65535)",
522 "Babel interface commands\n"
523 "Maximum additional cost due to RTT\n"
526 VTY_DECLVAR_CONTEXT(interface
, ifp
);
527 babel_interface_nfo
*babel_ifp
;
530 penalty
= strtoul(argv
[2]->arg
, NULL
, 10);
532 babel_ifp
= babel_get_if_nfo(ifp
);
533 assert (babel_ifp
!= NULL
);
535 babel_ifp
->max_rtt_penalty
= penalty
;
539 DEFUN (babel_set_enable_timestamps
,
540 babel_set_enable_timestamps_cmd
,
541 "babel enable-timestamps",
542 "Babel interface commands\n"
543 "Enable timestamps\n")
545 VTY_DECLVAR_CONTEXT(interface
, ifp
);
546 babel_interface_nfo
*babel_ifp
;
548 babel_ifp
= babel_get_if_nfo(ifp
);
549 assert (babel_ifp
!= NULL
);
551 babel_ifp
->flags
|= BABEL_IF_TIMESTAMPS
;
555 DEFUN (no_babel_set_enable_timestamps
,
556 no_babel_set_enable_timestamps_cmd
,
557 "no babel enable-timestamps",
559 "Babel interface commands\n"
560 "Disable timestamps\n")
562 VTY_DECLVAR_CONTEXT(interface
, ifp
);
563 babel_interface_nfo
*babel_ifp
;
565 babel_ifp
= babel_get_if_nfo(ifp
);
566 assert (babel_ifp
!= NULL
);
568 babel_ifp
->flags
&= ~BABEL_IF_TIMESTAMPS
;
572 DEFUN (babel_set_channel
,
573 babel_set_channel_cmd
,
574 "babel channel (1-254)",
575 "Babel interface commands\n"
576 "Channel number for diversity routing\n"
579 VTY_DECLVAR_CONTEXT(interface
, ifp
);
580 babel_interface_nfo
*babel_ifp
;
583 channel
= strtoul(argv
[2]->arg
, NULL
, 10);
585 babel_ifp
= babel_get_if_nfo(ifp
);
586 assert (babel_ifp
!= NULL
);
588 babel_ifp
->channel
= channel
;
592 DEFUN (babel_set_channel_interfering
,
593 babel_set_channel_interfering_cmd
,
594 "babel channel interfering",
595 "Babel interface commands\n"
596 "Channel number for diversity routing\n"
597 "Mark channel as interfering\n")
599 VTY_DECLVAR_CONTEXT(interface
, ifp
);
600 babel_interface_nfo
*babel_ifp
;
602 babel_ifp
= babel_get_if_nfo(ifp
);
603 assert (babel_ifp
!= NULL
);
605 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
609 DEFUN (babel_set_channel_noninterfering
,
610 babel_set_channel_noninterfering_cmd
,
611 "babel channel noninterfering",
612 "Babel interface commands\n"
613 "Channel number for diversity routing\n"
614 "Mark channel as noninterfering\n")
616 VTY_DECLVAR_CONTEXT(interface
, ifp
);
617 babel_interface_nfo
*babel_ifp
;
619 babel_ifp
= babel_get_if_nfo(ifp
);
620 assert (babel_ifp
!= NULL
);
622 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
626 /* This should be no more than half the hello interval, so that hellos
627 aren't sent late. The result is in milliseconds. */
629 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
631 unsigned interval
= babel_ifp
->hello_interval
;
633 interval
= MIN(interval
, 100);
635 interval
= MIN(interval
, 4000);
636 return roughly(interval
) / 4;
640 update_jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
642 unsigned interval
= babel_ifp
->hello_interval
;
644 interval
= MIN(interval
, 100);
646 interval
= MIN(interval
, 4000);
647 return roughly(interval
);
650 /* calculate babeld's specific datas of an interface (change when the interface
653 interface_recalculate(struct interface
*ifp
)
655 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
656 unsigned char *tmp
= NULL
;
658 struct ipv6_mreq mreq
;
663 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
664 interface_reset(ifp
);
668 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
670 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
672 /* We need to be able to fit at least two messages into a packet,
673 so MTUs below 116 require lower layer fragmentation. */
674 /* In IPv6, the minimum MTU is 1280, and every host must be able
675 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
677 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
678 mtu
, ifp
->name
, ifp
->ifindex
);
682 /* 4 for Babel header; 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
683 babel_ifp
->bufsize
= mtu
- 4 - 60;
684 tmp
= babel_ifp
->sendbuf
;
685 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
686 if(babel_ifp
->sendbuf
== NULL
) {
687 flog_err(EC_BABEL_MEMORY
, "Couldn't reallocate sendbuf.");
689 babel_ifp
->bufsize
= 0;
694 rc
= resize_receive_buffer(mtu
);
696 zlog_warn("couldn't resize receive buffer for interface %s (%d) (%d bytes).",
697 ifp
->name
, ifp
->ifindex
, mtu
);
699 memset(&mreq
, 0, sizeof(mreq
));
700 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
701 mreq
.ipv6mr_interface
= ifp
->ifindex
;
703 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
704 (char*)&mreq
, sizeof(mreq
));
706 flog_err_sys(EC_LIB_SOCKET
,
707 "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
708 ifp
->name
, safe_strerror(errno
));
709 /* This is probably due to a missing link-local address,
710 so down this interface, and wait until the main loop
711 tries to up it again. */
712 interface_reset(ifp
);
716 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
717 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
719 send_request(ifp
, NULL
, 0);
721 update_interface_metric(ifp
);
723 debugf(BABEL_DEBUG_COMMON
,
724 "Upped interface %s (%s, cost=%d, channel=%d%s).",
726 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
729 babel_ifp
->ipv4
? ", IPv4" : "");
732 send_update(ifp
, 0, NULL
, 0);
737 /* Reset the interface as it was new: it's not removed from the interface list,
738 and may be considered as a upped interface. */
740 interface_reset(struct interface
*ifp
)
743 struct ipv6_mreq mreq
;
744 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
746 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
749 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
750 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
752 flush_interface_routes(ifp
, 0);
753 babel_ifp
->buffered
= 0;
754 babel_ifp
->bufsize
= 0;
755 free(babel_ifp
->sendbuf
);
756 babel_ifp
->num_buffered_updates
= 0;
757 babel_ifp
->update_bufsize
= 0;
758 if(babel_ifp
->buffered_updates
)
759 free(babel_ifp
->buffered_updates
);
760 babel_ifp
->buffered_updates
= NULL
;
761 babel_ifp
->sendbuf
= NULL
;
763 if(ifp
->ifindex
> 0) {
764 memset(&mreq
, 0, sizeof(mreq
));
765 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
766 mreq
.ipv6mr_interface
= ifp
->ifindex
;
767 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
768 (char*)&mreq
, sizeof(mreq
));
770 flog_err_sys(EC_LIB_SOCKET
,
771 "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
772 ifp
->name
, safe_strerror(errno
));
775 update_interface_metric(ifp
);
777 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
779 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
781 babel_ifp
->ipv4
? ", IPv4" : "");
786 /* Send retraction to all, and reset all interfaces statistics. */
788 babel_interface_close_all(void)
790 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
791 struct interface
*ifp
= NULL
;
793 FOR_ALL_INTERFACES(vrf
, ifp
) {
796 send_wildcard_retraction(ifp
);
797 /* Make sure that we expire quickly from our neighbours'
798 association caches. */
799 send_hello_noupdate(ifp
, 10);
801 usleep(roughly(1000));
804 FOR_ALL_INTERFACES(vrf
, ifp
) {
807 /* Make sure they got it. */
808 send_wildcard_retraction(ifp
);
809 send_hello_noupdate(ifp
, 1);
811 usleep(roughly(10000));
813 interface_reset(ifp
);
817 /* return "true" if address is one of our ipv6 addresses */
819 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
821 struct connected
*connected
;
822 struct listnode
*node
;
827 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
828 if(connected
->address
->family
== AF_INET6
&&
829 memcmp(&connected
->address
->u
.prefix6
, address
, 16) == 0)
837 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
840 babel_interface_nfo
*babel_ifp
;
842 vty_out (vty
, "%s is %s\n", ifp
->name
,
843 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
844 vty_out (vty
, " ifindex %u, MTU %u bytes %s\n",
845 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
849 vty_out (vty
, " Babel protocol is not enabled on this interface\n");
855 " Babel protocol is enabled, but not running on this interface\n");
858 babel_ifp
= babel_get_if_nfo (ifp
);
859 vty_out (vty
, " Babel protocol is running on this interface\n");
860 vty_out (vty
, " Operating mode is \"%s\"\n",
861 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
862 vty_out (vty
, " Split horizon mode is %s\n",
863 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
864 vty_out (vty
, " Hello interval is %u ms\n", babel_ifp
->hello_interval
);
865 vty_out (vty
, " Update interval is %u ms\n", babel_ifp
->update_interval
);
866 vty_out (vty
, " Rxcost multiplier is %u\n", babel_ifp
->cost
);
869 DEFUN (show_babel_interface
,
870 show_babel_interface_cmd
,
871 "show babel interface [IFNAME]",
873 "Babel information\n"
874 "Interface information\n"
877 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
878 struct interface
*ifp
;
882 FOR_ALL_INTERFACES (vrf
, ifp
)
883 show_babel_interface_sub (vty
, ifp
);
886 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
888 vty_out (vty
, "No such interface name\n");
891 show_babel_interface_sub (vty
, ifp
);
896 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
899 "Neighbour %s dev %s reach %04x rxcost %d txcost %d rtt %s rttcost %d%s.\n",
900 format_address(neigh
->address
),
903 neighbour_rxcost(neigh
),
905 format_thousands(neigh
->rtt
),
906 neighbour_rttcost(neigh
),
907 if_up(neigh
->ifp
) ? "" : " (down)");
910 DEFUN (show_babel_neighbour
,
911 show_babel_neighbour_cmd
,
912 "show babel neighbor [IFNAME]",
914 "Babel information\n"
918 struct neighbour
*neigh
;
919 struct interface
*ifp
;
922 FOR_ALL_NEIGHBOURS(neigh
) {
923 show_babel_neighbour_sub(vty
, neigh
);
927 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
929 vty_out (vty
, "No such interface name\n");
932 FOR_ALL_NEIGHBOURS(neigh
) {
933 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
934 show_babel_neighbour_sub(vty
, neigh
);
941 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
943 if(prefix
->family
== AF_INET6
) {
944 if(prefix
->prefixlen
!= plen
||
945 memcmp(&prefix
->u
.prefix6
, p
, 16) != 0)
947 } else if(prefix
->family
== AF_INET
) {
948 if(plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96 ||
949 memcmp(&prefix
->u
.prefix4
, p
+ 12, 4) != 0)
959 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
960 struct prefix
*prefix
)
962 const unsigned char *nexthop
=
963 memcmp(route
->nexthop
, route
->neigh
->address
, 16) == 0 ?
964 NULL
: route
->nexthop
;
967 if(prefix
&& !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
970 if(route
->channels
[0] == 0)
974 snprintf(channels
, sizeof(channels
), " chan (");
975 j
= strlen(channels
);
976 for(k
= 0; k
< DIVERSITY_HOPS
; k
++) {
977 if(route
->channels
[k
] == 0)
981 snprintf(channels
+ j
, 100 - j
, "%u", route
->channels
[k
]);
982 j
= strlen(channels
);
984 snprintf(channels
+ j
, 100 - j
, ")");
990 "%s metric %d refmetric %d id %s seqno %d%s age %d via %s neigh %s%s%s%s\n",
991 format_prefix(route
->src
->prefix
, route
->src
->plen
),
992 route_metric(route
), route
->refmetric
,
993 format_eui64(route
->src
->id
),
996 (int)(babel_now
.tv_sec
- route
->time
),
997 route
->neigh
->ifp
->name
,
998 format_address(route
->neigh
->address
),
999 nexthop
? " nexthop " : "",
1000 nexthop
? format_address(nexthop
) : "",
1001 route
->installed
? " (installed)" : route_feasible(route
) ? " (feasible)" : "");
1005 show_babel_xroutes_sub (struct xroute
*xroute
, struct vty
*vty
,
1006 struct prefix
*prefix
)
1008 if(prefix
&& !babel_prefix_eq(prefix
, xroute
->prefix
, xroute
->plen
))
1011 vty_out (vty
, "%s metric %d (exported)\n",
1012 format_prefix(xroute
->prefix
, xroute
->plen
),
1016 DEFUN (show_babel_route
,
1017 show_babel_route_cmd
,
1020 "Babel information\n"
1021 "Babel internal routing table\n")
1023 struct route_stream
*routes
= NULL
;
1024 struct xroute_stream
*xroutes
= NULL
;
1025 routes
= route_stream(0);
1028 struct babel_route
*route
= route_stream_next(routes
);
1031 show_babel_routes_sub(route
, vty
, NULL
);
1033 route_stream_done(routes
);
1035 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1037 xroutes
= xroute_stream();
1040 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1043 show_babel_xroutes_sub(xroute
, vty
, NULL
);
1045 xroute_stream_done(xroutes
);
1047 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1052 DEFUN (show_babel_route_prefix
,
1053 show_babel_route_prefix_cmd
,
1054 "show babel route <A.B.C.D/M|X:X::X:X/M>",
1056 "Babel information\n"
1057 "Babel internal routing table\n"
1058 "IPv4 prefix <network>/<length>\n"
1059 "IPv6 prefix <network>/<length>\n")
1061 struct route_stream
*routes
= NULL
;
1062 struct xroute_stream
*xroutes
= NULL
;
1063 struct prefix prefix
;
1066 ret
= str2prefix(argv
[3]->arg
, &prefix
);
1068 vty_out (vty
, "%% Malformed address\n");
1072 routes
= route_stream(0);
1075 struct babel_route
*route
= route_stream_next(routes
);
1078 show_babel_routes_sub(route
, vty
, &prefix
);
1080 route_stream_done(routes
);
1082 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1084 xroutes
= xroute_stream();
1087 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1090 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1092 xroute_stream_done(xroutes
);
1094 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1100 DEFUN (show_babel_route_addr
,
1101 show_babel_route_addr_cmd
,
1102 "show babel route A.B.C.D",
1104 "Babel information\n"
1105 "Babel internal routing table\n"
1106 "IPv4 address <network>/<length>\n")
1108 struct in_addr addr
;
1109 char buf
[INET_ADDRSTRLEN
+ 8];
1110 char buf1
[INET_ADDRSTRLEN
+ 8];
1111 struct route_stream
*routes
= NULL
;
1112 struct xroute_stream
*xroutes
= NULL
;
1113 struct prefix prefix
;
1116 ret
= inet_aton (argv
[3]->arg
, &addr
);
1118 vty_out (vty
, "%% Malformed address\n");
1122 /* Quagga has no convenient prefix constructors. */
1123 snprintf(buf
, sizeof(buf
), "%s/%d",
1124 inet_ntop(AF_INET
, &addr
, buf1
, sizeof(buf1
)), 32);
1126 ret
= str2prefix(buf
, &prefix
);
1128 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1132 routes
= route_stream(0);
1135 struct babel_route
*route
= route_stream_next(routes
);
1138 show_babel_routes_sub(route
, vty
, &prefix
);
1140 route_stream_done(routes
);
1142 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1144 xroutes
= xroute_stream();
1147 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1150 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1152 xroute_stream_done(xroutes
);
1154 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1159 DEFUN (show_babel_route_addr6
,
1160 show_babel_route_addr6_cmd
,
1161 "show babel route X:X::X:X",
1163 "Babel information\n"
1164 "Babel internal routing table\n"
1165 "IPv6 address <network>/<length>\n")
1167 struct in6_addr addr
;
1168 char buf1
[INET6_ADDRSTRLEN
];
1169 char buf
[INET6_ADDRSTRLEN
+ 8];
1170 struct route_stream
*routes
= NULL
;
1171 struct xroute_stream
*xroutes
= NULL
;
1172 struct prefix prefix
;
1175 ret
= inet_pton (AF_INET6
, argv
[3]->arg
, &addr
);
1177 vty_out (vty
, "%% Malformed address\n");
1181 /* Quagga has no convenient prefix constructors. */
1182 snprintf(buf
, sizeof(buf
), "%s/%d",
1183 inet_ntop(AF_INET6
, &addr
, buf1
, sizeof(buf1
)), 128);
1185 ret
= str2prefix(buf
, &prefix
);
1187 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1191 routes
= route_stream(0);
1194 struct babel_route
*route
= route_stream_next(routes
);
1197 show_babel_routes_sub(route
, vty
, &prefix
);
1199 route_stream_done(routes
);
1201 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1203 xroutes
= xroute_stream();
1206 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1209 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1211 xroute_stream_done(xroutes
);
1213 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1218 DEFUN (show_babel_parameters
,
1219 show_babel_parameters_cmd
,
1220 "show babel parameters",
1222 "Babel information\n"
1223 "Configuration information\n")
1225 struct babel
*babel_ctx
;
1227 vty_out (vty
, " -- Babel running configuration --\n");
1228 show_babel_main_configuration(vty
);
1230 babel_ctx
= babel_lookup();
1232 vty_out (vty
, " -- distribution lists --\n");
1233 config_show_distribute(vty
, babel_ctx
->distribute_ctx
);
1238 int babel_ifp_up(struct interface
*ifp
)
1246 /* initialize interface list */
1247 hook_register_prio(if_add
, 0, babel_if_new_hook
);
1248 hook_register_prio(if_del
, 0, babel_if_delete_hook
);
1250 babel_enable_if
= vector_init (1);
1252 /* install interface node and commands */
1253 install_node(&babel_interface_node
);
1256 install_element(BABEL_NODE
, &babel_network_cmd
);
1257 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1258 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1259 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1260 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1261 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1262 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1263 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1264 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1265 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1266 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1267 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1268 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1269 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1270 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1271 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1272 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1273 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1275 /* "show babel ..." commands */
1276 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1277 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1278 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1279 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1280 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1281 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1282 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1285 /* hooks: functions called respectively when struct interface is
1286 created or deleted. */
1288 babel_if_new_hook (struct interface
*ifp
)
1290 ifp
->info
= babel_interface_allocate();
1295 babel_if_delete_hook (struct interface
*ifp
)
1297 babel_interface_free(ifp
->info
);
1302 /* Output an "interface" section for each of the known interfaces with
1303 babeld-specific statement lines where appropriate. */
1305 interface_config_write (struct vty
*vty
)
1307 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1308 struct interface
*ifp
;
1311 FOR_ALL_INTERFACES (vrf
, ifp
) {
1312 vty_frame (vty
, "interface %s\n",ifp
->name
);
1314 vty_out (vty
, " description %s\n",ifp
->desc
);
1315 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1316 /* wireless is the default*/
1317 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1319 vty_out (vty
, " babel wired\n");
1322 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1324 vty_out (vty
, " babel hello-interval %u\n",
1325 babel_ifp
->hello_interval
);
1328 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1330 vty_out (vty
, " babel update-interval %u\n",
1331 babel_ifp
->update_interval
);
1334 /* Some parameters have different defaults for wired/wireless. */
1335 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
)) {
1336 if (!CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1337 vty_out (vty
, " no babel split-horizon\n");
1340 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRED
) {
1341 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1344 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_INTERFERING
) {
1345 vty_out (vty
, " babel channel interfering\n");
1347 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_NONINTERFERING
) {
1348 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1352 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1353 vty_out (vty
, " babel split-horizon\n");
1356 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRELESS
) {
1357 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1360 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_NONINTERFERING
) {
1361 vty_out (vty
, " babel channel noninterfering\n");
1363 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_INTERFERING
) {
1364 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1368 vty_endframe (vty
, "!\n");
1374 /* Output a "network" statement line for each of the enabled interfaces. */
1376 babel_enable_if_config_write (struct vty
* vty
)
1378 unsigned int i
, lines
= 0;
1381 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
1382 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
1384 vty_out (vty
, " network %s\n", str
);
1390 /* functions to allocate or free memory for a babel_interface_nfo, filling
1392 static babel_interface_nfo
*
1393 babel_interface_allocate (void)
1395 babel_interface_nfo
*babel_ifp
;
1396 babel_ifp
= XCALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1397 /* All flags are unset */
1398 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1399 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1400 babel_ifp
->hello_seqno
= (frr_weak_random() & 0xFFFF);
1401 babel_ifp
->rtt_min
= 10000;
1402 babel_ifp
->rtt_max
= 120000;
1403 babel_ifp
->max_rtt_penalty
= 150;
1404 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1405 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1406 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1407 babel_set_wired_internal(babel_ifp
, 0);
1413 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1415 XFREE(MTYPE_BABEL_IF
, babel_ifp
);