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). */
63 int babel_ifp_up(struct interface
*ifp
)
65 debugf(BABEL_DEBUG_IF
, "receive a 'interface up'");
67 interface_recalculate(ifp
);
72 babel_ifp_down(struct interface
*ifp
)
74 debugf(BABEL_DEBUG_IF
, "receive a 'interface down'");
84 int babel_ifp_create (struct interface
*ifp
)
86 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
88 interface_recalculate(ifp
);
94 babel_ifp_destroy(struct interface
*ifp
)
96 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
105 babel_interface_address_add (ZAPI_CALLBACK_ARGS
)
107 babel_interface_nfo
*babel_ifp
;
108 struct connected
*ifc
;
109 struct prefix
*prefix
;
111 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
113 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
114 zclient
->ibuf
, vrf_id
);
119 prefix
= ifc
->address
;
121 if (prefix
->family
== AF_INET
) {
122 flush_interface_routes(ifc
->ifp
, 0);
123 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
124 if (babel_ifp
->ipv4
== NULL
) {
125 babel_ifp
->ipv4
= malloc(4);
126 if (babel_ifp
->ipv4
== NULL
) {
127 flog_err(EC_BABEL_MEMORY
, "not enough memory");
129 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
134 send_request(ifc
->ifp
, NULL
, 0);
135 send_update(ifc
->ifp
, 0, NULL
, 0);
141 babel_interface_address_delete (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 delete'");
149 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE
,
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 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, IPV4_MAX_BYTELEN
)
163 free(babel_ifp
->ipv4
);
164 babel_ifp
->ipv4
= NULL
;
168 send_request(ifc
->ifp
, NULL
, 0);
169 send_update(ifc
->ifp
, 0, NULL
, 0);
171 connected_free(&ifc
);
175 /* Lookup function. */
177 babel_enable_if_lookup (const char *ifname
)
182 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
183 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
184 if (strcmp (str
, ifname
) == 0)
189 /* Add interface to babel_enable_if. */
191 babel_enable_if_add (const char *ifname
)
194 struct interface
*ifp
= NULL
;
196 ret
= babel_enable_if_lookup (ifname
);
200 vector_set (babel_enable_if
, strdup (ifname
));
202 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
204 interface_recalculate(ifp
);
209 /* Delete interface from babel_enable_if. */
211 babel_enable_if_delete (const char *ifname
)
213 int babel_enable_if_index
;
215 struct interface
*ifp
= NULL
;
217 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
218 if (babel_enable_if_index
< 0)
221 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
223 vector_unset (babel_enable_if
, babel_enable_if_index
);
225 ifp
= if_lookup_by_name(ifname
, VRF_DEFAULT
);
227 interface_reset(ifp
);
232 /* [Babel Command] Babel enable on specified interface or matched network. */
233 DEFUN (babel_network
,
235 "network IF_OR_ADDR",
236 "Enable Babel protocol on specified interface or network.\n"
237 "Interface or address\n")
242 ret
= str2prefix (argv
[1]->arg
, &p
);
244 /* Given string is: */
245 if (ret
) /* an IPv4 or v6 network */
246 return CMD_ERR_NO_MATCH
; /* not implemented yet */
247 else /* an interface name */
248 ret
= babel_enable_if_add (argv
[1]->arg
);
251 vty_out (vty
, "There is same network configuration %s\n",
259 /* [Babel Command] Babel enable on specified interface or matched network. */
260 DEFUN (no_babel_network
,
261 no_babel_network_cmd
,
262 "no network IF_OR_ADDR",
264 "Disable Babel protocol on specified interface or network.\n"
265 "Interface or address\n")
270 ret
= str2prefix (argv
[2]->arg
, &p
);
272 /* Given string is: */
273 if (ret
) /* an IPv4 or v6 network */
274 return CMD_ERR_NO_MATCH
; /* not implemented yet */
275 else /* an interface name */
276 ret
= babel_enable_if_delete (argv
[2]->arg
);
279 vty_out (vty
, "can't find network %s\n",argv
[2]->arg
);
280 return CMD_WARNING_CONFIG_FAILED
;
286 /* There are a number of interface parameters that must be changed when
287 an interface becomes wired/wireless. In Quagga, they cannot be
288 configured separately. */
291 babel_set_wired_internal(babel_interface_nfo
*babel_ifp
, int wired
)
294 babel_ifp
->flags
|= BABEL_IF_WIRED
;
295 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
296 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRED
;
297 babel_ifp
->channel
= BABEL_IF_CHANNEL_NONINTERFERING
;
298 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
300 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
301 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
302 babel_ifp
->cost
= BABEL_DEFAULT_RXCOST_WIRELESS
;
303 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
304 babel_ifp
->flags
|= BABEL_IF_LQ
;
309 /* [Interface Command] Tell the interface is wire. */
310 DEFUN (babel_set_wired
,
313 "Babel interface commands\n"
314 "Enable wired optimizations\n")
316 VTY_DECLVAR_CONTEXT(interface
, ifp
);
317 babel_interface_nfo
*babel_ifp
;
319 babel_ifp
= babel_get_if_nfo(ifp
);
321 assert (babel_ifp
!= NULL
);
322 babel_set_wired_internal(babel_ifp
, 1);
326 /* [Interface Command] Tell the interface is wireless (default). */
327 DEFUN (babel_set_wireless
,
328 babel_set_wireless_cmd
,
330 "Babel interface commands\n"
331 "Disable wired optimizations (assume wireless)\n")
333 VTY_DECLVAR_CONTEXT(interface
, ifp
);
334 babel_interface_nfo
*babel_ifp
;
336 babel_ifp
= babel_get_if_nfo(ifp
);
338 assert (babel_ifp
!= NULL
);
339 babel_set_wired_internal(babel_ifp
, 0);
343 /* [Interface Command] Enable split horizon. */
344 DEFUN (babel_split_horizon
,
345 babel_split_horizon_cmd
,
346 "babel split-horizon",
347 "Babel interface commands\n"
348 "Enable split horizon processing\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_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
360 /* [Interface Command] Disable split horizon (default). */
361 DEFUN (no_babel_split_horizon
,
362 no_babel_split_horizon_cmd
,
363 "no babel split-horizon",
365 "Babel interface commands\n"
366 "Disable split horizon processing\n")
368 VTY_DECLVAR_CONTEXT(interface
, ifp
);
369 babel_interface_nfo
*babel_ifp
;
371 babel_ifp
= babel_get_if_nfo(ifp
);
373 assert (babel_ifp
!= NULL
);
374 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
378 /* [Interface Command]. */
379 DEFUN (babel_set_hello_interval
,
380 babel_set_hello_interval_cmd
,
381 "babel hello-interval (20-655340)",
382 "Babel interface commands\n"
383 "Time between scheduled hellos\n"
386 VTY_DECLVAR_CONTEXT(interface
, ifp
);
387 babel_interface_nfo
*babel_ifp
;
390 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
392 babel_ifp
= babel_get_if_nfo(ifp
);
393 assert (babel_ifp
!= NULL
);
395 babel_ifp
->hello_interval
= interval
;
399 /* [Interface Command]. */
400 DEFUN (babel_set_update_interval
,
401 babel_set_update_interval_cmd
,
402 "babel update-interval (20-655340)",
403 "Babel interface commands\n"
404 "Time between scheduled updates\n"
407 VTY_DECLVAR_CONTEXT(interface
, ifp
);
408 babel_interface_nfo
*babel_ifp
;
411 interval
= strtoul(argv
[2]->arg
, NULL
, 10);
413 babel_ifp
= babel_get_if_nfo(ifp
);
414 assert (babel_ifp
!= NULL
);
416 babel_ifp
->update_interval
= interval
;
420 DEFUN (babel_set_rxcost
,
421 babel_set_rxcost_cmd
,
422 "babel rxcost (1-65534)",
423 "Babel interface commands\n"
424 "Rxcost multiplier\n"
427 VTY_DECLVAR_CONTEXT(interface
, ifp
);
428 babel_interface_nfo
*babel_ifp
;
431 rxcost
= strtoul(argv
[2]->arg
, NULL
, 10);
433 babel_ifp
= babel_get_if_nfo(ifp
);
434 assert (babel_ifp
!= NULL
);
436 babel_ifp
->cost
= rxcost
;
440 DEFUN (babel_set_rtt_decay
,
441 babel_set_rtt_decay_cmd
,
442 "babel rtt-decay (1-256)",
443 "Babel interface commands\n"
444 "Decay factor for exponential moving average of RTT samples\n"
447 VTY_DECLVAR_CONTEXT(interface
, ifp
);
448 babel_interface_nfo
*babel_ifp
;
451 decay
= strtoul(argv
[2]->arg
, NULL
, 10);
453 babel_ifp
= babel_get_if_nfo(ifp
);
454 assert (babel_ifp
!= NULL
);
456 babel_ifp
->rtt_decay
= decay
;
460 DEFUN (babel_set_rtt_min
,
461 babel_set_rtt_min_cmd
,
462 "babel rtt-min (1-65535)",
463 "Babel interface commands\n"
464 "Minimum RTT starting for increasing cost\n"
467 VTY_DECLVAR_CONTEXT(interface
, ifp
);
468 babel_interface_nfo
*babel_ifp
;
471 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
473 babel_ifp
= babel_get_if_nfo(ifp
);
474 assert (babel_ifp
!= NULL
);
476 /* The value is entered in milliseconds but stored as microseconds. */
477 babel_ifp
->rtt_min
= rtt
* 1000;
481 DEFUN (babel_set_rtt_max
,
482 babel_set_rtt_max_cmd
,
483 "babel rtt-max (1-65535)",
484 "Babel interface commands\n"
488 VTY_DECLVAR_CONTEXT(interface
, ifp
);
489 babel_interface_nfo
*babel_ifp
;
492 rtt
= strtoul(argv
[2]->arg
, NULL
, 10);
494 babel_ifp
= babel_get_if_nfo(ifp
);
495 assert (babel_ifp
!= NULL
);
497 /* The value is entered in milliseconds but stored as microseconds. */
498 babel_ifp
->rtt_max
= rtt
* 1000;
502 DEFUN (babel_set_max_rtt_penalty
,
503 babel_set_max_rtt_penalty_cmd
,
504 "babel max-rtt-penalty (0-65535)",
505 "Babel interface commands\n"
506 "Maximum additional cost due to RTT\n"
509 VTY_DECLVAR_CONTEXT(interface
, ifp
);
510 babel_interface_nfo
*babel_ifp
;
513 penalty
= strtoul(argv
[2]->arg
, NULL
, 10);
515 babel_ifp
= babel_get_if_nfo(ifp
);
516 assert (babel_ifp
!= NULL
);
518 babel_ifp
->max_rtt_penalty
= penalty
;
522 DEFUN (babel_set_enable_timestamps
,
523 babel_set_enable_timestamps_cmd
,
524 "babel enable-timestamps",
525 "Babel interface commands\n"
526 "Enable timestamps\n")
528 VTY_DECLVAR_CONTEXT(interface
, ifp
);
529 babel_interface_nfo
*babel_ifp
;
531 babel_ifp
= babel_get_if_nfo(ifp
);
532 assert (babel_ifp
!= NULL
);
534 babel_ifp
->flags
|= BABEL_IF_TIMESTAMPS
;
538 DEFUN (no_babel_set_enable_timestamps
,
539 no_babel_set_enable_timestamps_cmd
,
540 "no babel enable-timestamps",
542 "Babel interface commands\n"
543 "Disable 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 (babel_set_channel
,
556 babel_set_channel_cmd
,
557 "babel channel (1-254)",
558 "Babel interface commands\n"
559 "Channel number for diversity routing\n"
562 VTY_DECLVAR_CONTEXT(interface
, ifp
);
563 babel_interface_nfo
*babel_ifp
;
566 channel
= strtoul(argv
[2]->arg
, NULL
, 10);
568 babel_ifp
= babel_get_if_nfo(ifp
);
569 assert (babel_ifp
!= NULL
);
571 babel_ifp
->channel
= channel
;
575 DEFUN (babel_set_channel_interfering
,
576 babel_set_channel_interfering_cmd
,
577 "babel channel interfering",
578 "Babel interface commands\n"
579 "Channel number for diversity routing\n"
580 "Mark channel as interfering\n")
582 VTY_DECLVAR_CONTEXT(interface
, ifp
);
583 babel_interface_nfo
*babel_ifp
;
585 babel_ifp
= babel_get_if_nfo(ifp
);
586 assert (babel_ifp
!= NULL
);
588 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
592 DEFUN (babel_set_channel_noninterfering
,
593 babel_set_channel_noninterfering_cmd
,
594 "babel channel noninterfering",
595 "Babel interface commands\n"
596 "Channel number for diversity routing\n"
597 "Mark channel as noninterfering\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_NONINTERFERING
;
609 /* This should be no more than half the hello interval, so that hellos
610 aren't sent late. The result is in milliseconds. */
612 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
614 unsigned interval
= babel_ifp
->hello_interval
;
616 interval
= MIN(interval
, 100);
618 interval
= MIN(interval
, 4000);
619 return roughly(interval
) / 4;
623 update_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
);
633 /* calculate babeld's specific datas of an interface (change when the interface
636 interface_recalculate(struct interface
*ifp
)
638 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
639 unsigned char *tmp
= NULL
;
641 struct ipv6_mreq mreq
;
646 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
647 interface_reset(ifp
);
651 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
653 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
655 /* We need to be able to fit at least two messages into a packet,
656 so MTUs below 116 require lower layer fragmentation. */
657 /* In IPv6, the minimum MTU is 1280, and every host must be able
658 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
660 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
661 mtu
, ifp
->name
, ifp
->ifindex
);
665 /* 4 for Babel header; 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
666 babel_ifp
->bufsize
= mtu
- 4 - 60;
667 tmp
= babel_ifp
->sendbuf
;
668 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
669 if(babel_ifp
->sendbuf
== NULL
) {
670 flog_err(EC_BABEL_MEMORY
, "Couldn't reallocate sendbuf.");
672 babel_ifp
->bufsize
= 0;
677 rc
= resize_receive_buffer(mtu
);
679 zlog_warn("couldn't resize receive buffer for interface %s (%d) (%d bytes).",
680 ifp
->name
, ifp
->ifindex
, mtu
);
682 memset(&mreq
, 0, sizeof(mreq
));
683 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
684 mreq
.ipv6mr_interface
= ifp
->ifindex
;
686 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
687 (char*)&mreq
, sizeof(mreq
));
689 flog_err_sys(EC_LIB_SOCKET
,
690 "setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
691 ifp
->name
, safe_strerror(errno
));
692 /* This is probably due to a missing link-local address,
693 so down this interface, and wait until the main loop
694 tries to up it again. */
695 interface_reset(ifp
);
699 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
700 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
702 send_request(ifp
, NULL
, 0);
704 update_interface_metric(ifp
);
706 debugf(BABEL_DEBUG_COMMON
,
707 "Upped interface %s (%s, cost=%d, channel=%d%s).",
709 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
712 babel_ifp
->ipv4
? ", IPv4" : "");
715 send_update(ifp
, 0, NULL
, 0);
720 /* Reset the interface as it was new: it's not removed from the interface list,
721 and may be considered as a upped interface. */
723 interface_reset(struct interface
*ifp
)
726 struct ipv6_mreq mreq
;
727 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
729 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
732 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
733 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
735 flush_interface_routes(ifp
, 0);
736 babel_ifp
->buffered
= 0;
737 babel_ifp
->bufsize
= 0;
738 free(babel_ifp
->sendbuf
);
739 babel_ifp
->num_buffered_updates
= 0;
740 babel_ifp
->update_bufsize
= 0;
741 if(babel_ifp
->buffered_updates
)
742 free(babel_ifp
->buffered_updates
);
743 babel_ifp
->buffered_updates
= NULL
;
744 babel_ifp
->sendbuf
= NULL
;
746 if(ifp
->ifindex
> 0) {
747 memset(&mreq
, 0, sizeof(mreq
));
748 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
749 mreq
.ipv6mr_interface
= ifp
->ifindex
;
750 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
751 (char*)&mreq
, sizeof(mreq
));
753 flog_err_sys(EC_LIB_SOCKET
,
754 "setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
755 ifp
->name
, safe_strerror(errno
));
758 update_interface_metric(ifp
);
760 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
762 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
764 babel_ifp
->ipv4
? ", IPv4" : "");
769 /* Send retraction to all, and reset all interfaces statistics. */
771 babel_interface_close_all(void)
773 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
774 struct interface
*ifp
= NULL
;
776 FOR_ALL_INTERFACES(vrf
, ifp
) {
779 send_wildcard_retraction(ifp
);
780 /* Make sure that we expire quickly from our neighbours'
781 association caches. */
782 send_hello_noupdate(ifp
, 10);
784 usleep(roughly(1000));
787 FOR_ALL_INTERFACES(vrf
, ifp
) {
790 /* Make sure they got it. */
791 send_wildcard_retraction(ifp
);
792 send_hello_noupdate(ifp
, 1);
794 usleep(roughly(10000));
796 interface_reset(ifp
);
800 /* return "true" if address is one of our ipv6 addresses */
802 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
804 struct connected
*connected
;
805 struct listnode
*node
;
810 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
811 if (connected
->address
->family
== AF_INET6
812 && memcmp(&connected
->address
->u
.prefix6
, address
,
822 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
825 babel_interface_nfo
*babel_ifp
;
827 vty_out (vty
, "%s is %s\n", ifp
->name
,
828 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"));
829 vty_out (vty
, " ifindex %u, MTU %u bytes %s\n",
830 ifp
->ifindex
, MIN(ifp
->mtu
, ifp
->mtu6
), if_flag_dump(ifp
->flags
));
834 vty_out (vty
, " Babel protocol is not enabled on this interface\n");
840 " Babel protocol is enabled, but not running on this interface\n");
843 babel_ifp
= babel_get_if_nfo (ifp
);
844 vty_out (vty
, " Babel protocol is running on this interface\n");
845 vty_out (vty
, " Operating mode is \"%s\"\n",
846 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless");
847 vty_out (vty
, " Split horizon mode is %s\n",
848 CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off");
849 vty_out (vty
, " Hello interval is %u ms\n", babel_ifp
->hello_interval
);
850 vty_out (vty
, " Update interval is %u ms\n", babel_ifp
->update_interval
);
851 vty_out (vty
, " Rxcost multiplier is %u\n", babel_ifp
->cost
);
854 DEFUN (show_babel_interface
,
855 show_babel_interface_cmd
,
856 "show babel interface [IFNAME]",
858 "Babel information\n"
859 "Interface information\n"
862 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
863 struct interface
*ifp
;
867 FOR_ALL_INTERFACES (vrf
, ifp
)
868 show_babel_interface_sub (vty
, ifp
);
871 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
873 vty_out (vty
, "No such interface name\n");
876 show_babel_interface_sub (vty
, ifp
);
881 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
884 "Neighbour %s dev %s reach %04x rxcost %d txcost %d rtt %s rttcost %d%s.\n",
885 format_address(neigh
->address
),
888 neighbour_rxcost(neigh
),
890 format_thousands(neigh
->rtt
),
891 neighbour_rttcost(neigh
),
892 if_up(neigh
->ifp
) ? "" : " (down)");
895 DEFUN (show_babel_neighbour
,
896 show_babel_neighbour_cmd
,
897 "show babel neighbor [IFNAME]",
899 "Babel information\n"
903 struct neighbour
*neigh
;
904 struct interface
*ifp
;
907 FOR_ALL_NEIGHBOURS(neigh
) {
908 show_babel_neighbour_sub(vty
, neigh
);
912 if ((ifp
= if_lookup_by_name (argv
[3]->arg
, VRF_DEFAULT
)) == NULL
)
914 vty_out (vty
, "No such interface name\n");
917 FOR_ALL_NEIGHBOURS(neigh
) {
918 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
919 show_babel_neighbour_sub(vty
, neigh
);
926 babel_prefix_eq(struct prefix
*prefix
, unsigned char *p
, int plen
)
928 if(prefix
->family
== AF_INET6
) {
929 if (prefix
->prefixlen
!= plen
930 || memcmp(&prefix
->u
.prefix6
, p
, IPV6_MAX_BYTELEN
) != 0)
932 } else if(prefix
->family
== AF_INET
) {
933 if (plen
< 96 || !v4mapped(p
) || prefix
->prefixlen
!= plen
- 96
934 || memcmp(&prefix
->u
.prefix4
, p
+ 12, IPV4_MAX_BYTELEN
) != 0)
944 show_babel_routes_sub(struct babel_route
*route
, struct vty
*vty
,
945 struct prefix
*prefix
)
947 const unsigned char *nexthop
=
948 memcmp(route
->nexthop
, route
->neigh
->address
, IPV6_MAX_BYTELEN
)
955 && !babel_prefix_eq(prefix
, route
->src
->prefix
, route
->src
->plen
))
958 if (route
->channels
[0] == 0)
962 snprintf(channels
, sizeof(channels
), " chan (");
963 j
= strlen(channels
);
964 for (k
= 0; k
< DIVERSITY_HOPS
; k
++) {
965 if (route
->channels
[k
] == 0)
969 snprintf(channels
+ j
, 100 - j
, "%u",
971 j
= strlen(channels
);
973 snprintf(channels
+ j
, 100 - j
, ")");
979 "%s metric %d refmetric %d id %s seqno %d%s age %d via %s neigh %s%s%s%s\n",
980 format_prefix(route
->src
->prefix
, route
->src
->plen
),
981 route_metric(route
), route
->refmetric
,
982 format_eui64(route
->src
->id
),
985 (int)(babel_now
.tv_sec
- route
->time
),
986 route
->neigh
->ifp
->name
,
987 format_address(route
->neigh
->address
),
988 nexthop
? " nexthop " : "",
989 nexthop
? format_address(nexthop
) : "",
990 route
->installed
? " (installed)" : route_feasible(route
) ? " (feasible)" : "");
994 show_babel_xroutes_sub (struct xroute
*xroute
, struct vty
*vty
,
995 struct prefix
*prefix
)
997 if(prefix
&& !babel_prefix_eq(prefix
, xroute
->prefix
, xroute
->plen
))
1000 vty_out (vty
, "%s metric %d (exported)\n",
1001 format_prefix(xroute
->prefix
, xroute
->plen
),
1005 DEFUN (show_babel_route
,
1006 show_babel_route_cmd
,
1009 "Babel information\n"
1010 "Babel internal routing table\n")
1012 struct route_stream
*routes
= NULL
;
1013 struct xroute_stream
*xroutes
= NULL
;
1014 routes
= route_stream(0);
1017 struct babel_route
*route
= route_stream_next(routes
);
1020 show_babel_routes_sub(route
, vty
, NULL
);
1022 route_stream_done(routes
);
1024 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1026 xroutes
= xroute_stream();
1029 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1032 show_babel_xroutes_sub(xroute
, vty
, NULL
);
1034 xroute_stream_done(xroutes
);
1036 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1041 DEFUN (show_babel_route_prefix
,
1042 show_babel_route_prefix_cmd
,
1043 "show babel route <A.B.C.D/M|X:X::X:X/M>",
1045 "Babel information\n"
1046 "Babel internal routing table\n"
1047 "IPv4 prefix <network>/<length>\n"
1048 "IPv6 prefix <network>/<length>\n")
1050 struct route_stream
*routes
= NULL
;
1051 struct xroute_stream
*xroutes
= NULL
;
1052 struct prefix prefix
;
1055 ret
= str2prefix(argv
[3]->arg
, &prefix
);
1057 vty_out (vty
, "%% Malformed address\n");
1061 routes
= route_stream(0);
1064 struct babel_route
*route
= route_stream_next(routes
);
1067 show_babel_routes_sub(route
, vty
, &prefix
);
1069 route_stream_done(routes
);
1071 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1073 xroutes
= xroute_stream();
1076 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1079 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1081 xroute_stream_done(xroutes
);
1083 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1089 DEFUN (show_babel_route_addr
,
1090 show_babel_route_addr_cmd
,
1091 "show babel route A.B.C.D",
1093 "Babel information\n"
1094 "Babel internal routing table\n"
1095 "IPv4 address <network>/<length>\n")
1097 struct in_addr addr
;
1098 char buf
[INET_ADDRSTRLEN
+ 8];
1099 char buf1
[INET_ADDRSTRLEN
+ 8];
1100 struct route_stream
*routes
= NULL
;
1101 struct xroute_stream
*xroutes
= NULL
;
1102 struct prefix prefix
;
1105 ret
= inet_aton (argv
[3]->arg
, &addr
);
1107 vty_out (vty
, "%% Malformed address\n");
1111 /* Quagga has no convenient prefix constructors. */
1112 snprintf(buf
, sizeof(buf
), "%s/%d",
1113 inet_ntop(AF_INET
, &addr
, buf1
, sizeof(buf1
)), 32);
1115 ret
= str2prefix(buf
, &prefix
);
1117 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1121 routes
= route_stream(0);
1124 struct babel_route
*route
= route_stream_next(routes
);
1127 show_babel_routes_sub(route
, vty
, &prefix
);
1129 route_stream_done(routes
);
1131 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1133 xroutes
= xroute_stream();
1136 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1139 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1141 xroute_stream_done(xroutes
);
1143 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1148 DEFUN (show_babel_route_addr6
,
1149 show_babel_route_addr6_cmd
,
1150 "show babel route X:X::X:X",
1152 "Babel information\n"
1153 "Babel internal routing table\n"
1154 "IPv6 address <network>/<length>\n")
1156 struct in6_addr addr
;
1157 char buf1
[INET6_ADDRSTRLEN
];
1158 char buf
[INET6_ADDRSTRLEN
+ 8];
1159 struct route_stream
*routes
= NULL
;
1160 struct xroute_stream
*xroutes
= NULL
;
1161 struct prefix prefix
;
1164 ret
= inet_pton (AF_INET6
, argv
[3]->arg
, &addr
);
1166 vty_out (vty
, "%% Malformed address\n");
1170 /* Quagga has no convenient prefix constructors. */
1171 snprintf(buf
, sizeof(buf
), "%s/%d",
1172 inet_ntop(AF_INET6
, &addr
, buf1
, sizeof(buf1
)), 128);
1174 ret
= str2prefix(buf
, &prefix
);
1176 vty_out (vty
, "%% Parse error -- this shouldn't happen\n");
1180 routes
= route_stream(0);
1183 struct babel_route
*route
= route_stream_next(routes
);
1186 show_babel_routes_sub(route
, vty
, &prefix
);
1188 route_stream_done(routes
);
1190 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1192 xroutes
= xroute_stream();
1195 struct xroute
*xroute
= xroute_stream_next(xroutes
);
1198 show_babel_xroutes_sub(xroute
, vty
, &prefix
);
1200 xroute_stream_done(xroutes
);
1202 flog_err(EC_BABEL_MEMORY
, "Couldn't allocate route stream.");
1207 DEFUN (show_babel_parameters
,
1208 show_babel_parameters_cmd
,
1209 "show babel parameters",
1211 "Babel information\n"
1212 "Configuration information\n")
1214 struct babel
*babel_ctx
;
1216 vty_out (vty
, " -- Babel running configuration --\n");
1217 show_babel_main_configuration(vty
);
1219 babel_ctx
= babel_lookup();
1221 vty_out (vty
, " -- distribution lists --\n");
1222 config_show_distribute(vty
, babel_ctx
->distribute_ctx
);
1230 /* initialize interface list */
1231 hook_register_prio(if_add
, 0, babel_if_new_hook
);
1232 hook_register_prio(if_del
, 0, babel_if_delete_hook
);
1234 babel_enable_if
= vector_init (1);
1236 /* install interface node and commands */
1237 if_cmd_init(interface_config_write
);
1239 install_element(BABEL_NODE
, &babel_network_cmd
);
1240 install_element(BABEL_NODE
, &no_babel_network_cmd
);
1241 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
1242 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
1243 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
1244 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
1245 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
1246 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
1247 install_element(INTERFACE_NODE
, &babel_set_rxcost_cmd
);
1248 install_element(INTERFACE_NODE
, &babel_set_channel_cmd
);
1249 install_element(INTERFACE_NODE
, &babel_set_rtt_decay_cmd
);
1250 install_element(INTERFACE_NODE
, &babel_set_rtt_min_cmd
);
1251 install_element(INTERFACE_NODE
, &babel_set_rtt_max_cmd
);
1252 install_element(INTERFACE_NODE
, &babel_set_max_rtt_penalty_cmd
);
1253 install_element(INTERFACE_NODE
, &babel_set_enable_timestamps_cmd
);
1254 install_element(INTERFACE_NODE
, &no_babel_set_enable_timestamps_cmd
);
1255 install_element(INTERFACE_NODE
, &babel_set_channel_interfering_cmd
);
1256 install_element(INTERFACE_NODE
, &babel_set_channel_noninterfering_cmd
);
1258 /* "show babel ..." commands */
1259 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
1260 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
1261 install_element(VIEW_NODE
, &show_babel_route_cmd
);
1262 install_element(VIEW_NODE
, &show_babel_route_prefix_cmd
);
1263 install_element(VIEW_NODE
, &show_babel_route_addr_cmd
);
1264 install_element(VIEW_NODE
, &show_babel_route_addr6_cmd
);
1265 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
1268 /* hooks: functions called respectively when struct interface is
1269 created or deleted. */
1271 babel_if_new_hook (struct interface
*ifp
)
1273 ifp
->info
= babel_interface_allocate();
1278 babel_if_delete_hook (struct interface
*ifp
)
1280 babel_interface_free(ifp
->info
);
1285 /* Output an "interface" section for each of the known interfaces with
1286 babeld-specific statement lines where appropriate. */
1288 interface_config_write (struct vty
*vty
)
1290 struct vrf
*vrf
= vrf_lookup_by_id(VRF_DEFAULT
);
1291 struct interface
*ifp
;
1294 FOR_ALL_INTERFACES (vrf
, ifp
) {
1295 if_vty_config_start(vty
, ifp
);
1297 vty_out (vty
, " description %s\n",ifp
->desc
);
1298 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo (ifp
);
1299 /* wireless is the default*/
1300 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
))
1302 vty_out (vty
, " babel wired\n");
1305 if (babel_ifp
->hello_interval
!= BABEL_DEFAULT_HELLO_INTERVAL
)
1307 vty_out (vty
, " babel hello-interval %u\n",
1308 babel_ifp
->hello_interval
);
1311 if (babel_ifp
->update_interval
!= BABEL_DEFAULT_UPDATE_INTERVAL
)
1313 vty_out (vty
, " babel update-interval %u\n",
1314 babel_ifp
->update_interval
);
1317 if (CHECK_FLAG(babel_ifp
->flags
, BABEL_IF_TIMESTAMPS
)) {
1318 vty_out(vty
, " babel enable-timestamps\n");
1321 if (babel_ifp
->max_rtt_penalty
!= BABEL_DEFAULT_MAX_RTT_PENALTY
) {
1322 vty_out(vty
, " babel max-rtt-penalty %u\n",
1323 babel_ifp
->max_rtt_penalty
);
1326 if (babel_ifp
->rtt_decay
!= BABEL_DEFAULT_RTT_DECAY
) {
1327 vty_out(vty
, " babel rtt-decay %u\n", babel_ifp
->rtt_decay
);
1330 if (babel_ifp
->rtt_min
!= BABEL_DEFAULT_RTT_MIN
) {
1331 vty_out(vty
, " babel rtt-min %u\n", babel_ifp
->rtt_min
/ 1000);
1334 if (babel_ifp
->rtt_max
!= BABEL_DEFAULT_RTT_MAX
) {
1335 vty_out(vty
, " babel rtt-max %u\n", babel_ifp
->rtt_max
/ 1000);
1338 /* Some parameters have different defaults for wired/wireless. */
1339 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
)) {
1340 if (!CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1341 vty_out (vty
, " no babel split-horizon\n");
1344 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRED
) {
1345 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1348 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_INTERFERING
) {
1349 vty_out (vty
, " babel channel interfering\n");
1351 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_NONINTERFERING
) {
1352 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1356 if (CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
)) {
1357 vty_out (vty
, " babel split-horizon\n");
1360 if (babel_ifp
->cost
!= BABEL_DEFAULT_RXCOST_WIRELESS
) {
1361 vty_out (vty
, " babel rxcost %u\n", babel_ifp
->cost
);
1364 if (babel_ifp
->channel
== BABEL_IF_CHANNEL_NONINTERFERING
) {
1365 vty_out (vty
, " babel channel noninterfering\n");
1367 } else if(babel_ifp
->channel
!= BABEL_IF_CHANNEL_INTERFERING
) {
1368 vty_out (vty
, " babel channel %d\n",babel_ifp
->channel
);
1372 if_vty_config_end(vty
);
1378 /* Output a "network" statement line for each of the enabled interfaces. */
1380 babel_enable_if_config_write (struct vty
* vty
)
1382 unsigned int i
, lines
= 0;
1385 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
1386 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
1388 vty_out (vty
, " network %s\n", str
);
1394 /* functions to allocate or free memory for a babel_interface_nfo, filling
1396 static babel_interface_nfo
*
1397 babel_interface_allocate (void)
1399 babel_interface_nfo
*babel_ifp
;
1400 babel_ifp
= XCALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1401 /* All flags are unset */
1402 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1403 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1404 babel_ifp
->hello_seqno
= (frr_weak_random() & 0xFFFF);
1405 babel_ifp
->rtt_decay
= BABEL_DEFAULT_RTT_DECAY
;
1406 babel_ifp
->rtt_min
= BABEL_DEFAULT_RTT_MIN
;
1407 babel_ifp
->rtt_max
= BABEL_DEFAULT_RTT_MAX
;
1408 babel_ifp
->max_rtt_penalty
= BABEL_DEFAULT_MAX_RTT_PENALTY
;
1409 babel_ifp
->hello_interval
= BABEL_DEFAULT_HELLO_INTERVAL
;
1410 babel_ifp
->update_interval
= BABEL_DEFAULT_UPDATE_INTERVAL
;
1411 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1412 babel_set_wired_internal(babel_ifp
, 0);
1418 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1420 XFREE(MTYPE_BABEL_IF
, babel_ifp
);