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). */
64 babel_interface_up (ZAPI_CALLBACK_ARGS
)
66 struct stream
*s
= NULL
;
67 struct interface
*ifp
= NULL
;
69 debugf(BABEL_DEBUG_IF
, "receive a 'interface up'");
72 ifp
= zebra_interface_state_read(s
, vrf_id
); /* it updates iflist */
78 interface_recalculate(ifp
);
83 babel_ifp_down(struct interface
*ifp
)
85 debugf(BABEL_DEBUG_IF
, "receive a 'interface down'");
95 int babel_ifp_create (struct interface
*ifp
)
97 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
99 interface_recalculate(ifp
);
105 babel_ifp_destroy(struct interface
*ifp
)
107 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
110 interface_reset(ifp
);
116 babel_interface_address_add (ZAPI_CALLBACK_ARGS
)
118 babel_interface_nfo
*babel_ifp
;
119 struct connected
*ifc
;
120 struct prefix
*prefix
;
122 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
124 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
125 zclient
->ibuf
, vrf_id
);
130 prefix
= ifc
->address
;
132 if (prefix
->family
== AF_INET
) {
133 flush_interface_routes(ifc
->ifp
, 0);
134 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
135 if (babel_ifp
->ipv4
== NULL
) {
136 babel_ifp
->ipv4
= malloc(4);
137 if (babel_ifp
->ipv4
== NULL
) {
138 flog_err(EC_BABEL_MEMORY
, "not enough memory");
140 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
145 send_request(ifc
->ifp
, NULL
, 0);
146 send_update(ifc
->ifp
, 0, NULL
, 0);
152 babel_interface_address_delete (ZAPI_CALLBACK_ARGS
)
154 babel_interface_nfo
*babel_ifp
;
155 struct connected
*ifc
;
156 struct prefix
*prefix
;
158 debugf(BABEL_DEBUG_IF
, "receive a 'interface address delete'");
160 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE
,
161 zclient
->ibuf
, vrf_id
);
166 prefix
= ifc
->address
;
168 if (prefix
->family
== AF_INET
) {
169 flush_interface_routes(ifc
->ifp
, 0);
170 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
171 if (babel_ifp
->ipv4
!= NULL
172 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, IPV4_MAX_BYTELEN
)
174 free(babel_ifp
->ipv4
);
175 babel_ifp
->ipv4
= NULL
;
179 send_request(ifc
->ifp
, NULL
, 0);
180 send_update(ifc
->ifp
, 0, NULL
, 0);
182 connected_free(&ifc
);
186 /* Lookup function. */
188 babel_enable_if_lookup (const char *ifname
)
193 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
194 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
195 if (strcmp (str
, ifname
) == 0)
200 /* Add interface to babel_enable_if. */
202 babel_enable_if_add (const char *ifname
)
205 struct interface
*ifp
= NULL
;
207 ret
= babel_enable_if_lookup (ifname
);
211 vector_set (babel_enable_if
, strdup (ifname
));
213 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
215 interface_recalculate(ifp
);
220 /* Delete interface from babel_enable_if. */
222 babel_enable_if_delete (const char *ifname
)
224 int babel_enable_if_index
;
226 struct interface
*ifp
= NULL
;
228 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
229 if (babel_enable_if_index
< 0)
232 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
234 vector_unset (babel_enable_if
, babel_enable_if_index
);
236 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
238 interface_reset(ifp
);
243 /* [Babel Command] Babel enable on specified interface or matched network. */
244 DEFUN (babel_network
,
246 "network IF_OR_ADDR",
247 "Enable Babel protocol on specified interface or network.\n"
248 "Interface or address\n")
253 ret
= str2prefix (argv
[1]->arg
, &p
);
255 /* Given string is: */
256 if (ret
) /* an IPv4 or v6 network */
257 return CMD_ERR_NO_MATCH
; /* not implemented yet */
258 else /* an interface name */
259 ret
= babel_enable_if_add (argv
[1]->arg
);
262 vty_out (vty
, "There is same network configuration %s\n",
270 /* [Babel Command] Babel enable on specified interface or matched network. */
271 DEFUN (no_babel_network
,
272 no_babel_network_cmd
,
273 "no network IF_OR_ADDR",
275 "Disable Babel protocol on specified interface or network.\n"
276 "Interface or address\n")
281 ret
= str2prefix (argv
[2]->arg
, &p
);
283 /* Given string is: */
284 if (ret
) /* an IPv4 or v6 network */
285 return CMD_ERR_NO_MATCH
; /* not implemented yet */
286 else /* an interface name */
287 ret
= babel_enable_if_delete (argv
[2]->arg
);
290 vty_out (vty
, "can't find network %s\n",argv
[2]->arg
);
291 return CMD_WARNING_CONFIG_FAILED
;
297 /* There are a number of interface parameters that must be changed when
298 an interface becomes wired/wireless. In Quagga, they cannot be
299 configured separately. */
302 babel_set_wired_internal(babel_interface_nfo
*babel_ifp
, int wired
)
305 babel_ifp
->flags
|= BABEL_IF_WIRED
;
306 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
307 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRED
;
308 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
309 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
311 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
312 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
313 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRELESS
;
314 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
315 babel_ifp
->flags
|= BABEL_IF_LQ
;
320 /* [Interface Command] Tell the interface is wire. */
321 DEFUN (babel_set_wired
,
324 "Babel interface commands\n"
325 "Enable wired optimizations\n")
327 VTY_DECLVAR_CONTEXT(interface
, ifp
);
328 babel_interface_nfo
*babel_ifp
;
330 babel_ifp
= babel_get_if_nfo(ifp
);
332 assert (babel_ifp
!= NULL
);
333 babel_set_wired_internal(babel_ifp
, 1);
337 /* [Interface Command] Tell the interface is wireless (default). */
338 DEFUN (babel_set_wireless
,
339 babel_set_wireless_cmd
,
341 "Babel interface commands\n"
342 "Disable wired optimizations (assume wireless)\n")
344 VTY_DECLVAR_CONTEXT(interface
, ifp
);
345 babel_interface_nfo
*babel_ifp
;
347 babel_ifp
= babel_get_if_nfo(ifp
);
349 assert (babel_ifp
!= NULL
);
350 babel_set_wired_internal(babel_ifp
, 0);
354 /* [Interface Command] Enable split horizon. */
355 DEFUN (babel_split_horizon
,
356 babel_split_horizon_cmd
,
357 "babel split-horizon",
358 "Babel interface commands\n"
359 "Enable split horizon processing\n")
361 VTY_DECLVAR_CONTEXT(interface
, ifp
);
362 babel_interface_nfo
*babel_ifp
;
364 babel_ifp
= babel_get_if_nfo(ifp
);
366 assert (babel_ifp
!= NULL
);
367 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
371 /* [Interface Command] Disable split horizon (default). */
372 DEFUN (no_babel_split_horizon
,
373 no_babel_split_horizon_cmd
,
374 "no babel split-horizon",
376 "Babel interface commands\n"
377 "Disable split horizon processing\n")
379 VTY_DECLVAR_CONTEXT(interface
, ifp
);
380 babel_interface_nfo
*babel_ifp
;
382 babel_ifp
= babel_get_if_nfo(ifp
);
384 assert (babel_ifp
!= NULL
);
385 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
389 /* [Interface Command]. */
390 DEFUN (babel_set_hello_interval
,
391 babel_set_hello_interval_cmd
,
392 "babel hello-interval (20-655340)",
393 "Babel interface commands\n"
394 "Time between scheduled hellos\n"
397 VTY_DECLVAR_CONTEXT(interface
, ifp
);
398 babel_interface_nfo
*babel_ifp
;
401 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
403 babel_ifp
= babel_get_if_nfo(ifp
);
404 assert (babel_ifp
!= NULL
);
406 babel_ifp
->hello_interval
= interval
;
410 /* [Interface Command]. */
411 DEFUN (babel_set_update_interval
,
412 babel_set_update_interval_cmd
,
413 "babel update-interval (20-655340)",
414 "Babel interface commands\n"
415 "Time between scheduled updates\n"
418 VTY_DECLVAR_CONTEXT(interface
, ifp
);
419 babel_interface_nfo
*babel_ifp
;
422 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
424 babel_ifp
= babel_get_if_nfo(ifp
);
425 assert (babel_ifp
!= NULL
);
427 babel_ifp
->update_interval
= interval
;
431 DEFUN (babel_set_rxcost
,
432 babel_set_rxcost_cmd
,
433 "babel rxcost (1-65534)",
434 "Babel interface commands\n"
435 "Rxcost multiplier\n"
438 VTY_DECLVAR_CONTEXT(interface
, ifp
);
439 babel_interface_nfo
*babel_ifp
;
442 rxcost
= strtoul(argv
[2]->arg
, NULL
, 10);
444 babel_ifp
= babel_get_if_nfo(ifp
);
445 assert (babel_ifp
!= NULL
);
447 babel_ifp
->cost
= rxcost
;
451 DEFUN (babel_set_rtt_decay
,
452 babel_set_rtt_decay_cmd
,
453 "babel rtt-decay (1-256)",
454 "Babel interface commands\n"
455 "Decay factor for exponential moving average of RTT samples\n"
458 VTY_DECLVAR_CONTEXT(interface
, ifp
);
459 babel_interface_nfo
*babel_ifp
;
462 decay
= strtoul(argv
[2]->arg
, NULL
, 10);
464 babel_ifp
= babel_get_if_nfo(ifp
);
465 assert (babel_ifp
!= NULL
);
467 babel_ifp
->rtt_decay
= decay
;
471 DEFUN (babel_set_rtt_min
,
472 babel_set_rtt_min_cmd
,
473 "babel rtt-min (1-65535)",
474 "Babel interface commands\n"
475 "Minimum RTT starting for increasing cost\n"
478 VTY_DECLVAR_CONTEXT(interface
, ifp
);
479 babel_interface_nfo
*babel_ifp
;
482 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
484 babel_ifp
= babel_get_if_nfo(ifp
);
485 assert (babel_ifp
!= NULL
);
487 /* The value is entered in milliseconds but stored as microseconds. */
488 babel_ifp
->rtt_min
= rtt
* 1000;
492 DEFUN (babel_set_rtt_max
,
493 babel_set_rtt_max_cmd
,
494 "babel rtt-max (1-65535)",
495 "Babel interface commands\n"
499 VTY_DECLVAR_CONTEXT(interface
, ifp
);
500 babel_interface_nfo
*babel_ifp
;
503 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
505 babel_ifp
= babel_get_if_nfo(ifp
);
506 assert (babel_ifp
!= NULL
);
508 /* The value is entered in milliseconds but stored as microseconds. */
509 babel_ifp
->rtt_max
= rtt
* 1000;
513 DEFUN (babel_set_max_rtt_penalty
,
514 babel_set_max_rtt_penalty_cmd
,
515 "babel max-rtt-penalty (0-65535)",
516 "Babel interface commands\n"
517 "Maximum additional cost due to RTT\n"
520 VTY_DECLVAR_CONTEXT(interface
, ifp
);
521 babel_interface_nfo
*babel_ifp
;
524 penalty
= strtoul(argv
[2]->arg
, NULL
, 10);
526 babel_ifp
= babel_get_if_nfo(ifp
);
527 assert (babel_ifp
!= NULL
);
529 babel_ifp
->max_rtt_penalty
= penalty
;
533 DEFUN (babel_set_enable_timestamps
,
534 babel_set_enable_timestamps_cmd
,
535 "babel enable-timestamps",
536 "Babel interface commands\n"
537 "Enable timestamps\n")
539 VTY_DECLVAR_CONTEXT(interface
, ifp
);
540 babel_interface_nfo
*babel_ifp
;
542 babel_ifp
= babel_get_if_nfo(ifp
);
543 assert (babel_ifp
!= NULL
);
545 babel_ifp
->flags
|= BABEL_IF_TIMESTAMPS
;
549 DEFUN (no_babel_set_enable_timestamps
,
550 no_babel_set_enable_timestamps_cmd
,
551 "no babel enable-timestamps",
553 "Babel interface commands\n"
554 "Disable timestamps\n")
556 VTY_DECLVAR_CONTEXT(interface
, ifp
);
557 babel_interface_nfo
*babel_ifp
;
559 babel_ifp
= babel_get_if_nfo(ifp
);
560 assert (babel_ifp
!= NULL
);
562 babel_ifp
->flags
&= ~BABEL_IF_TIMESTAMPS
;
566 DEFUN (babel_set_channel
,
567 babel_set_channel_cmd
,
568 "babel channel (1-254)",
569 "Babel interface commands\n"
570 "Channel number for diversity routing\n"
573 VTY_DECLVAR_CONTEXT(interface
, ifp
);
574 babel_interface_nfo
*babel_ifp
;
577 channel
= strtoul(argv
[2]->arg
, NULL
, 10);
579 babel_ifp
= babel_get_if_nfo(ifp
);
580 assert (babel_ifp
!= NULL
);
582 babel_ifp
->channel
= channel
;
586 DEFUN (babel_set_channel_interfering
,
587 babel_set_channel_interfering_cmd
,
588 "babel channel interfering",
589 "Babel interface commands\n"
590 "Channel number for diversity routing\n"
591 "Mark channel as interfering\n")
593 VTY_DECLVAR_CONTEXT(interface
, ifp
);
594 babel_interface_nfo
*babel_ifp
;
596 babel_ifp
= babel_get_if_nfo(ifp
);
597 assert (babel_ifp
!= NULL
);
599 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
603 DEFUN (babel_set_channel_noninterfering
,
604 babel_set_channel_noninterfering_cmd
,
605 "babel channel noninterfering",
606 "Babel interface commands\n"
607 "Channel number for diversity routing\n"
608 "Mark channel as noninterfering\n")
610 VTY_DECLVAR_CONTEXT(interface
, ifp
);
611 babel_interface_nfo
*babel_ifp
;
613 babel_ifp
= babel_get_if_nfo(ifp
);
614 assert (babel_ifp
!= NULL
);
616 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
620 /* This should be no more than half the hello interval, so that hellos
621 aren't sent late. The result is in milliseconds. */
623 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
625 unsigned interval
= babel_ifp
->hello_interval
;
627 interval
= MIN(interval
, 100);
629 interval
= MIN(interval
, 4000);
630 return roughly(interval
) / 4;
634 update_jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
636 unsigned interval
= babel_ifp
->hello_interval
;
638 interval
= MIN(interval
, 100);
640 interval
= MIN(interval
, 4000);
641 return roughly(interval
);
644 /* calculate babeld's specific datas of an interface (change when the interface
647 interface_recalculate(struct interface
*ifp
)
649 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
650 unsigned char *tmp
= NULL
;
652 struct ipv6_mreq mreq
;
657 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
658 interface_reset(ifp
);
662 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
664 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
666 /* We need to be able to fit at least two messages into a packet,
667 so MTUs below 116 require lower layer fragmentation. */
668 /* In IPv6, the minimum MTU is 1280, and every host must be able
669 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
671 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
672 mtu
, ifp
->name
, ifp
->ifindex
);
676 /* 4 for Babel header; 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
677 babel_ifp
->bufsize
= mtu
- 4 - 60;
678 tmp
= babel_ifp
->sendbuf
;
679 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
680 if(babel_ifp
->sendbuf
== NULL
) {
681 flog_err(EC_BABEL_MEMORY
, "Couldn't reallocate sendbuf.");
683 babel_ifp
->bufsize
= 0;
688 rc
= resize_receive_buffer(mtu
);
690 zlog_warn("couldn't resize receive buffer for interface %s (%d) (%d bytes).",
691 ifp
->name
, ifp
->ifindex
, mtu
);
693 memset(&mreq
, 0, sizeof(mreq
));
694 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
695 mreq
.ipv6mr_interface
= ifp
->ifindex
;
697 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
698 (char*)&mreq
, sizeof(mreq
));
700 flog_err_sys(EC_LIB_SOCKET
,
701 "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
702 ifp
->name
, safe_strerror(errno
));
703 /* This is probably due to a missing link-local address,
704 so down this interface, and wait until the main loop
705 tries to up it again. */
706 interface_reset(ifp
);
710 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
711 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
713 send_request(ifp
, NULL
, 0);
715 update_interface_metric(ifp
);
717 debugf(BABEL_DEBUG_COMMON
,
718 "Upped interface %s (%s, cost=%d, channel=%d%s).",
720 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
723 babel_ifp
->ipv4
? ", IPv4" : "");
726 send_update(ifp
, 0, NULL
, 0);
731 /* Reset the interface as it was new: it's not removed from the interface list,
732 and may be considered as a upped interface. */
734 interface_reset(struct interface
*ifp
)
737 struct ipv6_mreq mreq
;
738 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
740 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
743 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
744 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
746 flush_interface_routes(ifp
, 0);
747 babel_ifp
->buffered
= 0;
748 babel_ifp
->bufsize
= 0;
749 free(babel_ifp
->sendbuf
);
750 babel_ifp
->num_buffered_updates
= 0;
751 babel_ifp
->update_bufsize
= 0;
752 if(babel_ifp
->buffered_updates
)
753 free(babel_ifp
->buffered_updates
);
754 babel_ifp
->buffered_updates
= NULL
;
755 babel_ifp
->sendbuf
= NULL
;
757 if(ifp
->ifindex
> 0) {
758 memset(&mreq
, 0, sizeof(mreq
));
759 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
760 mreq
.ipv6mr_interface
= ifp
->ifindex
;
761 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
762 (char*)&mreq
, sizeof(mreq
));
764 flog_err_sys(EC_LIB_SOCKET
,
765 "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
766 ifp
->name
, safe_strerror(errno
));
769 update_interface_metric(ifp
);
771 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
773 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
775 babel_ifp
->ipv4
? ", IPv4" : "");
780 /* Send retraction to all, and reset all interfaces statistics. */
782 babel_interface_close_all(void)
784 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
785 struct interface
*ifp
= NULL
;
787 FOR_ALL_INTERFACES(vrf
, ifp
) {
790 send_wildcard_retraction(ifp
);
791 /* Make sure that we expire quickly from our neighbours'
792 association caches. */
793 send_hello_noupdate(ifp
, 10);
795 usleep(roughly(1000));
798 FOR_ALL_INTERFACES(vrf
, ifp
) {
801 /* Make sure they got it. */
802 send_wildcard_retraction(ifp
);
803 send_hello_noupdate(ifp
, 1);
805 usleep(roughly(10000));
807 interface_reset(ifp
);
811 /* return "true" if address is one of our ipv6 addresses */
813 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
815 struct connected
*connected
;
816 struct listnode
*node
;
821 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
822 if (connected
->address
->family
== AF_INET6
823 && memcmp(&connected
->address
->u
.prefix6
, address
,
833 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
836 babel_interface_nfo
*babel_ifp
;
838 vty_out (vty
, "%s is %s\n", ifp
->name
,
839 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
840 vty_out (vty
, " ifindex %u, MTU %u bytes %s\n",
841 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
845 vty_out (vty
, " Babel protocol is not enabled on this interface\n");
851 " Babel protocol is enabled, but not running on this interface\n");
854 babel_ifp
= babel_get_if_nfo (ifp
);
855 vty_out (vty
, " Babel protocol is running on this interface\n");
856 vty_out (vty
, " Operating mode is \"%s\"\n",
857 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
858 vty_out (vty
, " Split horizon mode is %s\n",
859 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
860 vty_out (vty
, " Hello interval is %u ms\n", babel_ifp
->hello_interval
);
861 vty_out (vty
, " Update interval is %u ms\n", babel_ifp
->update_interval
);
862 vty_out (vty
, " Rxcost multiplier is %u\n", babel_ifp
->cost
);
865 DEFUN (show_babel_interface
,
866 show_babel_interface_cmd
,
867 "show babel interface [IFNAME]",
869 "Babel information\n"
870 "Interface information\n"
873 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
874 struct interface
*ifp
;
878 FOR_ALL_INTERFACES (vrf
, ifp
)
879 show_babel_interface_sub (vty
, ifp
);
882 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
884 vty_out (vty
, "No such interface name\n");
887 show_babel_interface_sub (vty
, ifp
);
892 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
895 "Neighbour %s dev %s reach %04x rxcost %d txcost %d rtt %s rttcost %d%s.\n",
896 format_address(neigh
->address
),
899 neighbour_rxcost(neigh
),
901 format_thousands(neigh
->rtt
),
902 neighbour_rttcost(neigh
),
903 if_up(neigh
->ifp
) ? "" : " (down)");
906 DEFUN (show_babel_neighbour
,
907 show_babel_neighbour_cmd
,
908 "show babel neighbor [IFNAME]",
910 "Babel information\n"
914 struct neighbour
*neigh
;
915 struct interface
*ifp
;
918 FOR_ALL_NEIGHBOURS(neigh
) {
919 show_babel_neighbour_sub(vty
, neigh
);
923 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
925 vty_out (vty
, "No such interface name\n");
928 FOR_ALL_NEIGHBOURS(neigh
) {
929 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
930 show_babel_neighbour_sub(vty
, neigh
);
937 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
939 if(prefix
->family
== AF_INET6
) {
940 if (prefix
->prefixlen
!= plen
941 || memcmp(&prefix
->u
.prefix6
, p
, IPV6_MAX_BYTELEN
) != 0)
943 } else if(prefix
->family
== AF_INET
) {
944 if (plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96
945 || memcmp(&prefix
->u
.prefix4
, p
+ 12, IPV4_MAX_BYTELEN
) != 0)
955 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
956 struct prefix
*prefix
)
958 const unsigned char *nexthop
=
959 memcmp(route
->nexthop
, route
->neigh
->address
, IPV6_MAX_BYTELEN
)
966 && !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
969 if (route
->channels
[0] == 0)
973 snprintf(channels
, sizeof(channels
), " chan (");
974 j
= strlen(channels
);
975 for (k
= 0; k
< DIVERSITY_HOPS
; k
++) {
976 if (route
->channels
[k
] == 0)
980 snprintf(channels
+ j
, 100 - j
, "%u",
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 if_cmd_init(interface_config_write
);
1255 install_element(BABEL_NODE
, &babel_network_cmd
);
1256 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1257 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1258 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1259 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1260 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1261 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1262 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1263 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1264 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1265 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1266 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1267 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1268 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1269 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1270 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1271 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1272 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1274 /* "show babel ..." commands */
1275 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1276 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1277 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1278 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1279 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1280 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1281 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1284 /* hooks: functions called respectively when struct interface is
1285 created or deleted. */
1287 babel_if_new_hook (struct interface
*ifp
)
1289 ifp
->info
= babel_interface_allocate();
1294 babel_if_delete_hook (struct interface
*ifp
)
1296 babel_interface_free(ifp
->info
);
1301 /* Output an "interface" section for each of the known interfaces with
1302 babeld-specific statement lines where appropriate. */
1304 interface_config_write (struct vty
*vty
)
1306 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1307 struct interface
*ifp
;
1310 FOR_ALL_INTERFACES (vrf
, ifp
) {
1311 vty_frame (vty
, "interface %s\n",ifp
->name
);
1313 vty_out (vty
, " description %s\n",ifp
->desc
);
1314 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1315 /* wireless is the default*/
1316 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1318 vty_out (vty
, " babel wired\n");
1321 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1323 vty_out (vty
, " babel hello-interval %u\n",
1324 babel_ifp
->hello_interval
);
1327 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1329 vty_out (vty
, " babel update-interval %u\n",
1330 babel_ifp
->update_interval
);
1333 if (CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_TIMESTAMPS
)) {
1334 vty_out(vty
, " babel enable-timestamps\n");
1337 if (babel_ifp
->max_rtt_penalty
!= BABEL_DEFAULT_MAX_RTT_PENALTY
) {
1338 vty_out(vty
, " babel max-rtt-penalty %u\n",
1339 babel_ifp
->max_rtt_penalty
);
1342 if (babel_ifp
->rtt_decay
!= BABEL_DEFAULT_RTT_DECAY
) {
1343 vty_out(vty
, " babel rtt-decay %u\n", babel_ifp
->rtt_decay
);
1346 if (babel_ifp
->rtt_min
!= BABEL_DEFAULT_RTT_MIN
) {
1347 vty_out(vty
, " babel rtt-min %u\n", babel_ifp
->rtt_min
/ 1000);
1350 if (babel_ifp
->rtt_max
!= BABEL_DEFAULT_RTT_MAX
) {
1351 vty_out(vty
, " babel rtt-max %u\n", babel_ifp
->rtt_max
/ 1000);
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
, "exit\n!\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
= (frr_weak_random() & 0xFFFF);
1421 babel_ifp
->rtt_decay
= BABEL_DEFAULT_RTT_DECAY
;
1422 babel_ifp
->rtt_min
= BABEL_DEFAULT_RTT_MIN
;
1423 babel_ifp
->rtt_max
= BABEL_DEFAULT_RTT_MAX
;
1424 babel_ifp
->max_rtt_penalty
= BABEL_DEFAULT_MAX_RTT_PENALTY
;
1425 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1426 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1427 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1428 babel_set_wired_internal(babel_ifp
, 0);
1434 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1436 XFREE(MTYPE_BABEL_IF
, babel_ifp
);