2 * This file is free software: you may copy, redistribute and/or modify it
3 * under the terms of the GNU General Public License as published by the
4 * Free Software Foundation, either version 2 of the License, or (at your
5 * option) any later version.
7 * This file is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 * This file incorporates work covered by the following copyright and
19 Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
21 Permission is hereby granted, free of charge, to any person obtaining a copy
22 of this software and associated documentation files (the "Software"), to deal
23 in the Software without restriction, including without limitation the rights
24 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25 copies of the Software, and to permit persons to whom the Software is
26 furnished to do so, subject to the following conditions:
28 The above copyright notice and this permission notice shall be included in
29 all copies or substantial portions of the Software.
31 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46 #include "distribute.h"
48 #include "babel_main.h"
51 #include "babel_interface.h"
54 #include "babel_zebra.h"
55 #include "neighbour.h"
60 #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0)
62 static int babel_enable_if_lookup (const char *ifname
);
63 static int babel_enable_if_add (const char *ifname
);
64 static int babel_enable_if_delete (const char *ifname
);
65 static int interface_recalculate(struct interface
*ifp
);
66 static int interface_reset(struct interface
*ifp
);
67 static int babel_if_new_hook (struct interface
*ifp
);
68 static int babel_if_delete_hook (struct interface
*ifp
);
69 static int interface_config_write (struct vty
*vty
);
70 static babel_interface_nfo
* babel_interface_allocate (void);
71 static void babel_interface_free (babel_interface_nfo
*bi
);
74 static vector babel_enable_if
; /* enable interfaces (by cmd). */
75 static struct cmd_node babel_interface_node
= /* babeld's interface node. */
84 babel_interface_up (int cmd
, struct zclient
*client
, zebra_size_t length
)
86 struct stream
*s
= NULL
;
87 struct interface
*ifp
= NULL
;
89 debugf(BABEL_DEBUG_IF
, "receive a 'interface up'");
92 ifp
= zebra_interface_state_read(s
); /* it updates iflist */
98 interface_recalculate(ifp
);
103 babel_interface_down (int cmd
, struct zclient
*client
, zebra_size_t length
)
105 struct stream
*s
= NULL
;
106 struct interface
*ifp
= NULL
;
108 debugf(BABEL_DEBUG_IF
, "receive a 'interface down'");
111 ifp
= zebra_interface_state_read(s
); /* it updates iflist */
117 interface_reset(ifp
);
122 babel_interface_add (int cmd
, struct zclient
*client
, zebra_size_t length
)
124 struct interface
*ifp
= NULL
;
126 debugf(BABEL_DEBUG_IF
, "receive a 'interface add'");
128 /* read and add the interface in the iflist. */
129 ifp
= zebra_interface_add_read (zclient
->ibuf
);
135 interface_recalculate(ifp
);
140 babel_interface_delete (int cmd
, struct zclient
*client
, zebra_size_t length
)
142 struct interface
*ifp
;
145 debugf(BABEL_DEBUG_IF
, "receive a 'interface delete'");
148 ifp
= zebra_interface_state_read(s
); /* it updates iflist */
154 interface_reset(ifp
);
156 /* To support pseudo interface do not free interface structure. */
157 /* if_delete(ifp); */
158 ifp
->ifindex
= IFINDEX_INTERNAL
;
164 babel_interface_address_add (int cmd
, struct zclient
*client
,
167 babel_interface_nfo
*babel_ifp
;
168 struct connected
*ifc
;
169 struct prefix
*prefix
;
171 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
173 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
179 prefix
= ifc
->address
;
181 if (prefix
->family
== AF_INET
) {
182 flush_interface_routes(ifc
->ifp
, 0);
183 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
184 if (babel_ifp
->ipv4
== NULL
) {
185 babel_ifp
->ipv4
= malloc(4);
186 if (babel_ifp
->ipv4
== NULL
) {
187 zlog_err("not einough memory");
189 memcpy(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4);
194 send_request(ifc
->ifp
, NULL
, 0);
195 send_update(ifc
->ifp
, 0, NULL
, 0);
201 babel_interface_address_delete (int cmd
, struct zclient
*client
,
204 babel_interface_nfo
*babel_ifp
;
205 struct connected
*ifc
;
206 struct prefix
*prefix
;
208 debugf(BABEL_DEBUG_IF
, "receive a 'interface address add'");
210 ifc
= zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD
,
216 prefix
= ifc
->address
;
218 if (prefix
->family
== AF_INET
) {
219 flush_interface_routes(ifc
->ifp
, 0);
220 babel_ifp
= babel_get_if_nfo(ifc
->ifp
);
221 if (babel_ifp
->ipv4
!= NULL
222 && memcmp(babel_ifp
->ipv4
, &prefix
->u
.prefix4
, 4) == 0) {
223 free(babel_ifp
->ipv4
);
224 babel_ifp
->ipv4
= NULL
;
228 send_request(ifc
->ifp
, NULL
, 0);
229 send_update(ifc
->ifp
, 0, NULL
, 0);
234 /* Lookup function. */
236 babel_enable_if_lookup (const char *ifname
)
241 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
242 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
243 if (strcmp (str
, ifname
) == 0)
248 /* Add interface to babel_enable_if. */
250 babel_enable_if_add (const char *ifname
)
253 struct interface
*ifp
= NULL
;
255 ret
= babel_enable_if_lookup (ifname
);
259 vector_set (babel_enable_if
, strdup (ifname
));
261 ifp
= if_lookup_by_name(ifname
);
263 interface_recalculate(ifp
);
268 /* Delete interface from babel_enable_if. */
270 babel_enable_if_delete (const char *ifname
)
272 int babel_enable_if_index
;
274 struct interface
*ifp
= NULL
;
276 babel_enable_if_index
= babel_enable_if_lookup (ifname
);
277 if (babel_enable_if_index
< 0)
280 str
= vector_slot (babel_enable_if
, babel_enable_if_index
);
282 vector_unset (babel_enable_if
, babel_enable_if_index
);
284 ifp
= if_lookup_by_name(ifname
);
286 interface_reset(ifp
);
292 /* [Babel Command] Babel enable on specified interface or matched network. */
293 DEFUN (babel_network
,
295 "network IF_OR_ADDR",
296 "Enable Babel protocol on specified interface or network.\n"
297 "Interface or address")
302 ret
= str2prefix (argv
[0], &p
);
304 /* Given string is: */
305 if (ret
) /* an IPv4 or v6 network */
306 return CMD_ERR_NO_MATCH
; /* not implemented yet */
307 else /* an interface name */
308 ret
= babel_enable_if_add (argv
[0]);
311 vty_out (vty
, "There is same network configuration %s%s", argv
[0],
319 /* [Babel Command] Babel enable on specified interface or matched network. */
320 DEFUN (no_babel_network
,
321 no_babel_network_cmd
,
322 "no network IF_OR_ADDR",
324 "Disable Babel protocol on specified interface or network.\n"
325 "Interface or address")
330 ret
= str2prefix (argv
[0], &p
);
332 /* Given string is: */
333 if (ret
) /* an IPv4 or v6 network */
334 return CMD_ERR_NO_MATCH
; /* not implemented yet */
335 else /* an interface name */
336 ret
= babel_enable_if_delete (argv
[0]);
339 vty_out (vty
, "can't find network %s%s", argv
[0],
347 /* [Interface Command] Tell the interface is wire. */
348 DEFUN (babel_set_wired
,
351 "Babel interface commands\n"
352 "Enable wired optimisations")
354 struct interface
*ifp
;
355 babel_interface_nfo
*babel_ifp
;
358 babel_ifp
= babel_get_if_nfo(ifp
);
360 assert (babel_ifp
!= NULL
);
361 babel_ifp
->flags
|= BABEL_IF_WIRED
;
365 /* [Interface Command] Tell the interface is wireless (default). */
366 DEFUN (babel_set_wireless
,
367 babel_set_wireless_cmd
,
369 "Babel interface commands\n"
370 "Disable wired optimiations (assume wireless)")
372 struct interface
*ifp
;
373 babel_interface_nfo
*babel_ifp
;
376 babel_ifp
= babel_get_if_nfo(ifp
);
378 assert (babel_ifp
!= NULL
);
379 babel_ifp
->flags
&= ~BABEL_IF_WIRED
;
383 /* [Interface Command] Enable split horizon. */
384 DEFUN (babel_split_horizon
,
385 babel_split_horizon_cmd
,
386 "babel split-horizon",
387 "Babel interface commands\n"
388 "Enable split horizon processing")
390 struct interface
*ifp
;
391 babel_interface_nfo
*babel_ifp
;
394 babel_ifp
= babel_get_if_nfo(ifp
);
396 assert (babel_ifp
!= NULL
);
397 babel_ifp
->flags
|= BABEL_IF_SPLIT_HORIZON
;
401 /* [Interface Command] Disable split horizon (default). */
402 DEFUN (no_babel_split_horizon
,
403 no_babel_split_horizon_cmd
,
404 "no babel split-horizon",
406 "Babel interface commands\n"
407 "Disable split horizon processing")
409 struct interface
*ifp
;
410 babel_interface_nfo
*babel_ifp
;
413 babel_ifp
= babel_get_if_nfo(ifp
);
415 assert (babel_ifp
!= NULL
);
416 babel_ifp
->flags
&= ~BABEL_IF_SPLIT_HORIZON
;
420 /* [Interface Command]. */
421 DEFUN (babel_set_hello_interval
,
422 babel_set_hello_interval_cmd
,
423 "babel hello-interval <20-655340>",
424 "Babel interface commands\n"
425 "Time between scheduled hellos\n"
428 struct interface
*ifp
;
429 babel_interface_nfo
*babel_ifp
;
432 VTY_GET_INTEGER_RANGE("milliseconds", interval
, argv
[0], 20, 10 * 0xFFFE);
435 babel_ifp
= babel_get_if_nfo(ifp
);
436 assert (babel_ifp
!= NULL
);
438 babel_ifp
->hello_interval
= interval
;
442 /* [Interface Command]. */
443 DEFUN (babel_set_update_interval
,
444 babel_set_update_interval_cmd
,
445 "babel update-interval <20-655340>",
446 "Babel interface commands\n"
447 "Time between scheduled updates\n"
450 struct interface
*ifp
;
451 babel_interface_nfo
*babel_ifp
;
454 VTY_GET_INTEGER_RANGE("milliseconds", interval
, argv
[0], 20, 10 * 0xFFFE);
457 babel_ifp
= babel_get_if_nfo(ifp
);
458 assert (babel_ifp
!= NULL
);
460 babel_ifp
->update_interval
= interval
;
464 /* [Interface Command]. */
465 DEFUN (babel_passive_interface
,
466 babel_passive_interface_cmd
,
467 "babel passive-interface",
468 "Babel interface commands\n"
469 "Only announce redistributed routes on this interface\n")
471 if (allow_duplicates
) {
478 /* [Interface Command]. */
479 DEFUN (no_babel_passive_interface
,
480 no_babel_passive_interface_cmd
,
481 "no babel passive-interface",
483 "Babel interface commands\n"
484 "Announce all routes on this interface\n")
490 /* This should be no more than half the hello interval, so that hellos
491 aren't sent late. The result is in milliseconds. */
493 jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
495 unsigned interval
= babel_ifp
->hello_interval
;
497 interval
= MIN(interval
, 100);
499 interval
= MIN(interval
, 4000);
500 return roughly(interval
) / 4;
504 update_jitter(babel_interface_nfo
*babel_ifp
, int urgent
)
506 unsigned interval
= babel_ifp
->hello_interval
;
508 interval
= MIN(interval
, 100);
510 interval
= MIN(interval
, 4000);
511 return roughly(interval
);
514 /* calculate babeld's specific datas of an interface (change when the interface
517 interface_recalculate(struct interface
*ifp
)
519 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
520 unsigned char *tmp
= NULL
;
522 struct ipv6_mreq mreq
;
527 if (!if_is_operative(ifp
) || !CHECK_FLAG(ifp
->flags
, IFF_RUNNING
)) {
528 interface_reset(ifp
);
532 babel_ifp
->flags
|= BABEL_IF_IS_UP
;
534 mtu
= MIN(ifp
->mtu
, ifp
->mtu6
);
536 /* We need to be able to fit at least two messages into a packet,
537 so MTUs below 116 require lower layer fragmentation. */
538 /* In IPv6, the minimum MTU is 1280, and every host must be able
539 to reassemble up to 1500 bytes, but I'd rather not rely on this. */
541 debugf(BABEL_DEBUG_IF
, "Suspiciously low MTU %d on interface %s (%d).",
542 mtu
, ifp
->name
, ifp
->ifindex
);
546 /* 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
547 babel_ifp
->bufsize
= mtu
- sizeof(packet_header
) - 60;
548 tmp
= babel_ifp
->sendbuf
;
549 babel_ifp
->sendbuf
= realloc(babel_ifp
->sendbuf
, babel_ifp
->bufsize
);
550 if(babel_ifp
->sendbuf
== NULL
) {
551 zlog_err("Couldn't reallocate sendbuf.");
553 babel_ifp
->bufsize
= 0;
558 resize_receive_buffer(mtu
);
560 if(!(babel_ifp
->flags
& BABEL_IF_WIRED
)) { /* if (wired) */
561 babel_ifp
->cost
= 96;
562 babel_ifp
->flags
&= ~BABEL_IF_LQ
;
564 babel_ifp
->cost
= 256;
565 babel_ifp
->flags
|= BABEL_IF_LQ
;
568 /* Since the interface was marked as active above, the
569 idle_hello_interval cannot be the one being used here. */
570 babel_ifp
->update_interval
= babel_ifp
->hello_interval
* 4;
572 memset(&mreq
, 0, sizeof(mreq
));
573 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
574 mreq
.ipv6mr_interface
= ifp
->ifindex
;
576 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
577 (char*)&mreq
, sizeof(mreq
));
579 zlog_err("setsockopt(IPV6_JOIN_GROUP) on interface '%s': %s",
580 ifp
->name
, safe_strerror(errno
));
581 /* This is probably due to a missing link-local address,
582 so down this interface, and wait until the main loop
583 tries to up it again. */
584 interface_reset(ifp
);
588 set_timeout(&babel_ifp
->hello_timeout
, babel_ifp
->hello_interval
);
589 set_timeout(&babel_ifp
->update_timeout
, babel_ifp
->update_interval
);
591 send_request(ifp
, NULL
, 0);
593 update_interface_metric(ifp
);
595 debugf(BABEL_DEBUG_COMMON
,
596 "Upped interface %s (%s, cost=%d, channel=%d%s).",
598 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
601 babel_ifp
->ipv4
? ", IPv4" : "");
604 send_update(ifp
, 0, NULL
, 0);
609 /* Reset the interface as it was new: it's not removed from the interface list,
610 and may be considered as a upped interface. */
612 interface_reset(struct interface
*ifp
)
615 struct ipv6_mreq mreq
;
616 babel_interface_nfo
*babel_ifp
= babel_get_if_nfo(ifp
);
618 if (!(babel_ifp
->flags
& BABEL_IF_IS_UP
))
621 debugf(BABEL_DEBUG_IF
, "interface reset: %s", ifp
->name
);
622 babel_ifp
->flags
&= ~BABEL_IF_IS_UP
;
624 flush_interface_routes(ifp
, 0);
625 babel_ifp
->buffered
= 0;
626 babel_ifp
->bufsize
= 0;
627 free(babel_ifp
->sendbuf
);
628 babel_ifp
->num_buffered_updates
= 0;
629 babel_ifp
->update_bufsize
= 0;
630 if(babel_ifp
->buffered_updates
)
631 free(babel_ifp
->buffered_updates
);
632 babel_ifp
->buffered_updates
= NULL
;
633 babel_ifp
->sendbuf
= NULL
;
635 if(ifp
->ifindex
> 0) {
636 memset(&mreq
, 0, sizeof(mreq
));
637 memcpy(&mreq
.ipv6mr_multiaddr
, protocol_group
, 16);
638 mreq
.ipv6mr_interface
= ifp
->ifindex
;
639 rc
= setsockopt(protocol_socket
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
640 (char*)&mreq
, sizeof(mreq
));
642 zlog_err("setsockopt(IPV6_LEAVE_GROUP) on interface '%s': %s",
643 ifp
->name
, safe_strerror(errno
));
646 update_interface_metric(ifp
);
648 debugf(BABEL_DEBUG_COMMON
,"Upped network %s (%s, cost=%d%s).",
650 (babel_ifp
->flags
& BABEL_IF_WIRED
) ? "wired" : "wireless",
652 babel_ifp
->ipv4
? ", IPv4" : "");
657 /* Send retraction to all, and reset all interfaces statistics. */
659 babel_interface_close_all(void)
661 struct interface
*ifp
= NULL
;
662 struct listnode
*linklist_node
= NULL
;
664 FOR_ALL_INTERFACES(ifp
, linklist_node
) {
667 send_wildcard_retraction(ifp
);
668 /* Make sure that we expire quickly from our neighbours'
669 association caches. */
670 send_hello_noupdate(ifp
, 10);
672 usleep(roughly(1000));
675 FOR_ALL_INTERFACES(ifp
, linklist_node
) {
678 /* Make sure they got it. */
679 send_wildcard_retraction(ifp
);
680 send_hello_noupdate(ifp
, 1);
682 usleep(roughly(10000));
684 interface_reset(ifp
);
688 /* return "true" if address is one of our ipv6 addresses */
690 is_interface_ll_address(struct interface
*ifp
, const unsigned char *address
)
692 struct connected
*connected
;
693 struct listnode
*node
;
698 FOR_ALL_INTERFACES_ADDRESSES(ifp
, connected
, node
) {
699 if(connected
->address
->family
== AF_INET6
&&
700 memcmp(&connected
->address
->u
.prefix6
, address
, 16) == 0)
708 show_babel_interface_sub (struct vty
*vty
, struct interface
*ifp
)
711 babel_interface_nfo
*babel_ifp
;
713 vty_out (vty
, "%s is %s%s", ifp
->name
,
714 ((is_up
= if_is_operative(ifp
)) ? "up" : "down"), VTY_NEWLINE
);
715 vty_out (vty
, " ifindex %u, MTU %u bytes %s%s",
716 ifp
->ifindex
, ifp
->mtu
, if_flag_dump(ifp
->flags
), VTY_NEWLINE
);
718 if (babel_enable_if_lookup (ifp
->name
) < 0)
720 vty_out (vty
, " Babel protocol is not enabled on this interface%s", VTY_NEWLINE
);
725 vty_out (vty
, " Babel protocol is enabled, but not running on this interface%s", VTY_NEWLINE
);
728 babel_ifp
= babel_get_if_nfo (ifp
);
729 vty_out (vty
, " Babel protocol is running on this interface%s", VTY_NEWLINE
);
730 vty_out (vty
, " Operating mode is \"%s\"%s",
731 CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_WIRED
) ? "wired" : "wireless", VTY_NEWLINE
);
732 vty_out (vty
, " Split horizon mode is %s%s",
733 CHECK_FLAG (babel_ifp
->flags
, BABEL_IF_SPLIT_HORIZON
) ? "On" : "Off", VTY_NEWLINE
);
734 vty_out (vty
, " Hello interval is %u ms%s", babel_ifp
->hello_interval
, VTY_NEWLINE
);
735 vty_out (vty
, " Update interval is %u ms%s", babel_ifp
->update_interval
, VTY_NEWLINE
);
738 DEFUN (show_babel_interface
,
739 show_babel_interface_cmd
,
740 "show babel interface [INTERFACE]",
743 "Babel information\n"
744 "Interface information\n"
747 struct interface
*ifp
;
748 struct listnode
*node
;
752 for (ALL_LIST_ELEMENTS_RO (iflist
, node
, ifp
))
753 show_babel_interface_sub (vty
, ifp
);
756 if ((ifp
= if_lookup_by_name (argv
[0])) == NULL
)
758 vty_out (vty
, "No such interface name%s", VTY_NEWLINE
);
761 show_babel_interface_sub (vty
, ifp
);
766 show_babel_neighbour_sub (struct vty
*vty
, struct neighbour
*neigh
)
769 "Neighbour %s dev %s reach %04x rxcost %d txcost %d %s.%s",
770 format_address(neigh
->address
),
773 neighbour_rxcost(neigh
),
775 if_up(neigh
->ifp
) ? "" : " (down)",
779 DEFUN (show_babel_neighbour
,
780 show_babel_neighbour_cmd
,
781 "show babel neighbour [INTERFACE]",
784 "Babel information\n"
788 struct neighbour
*neigh
;
789 struct interface
*ifp
;
792 FOR_ALL_NEIGHBOURS(neigh
) {
793 show_babel_neighbour_sub(vty
, neigh
);
797 if ((ifp
= if_lookup_by_name (argv
[0])) == NULL
)
799 vty_out (vty
, "No such interface name%s", VTY_NEWLINE
);
802 FOR_ALL_NEIGHBOURS(neigh
) {
803 if(ifp
->ifindex
== neigh
->ifp
->ifindex
) {
804 show_babel_neighbour_sub(vty
, neigh
);
811 show_babel_routes_sub (struct babel_route
*route
, void *closure
)
813 struct vty
*vty
= (struct vty
*) closure
;
814 const unsigned char *nexthop
=
815 memcmp(route
->nexthop
, route
->neigh
->address
, 16) == 0 ?
816 NULL
: route
->nexthop
;
819 if(route
->channels
[0] == 0)
823 snprintf(channels
, 100, " chan (");
824 j
= strlen(channels
);
825 for(k
= 0; k
< DIVERSITY_HOPS
; k
++) {
826 if(route
->channels
[k
] == 0)
830 snprintf(channels
+ j
, 100 - j
, "%d", route
->channels
[k
]);
831 j
= strlen(channels
);
833 snprintf(channels
+ j
, 100 - j
, ")");
839 "%s metric %d refmetric %d id %s seqno %d%s age %d "
840 "via %s neigh %s%s%s%s%s",
841 format_prefix(route
->src
->prefix
, route
->src
->plen
),
842 route_metric(route
), route
->refmetric
,
843 format_eui64(route
->src
->id
),
846 (int)(babel_now
.tv_sec
- route
->time
),
847 route
->neigh
->ifp
->name
,
848 format_address(route
->neigh
->address
),
849 nexthop
? " nexthop " : "",
850 nexthop
? format_address(nexthop
) : "",
851 route
->installed
? " (installed)" :
852 route_feasible(route
) ? " (feasible)" : "",
857 show_babel_xroutes_sub (struct xroute
*xroute
, void *closure
)
859 struct vty
*vty
= (struct vty
*) closure
;
860 vty_out(vty
, "%s metric %d (exported)%s",
861 format_prefix(xroute
->prefix
, xroute
->plen
),
866 DEFUN (show_babel_database
,
867 show_babel_database_cmd
,
868 "show babel database",
871 "Babel information\n"
872 "Database information\n"
875 for_all_routes(show_babel_routes_sub
, vty
);
876 for_all_xroutes(show_babel_xroutes_sub
, vty
);
880 DEFUN (show_babel_parameters
,
881 show_babel_parameters_cmd
,
882 "show babel parameters",
885 "Babel information\n"
886 "Configuration information\n"
889 vty_out(vty
, " -- Babel running configuration --%s", VTY_NEWLINE
);
890 show_babel_main_configuration(vty
);
891 vty_out(vty
, " -- distribution lists --%s", VTY_NEWLINE
);
892 config_show_distribute(vty
);
900 /* initialize interface list */
902 if_add_hook (IF_NEW_HOOK
, babel_if_new_hook
);
903 if_add_hook (IF_DELETE_HOOK
, babel_if_delete_hook
);
905 babel_enable_if
= vector_init (1);
907 /* install interface node and commands */
908 install_element (CONFIG_NODE
, &interface_cmd
);
909 install_element (CONFIG_NODE
, &no_interface_cmd
);
910 install_node (&babel_interface_node
, interface_config_write
);
911 install_default(INTERFACE_NODE
);
912 install_element(INTERFACE_NODE
, &interface_cmd
);
913 install_element(INTERFACE_NODE
, &no_interface_cmd
);
915 install_element(BABEL_NODE
, &babel_network_cmd
);
916 install_element(BABEL_NODE
, &no_babel_network_cmd
);
917 install_element(INTERFACE_NODE
, &babel_split_horizon_cmd
);
918 install_element(INTERFACE_NODE
, &no_babel_split_horizon_cmd
);
919 install_element(INTERFACE_NODE
, &babel_set_wired_cmd
);
920 install_element(INTERFACE_NODE
, &babel_set_wireless_cmd
);
921 install_element(INTERFACE_NODE
, &babel_set_hello_interval_cmd
);
922 install_element(INTERFACE_NODE
, &babel_set_update_interval_cmd
);
923 install_element(INTERFACE_NODE
, &babel_passive_interface_cmd
);
924 install_element(INTERFACE_NODE
, &no_babel_passive_interface_cmd
);
926 /* "show babel ..." commands */
927 install_element(VIEW_NODE
, &show_babel_interface_cmd
);
928 install_element(ENABLE_NODE
, &show_babel_interface_cmd
);
929 install_element(VIEW_NODE
, &show_babel_neighbour_cmd
);
930 install_element(ENABLE_NODE
, &show_babel_neighbour_cmd
);
931 install_element(VIEW_NODE
, &show_babel_database_cmd
);
932 install_element(ENABLE_NODE
, &show_babel_database_cmd
);
933 install_element(VIEW_NODE
, &show_babel_parameters_cmd
);
934 install_element(ENABLE_NODE
, &show_babel_parameters_cmd
);
937 /* hooks: functions called respectively when struct interface is
938 created or deleted. */
940 babel_if_new_hook (struct interface
*ifp
)
942 ifp
->info
= babel_interface_allocate();
947 babel_if_delete_hook (struct interface
*ifp
)
949 babel_interface_free(ifp
->info
);
954 /* Configuration write function for babeld. */
956 interface_config_write (struct vty
*vty
)
958 struct listnode
*node
;
959 struct interface
*ifp
;
962 for (ALL_LIST_ELEMENTS_RO (iflist
, node
, ifp
)) {
963 /* Do not display the interface if there is no configuration about it */
964 if (ifp
->desc
== NULL
)
967 vty_out (vty
, "interface %s%s", ifp
->name
,
970 vty_out (vty
, " description %s%s", ifp
->desc
,
973 /* TODO: to be completed... */
975 vty_out (vty
, "!%s", VTY_NEWLINE
);
982 /* Output a "network" statement line for each of the enabled interfaces. */
984 babel_enable_if_config_write (struct vty
* vty
)
986 unsigned int i
, lines
= 0;
989 for (i
= 0; i
< vector_active (babel_enable_if
); i
++)
990 if ((str
= vector_slot (babel_enable_if
, i
)) != NULL
)
992 vty_out (vty
, " network %s%s", str
, VTY_NEWLINE
);
998 /* functions to allocate or free memory for a babel_interface_nfo, filling
1000 static babel_interface_nfo
*
1001 babel_interface_allocate (void)
1003 babel_interface_nfo
*babel_ifp
;
1004 babel_ifp
= XMALLOC(MTYPE_BABEL_IF
, sizeof(babel_interface_nfo
));
1005 if(babel_ifp
== NULL
)
1008 /* Here are set the default values for an interface. */
1009 memset(babel_ifp
, 0, sizeof(babel_interface_nfo
));
1010 /* All flags are unset */
1011 babel_ifp
->bucket_time
= babel_now
.tv_sec
;
1012 babel_ifp
->bucket
= BUCKET_TOKENS_MAX
;
1013 babel_ifp
->hello_seqno
= (random() & 0xFFFF);
1014 babel_ifp
->hello_interval
= BABELD_DEFAULT_HELLO_INTERVAL
;
1015 babel_ifp
->channel
= BABEL_IF_CHANNEL_INTERFERING
;
1021 babel_interface_free (babel_interface_nfo
*babel_ifp
)
1023 XFREE(MTYPE_BABEL_IF
, babel_ifp
);