lib: make some structures constant
[jleu-quagga.git] / ripd / rip_interface.c
blobd3b55fc01f52a0ca0a0ef197382d5a643104c96b
1 /* Interface related function for RIP.
2 * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
22 #include <zebra.h>
24 #include "command.h"
25 #include "if.h"
26 #include "sockunion.h"
27 #include "prefix.h"
28 #include "memory.h"
29 #include "network.h"
30 #include "table.h"
31 #include "log.h"
32 #include "stream.h"
33 #include "thread.h"
34 #include "zclient.h"
35 #include "filter.h"
36 #include "sockopt.h"
37 #include "privs.h"
39 #include "zebra/connected.h"
41 #include "ripd/ripd.h"
42 #include "ripd/rip_debug.h"
43 #include "ripd/rip_interface.h"
45 /* static prototypes */
46 static void rip_enable_apply (struct interface *);
47 static void rip_passive_interface_apply (struct interface *);
48 static int rip_if_down(struct interface *ifp);
49 static int rip_enable_if_lookup (const char *ifname);
50 static int rip_enable_network_lookup2 (struct connected *connected);
51 static void rip_enable_apply_all (void);
53 struct message ri_version_msg[] =
55 {RI_RIP_VERSION_1, "1"},
56 {RI_RIP_VERSION_2, "2"},
57 {RI_RIP_VERSION_1_AND_2, "1 2"},
60 extern struct zebra_privs_t ripd_privs;
62 /* RIP enabled network vector. */
63 vector rip_enable_interface;
65 /* RIP enabled interface table. */
66 struct route_table *rip_enable_network;
68 /* Vector to store passive-interface name. */
69 static int passive_default; /* are we in passive-interface default mode? */
70 vector Vrip_passive_nondefault;
72 /* Join to the RIP version 2 multicast group. */
73 static int
74 ipv4_multicast_join (int sock,
75 struct in_addr group,
76 struct in_addr ifa,
77 unsigned int ifindex)
79 int ret;
81 ret = setsockopt_multicast_ipv4 (sock,
82 IP_ADD_MEMBERSHIP,
83 ifa,
84 group.s_addr,
85 ifindex);
87 if (ret < 0)
88 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
89 safe_strerror (errno));
91 return ret;
94 /* Leave from the RIP version 2 multicast group. */
95 static int
96 ipv4_multicast_leave (int sock,
97 struct in_addr group,
98 struct in_addr ifa,
99 unsigned int ifindex)
101 int ret;
103 ret = setsockopt_multicast_ipv4 (sock,
104 IP_DROP_MEMBERSHIP,
105 ifa,
106 group.s_addr,
107 ifindex);
109 if (ret < 0)
110 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
112 return ret;
115 /* Allocate new RIP's interface configuration. */
116 static struct rip_interface *
117 rip_interface_new (void)
119 struct rip_interface *ri;
121 ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
123 /* Default authentication type is simple password for Cisco
124 compatibility. */
125 ri->auth_type = RIP_NO_AUTH;
126 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
128 /* Set default split-horizon behavior. If the interface is Frame
129 Relay or SMDS is enabled, the default value for split-horizon is
130 off. But currently Zebra does detect Frame Relay or SMDS
131 interface. So all interface is set to split horizon. */
132 ri->split_horizon_default = RIP_SPLIT_HORIZON;
133 ri->split_horizon = ri->split_horizon_default;
135 return ri;
138 void
139 rip_interface_multicast_set (int sock, struct connected *connected)
141 struct in_addr addr;
143 assert (connected != NULL);
145 addr = CONNECTED_ID(connected)->u.prefix4;
147 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
148 connected->ifp->ifindex) < 0)
150 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
151 "source address %s for interface %s",
152 sock, inet_ntoa(addr),
153 connected->ifp->name);
156 return;
159 /* Send RIP request packet to specified interface. */
160 static void
161 rip_request_interface_send (struct interface *ifp, u_char version)
163 struct sockaddr_in to;
165 /* RIPv2 support multicast. */
166 if (version == RIPv2 && if_is_multicast (ifp))
169 if (IS_RIP_DEBUG_EVENT)
170 zlog_debug ("multicast request on %s", ifp->name);
172 rip_request_send (NULL, ifp, version, NULL);
173 return;
176 /* RIPv1 and non multicast interface. */
177 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
179 struct listnode *cnode, *cnnode;
180 struct connected *connected;
182 if (IS_RIP_DEBUG_EVENT)
183 zlog_debug ("broadcast request to %s", ifp->name);
185 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
187 if (connected->address->family == AF_INET)
189 memset (&to, 0, sizeof (struct sockaddr_in));
190 to.sin_port = htons (RIP_PORT_DEFAULT);
191 if (connected->destination)
192 /* use specified broadcast or peer destination addr */
193 to.sin_addr = connected->destination->u.prefix4;
194 else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
195 /* calculate the appropriate broadcast address */
196 to.sin_addr.s_addr =
197 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
198 connected->address->prefixlen);
199 else
200 /* do not know where to send the packet */
201 continue;
203 if (IS_RIP_DEBUG_EVENT)
204 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
206 rip_request_send (&to, ifp, version, connected);
212 /* This will be executed when interface goes up. */
213 static void
214 rip_request_interface (struct interface *ifp)
216 struct rip_interface *ri;
218 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
219 if (if_is_loopback (ifp))
220 return;
222 /* If interface is down, don't send RIP packet. */
223 if (! if_is_operative (ifp))
224 return;
226 /* Fetch RIP interface information. */
227 ri = ifp->info;
230 /* If there is no version configuration in the interface,
231 use rip's version setting. */
233 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
234 rip->version_send : ri->ri_send);
235 if (vsend & RIPv1)
236 rip_request_interface_send (ifp, RIPv1);
237 if (vsend & RIPv2)
238 rip_request_interface_send (ifp, RIPv2);
242 #if 0
243 /* Send RIP request to the neighbor. */
244 static void
245 rip_request_neighbor (struct in_addr addr)
247 struct sockaddr_in to;
249 memset (&to, 0, sizeof (struct sockaddr_in));
250 to.sin_port = htons (RIP_PORT_DEFAULT);
251 to.sin_addr = addr;
253 rip_request_send (&to, NULL, rip->version_send, NULL);
256 /* Request routes at all interfaces. */
257 static void
258 rip_request_neighbor_all (void)
260 struct route_node *rp;
262 if (! rip)
263 return;
265 if (IS_RIP_DEBUG_EVENT)
266 zlog_debug ("request to the all neighbor");
268 /* Send request to all neighbor. */
269 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
270 if (rp->info)
271 rip_request_neighbor (rp->p.u.prefix4);
273 #endif
275 /* Multicast packet receive socket. */
276 static int
277 rip_multicast_join (struct interface *ifp, int sock)
279 struct listnode *cnode;
280 struct connected *ifc;
282 if (if_is_operative (ifp) && if_is_multicast (ifp))
284 if (IS_RIP_DEBUG_EVENT)
285 zlog_debug ("multicast join at %s", ifp->name);
287 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
289 struct prefix_ipv4 *p;
290 struct in_addr group;
292 p = (struct prefix_ipv4 *) ifc->address;
294 if (p->family != AF_INET)
295 continue;
297 group.s_addr = htonl (INADDR_RIP_GROUP);
298 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
299 return -1;
300 else
301 return 0;
304 return 0;
307 /* Leave from multicast group. */
308 static void
309 rip_multicast_leave (struct interface *ifp, int sock)
311 struct listnode *cnode;
312 struct connected *connected;
314 if (if_is_up (ifp) && if_is_multicast (ifp))
316 if (IS_RIP_DEBUG_EVENT)
317 zlog_debug ("multicast leave from %s", ifp->name);
319 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
321 struct prefix_ipv4 *p;
322 struct in_addr group;
324 p = (struct prefix_ipv4 *) connected->address;
326 if (p->family != AF_INET)
327 continue;
329 group.s_addr = htonl (INADDR_RIP_GROUP);
330 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
331 return;
336 /* Is there and address on interface that I could use ? */
337 static int
338 rip_if_ipv4_address_check (struct interface *ifp)
340 struct listnode *nn;
341 struct connected *connected;
342 int count = 0;
344 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
346 struct prefix *p;
348 p = connected->address;
350 if (p->family == AF_INET)
351 count++;
354 return count;
360 /* Does this address belongs to me ? */
362 if_check_address (struct in_addr addr)
364 struct listnode *node;
365 struct interface *ifp;
367 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
369 struct listnode *cnode;
370 struct connected *connected;
372 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
374 struct prefix_ipv4 *p;
376 p = (struct prefix_ipv4 *) connected->address;
378 if (p->family != AF_INET)
379 continue;
381 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
382 return 1;
385 return 0;
388 /* Inteface link down message processing. */
390 rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
392 struct interface *ifp;
393 struct stream *s;
395 s = zclient->ibuf;
397 /* zebra_interface_state_read() updates interface structure in
398 iflist. */
399 ifp = zebra_interface_state_read(s);
401 if (ifp == NULL)
402 return 0;
404 rip_if_down(ifp);
406 if (IS_RIP_DEBUG_ZEBRA)
407 zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down",
408 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
409 ifp->metric, ifp->mtu);
411 return 0;
414 /* Inteface link up message processing */
416 rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
418 struct interface *ifp;
420 /* zebra_interface_state_read () updates interface structure in
421 iflist. */
422 ifp = zebra_interface_state_read (zclient->ibuf);
424 if (ifp == NULL)
425 return 0;
427 if (IS_RIP_DEBUG_ZEBRA)
428 zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up",
429 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
430 ifp->metric, ifp->mtu);
432 /* Check if this interface is RIP enabled or not.*/
433 rip_enable_apply (ifp);
435 /* Check for a passive interface */
436 rip_passive_interface_apply (ifp);
438 /* Apply distribute list to the all interface. */
439 rip_distribute_update_interface (ifp);
441 return 0;
444 /* Inteface addition message from zebra. */
446 rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
448 struct interface *ifp;
450 ifp = zebra_interface_add_read (zclient->ibuf);
452 if (IS_RIP_DEBUG_ZEBRA)
453 zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d",
454 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
455 ifp->metric, ifp->mtu);
457 /* Check if this interface is RIP enabled or not.*/
458 rip_enable_apply (ifp);
460 /* Check for a passive interface */
461 rip_passive_interface_apply (ifp);
463 /* Apply distribute list to the all interface. */
464 rip_distribute_update_interface (ifp);
466 /* rip_request_neighbor_all (); */
468 /* Check interface routemap. */
469 rip_if_rmap_update_interface (ifp);
471 return 0;
475 rip_interface_delete (int command, struct zclient *zclient,
476 zebra_size_t length)
478 struct interface *ifp;
479 struct stream *s;
482 s = zclient->ibuf;
483 /* zebra_interface_state_read() updates interface structure in iflist */
484 ifp = zebra_interface_state_read(s);
486 if (ifp == NULL)
487 return 0;
489 if (if_is_up (ifp)) {
490 rip_if_down(ifp);
493 zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
494 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
495 ifp->metric, ifp->mtu);
497 /* To support pseudo interface do not free interface structure. */
498 /* if_delete(ifp); */
499 ifp->ifindex = IFINDEX_INTERNAL;
501 return 0;
504 void
505 rip_interface_clean (void)
507 struct listnode *node;
508 struct interface *ifp;
509 struct rip_interface *ri;
511 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
513 ri = ifp->info;
515 ri->enable_network = 0;
516 ri->enable_interface = 0;
517 ri->running = 0;
519 if (ri->t_wakeup)
521 thread_cancel (ri->t_wakeup);
522 ri->t_wakeup = NULL;
527 void
528 rip_interface_reset (void)
530 struct listnode *node;
531 struct interface *ifp;
532 struct rip_interface *ri;
534 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
536 ri = ifp->info;
538 ri->enable_network = 0;
539 ri->enable_interface = 0;
540 ri->running = 0;
542 ri->ri_send = RI_RIP_UNSPEC;
543 ri->ri_receive = RI_RIP_UNSPEC;
545 ri->auth_type = RIP_NO_AUTH;
547 if (ri->auth_str)
549 free (ri->auth_str);
550 ri->auth_str = NULL;
552 if (ri->key_chain)
554 free (ri->key_chain);
555 ri->key_chain = NULL;
558 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
559 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
561 ri->list[RIP_FILTER_IN] = NULL;
562 ri->list[RIP_FILTER_OUT] = NULL;
564 ri->prefix[RIP_FILTER_IN] = NULL;
565 ri->prefix[RIP_FILTER_OUT] = NULL;
567 if (ri->t_wakeup)
569 thread_cancel (ri->t_wakeup);
570 ri->t_wakeup = NULL;
573 ri->recv_badpackets = 0;
574 ri->recv_badroutes = 0;
575 ri->sent_updates = 0;
577 ri->passive = 0;
582 rip_if_down(struct interface *ifp)
584 struct route_node *rp;
585 struct rip_info *rinfo;
586 struct rip_interface *ri = NULL;
587 if (rip)
589 for (rp = route_top (rip->table); rp; rp = route_next (rp))
590 if ((rinfo = rp->info) != NULL)
592 /* Routes got through this interface. */
593 if (rinfo->ifindex == ifp->ifindex &&
594 rinfo->type == ZEBRA_ROUTE_RIP &&
595 rinfo->sub_type == RIP_ROUTE_RTE)
597 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
598 &rinfo->nexthop,
599 rinfo->metric);
601 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
602 (struct prefix_ipv4 *)&rp->p,
603 rinfo->ifindex);
605 else
607 /* All redistributed routes but static and system */
608 if ((rinfo->ifindex == ifp->ifindex) &&
609 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
610 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
611 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
612 (struct prefix_ipv4 *)&rp->p,
613 rinfo->ifindex);
618 ri = ifp->info;
620 if (ri->running)
622 if (IS_RIP_DEBUG_EVENT)
623 zlog_debug ("turn off %s", ifp->name);
625 /* Leave from multicast group. */
626 rip_multicast_leave (ifp, rip->sock);
628 ri->running = 0;
631 return 0;
634 /* Needed for stop RIP process. */
635 void
636 rip_if_down_all ()
638 struct interface *ifp;
639 struct listnode *node, *nnode;
641 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
642 rip_if_down (ifp);
645 static void
646 rip_apply_address_add (struct connected *ifc)
648 struct prefix_ipv4 address;
649 struct prefix *p;
651 if (!rip)
652 return;
654 if (! if_is_up(ifc->ifp))
655 return;
657 p = ifc->address;
659 memset (&address, 0, sizeof (address));
660 address.family = p->family;
661 address.prefix = p->u.prefix4;
662 address.prefixlen = p->prefixlen;
663 apply_mask_ipv4(&address);
665 /* Check if this interface is RIP enabled or not
666 or Check if this address's prefix is RIP enabled */
667 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
668 (rip_enable_network_lookup2(ifc) >= 0))
669 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
670 &address, ifc->ifp->ifindex, NULL, 0, 0);
675 rip_interface_address_add (int command, struct zclient *zclient,
676 zebra_size_t length)
678 struct connected *ifc;
679 struct prefix *p;
681 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
682 zclient->ibuf);
684 if (ifc == NULL)
685 return 0;
687 p = ifc->address;
689 if (p->family == AF_INET)
691 if (IS_RIP_DEBUG_ZEBRA)
692 zlog_debug ("connected address %s/%d is added",
693 inet_ntoa (p->u.prefix4), p->prefixlen);
695 rip_enable_apply(ifc->ifp);
696 /* Check if this prefix needs to be redistributed */
697 rip_apply_address_add(ifc);
699 #ifdef HAVE_SNMP
700 rip_ifaddr_add (ifc->ifp, ifc);
701 #endif /* HAVE_SNMP */
704 return 0;
707 static void
708 rip_apply_address_del (struct connected *ifc) {
709 struct prefix_ipv4 address;
710 struct prefix *p;
712 if (!rip)
713 return;
715 if (! if_is_up(ifc->ifp))
716 return;
718 p = ifc->address;
720 memset (&address, 0, sizeof (address));
721 address.family = p->family;
722 address.prefix = p->u.prefix4;
723 address.prefixlen = p->prefixlen;
724 apply_mask_ipv4(&address);
726 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
727 &address, ifc->ifp->ifindex);
731 rip_interface_address_delete (int command, struct zclient *zclient,
732 zebra_size_t length)
734 struct connected *ifc;
735 struct prefix *p;
737 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
738 zclient->ibuf);
740 if (ifc)
742 p = ifc->address;
743 if (p->family == AF_INET)
745 if (IS_RIP_DEBUG_ZEBRA)
746 zlog_debug ("connected address %s/%d is deleted",
747 inet_ntoa (p->u.prefix4), p->prefixlen);
749 #ifdef HAVE_SNMP
750 rip_ifaddr_delete (ifc->ifp, ifc);
751 #endif /* HAVE_SNMP */
753 /* Chech wether this prefix needs to be removed */
754 rip_apply_address_del(ifc);
758 connected_free (ifc);
762 return 0;
765 /* Check interface is enabled by network statement. */
766 /* Check wether the interface has at least a connected prefix that
767 * is within the ripng_enable_network table. */
768 static int
769 rip_enable_network_lookup_if (struct interface *ifp)
771 struct listnode *node, *nnode;
772 struct connected *connected;
773 struct prefix_ipv4 address;
775 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
777 struct prefix *p;
778 struct route_node *node;
780 p = connected->address;
782 if (p->family == AF_INET)
784 address.family = AF_INET;
785 address.prefix = p->u.prefix4;
786 address.prefixlen = IPV4_MAX_BITLEN;
788 node = route_node_match (rip_enable_network,
789 (struct prefix *)&address);
790 if (node)
792 route_unlock_node (node);
793 return 1;
797 return -1;
800 /* Check wether connected is within the ripng_enable_network table. */
802 rip_enable_network_lookup2 (struct connected *connected)
804 struct prefix_ipv4 address;
805 struct prefix *p;
807 p = connected->address;
809 if (p->family == AF_INET) {
810 struct route_node *node;
812 address.family = p->family;
813 address.prefix = p->u.prefix4;
814 address.prefixlen = IPV4_MAX_BITLEN;
816 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
817 node = route_node_match (rip_enable_network,
818 (struct prefix *)&address);
820 if (node) {
821 route_unlock_node (node);
822 return 1;
826 return -1;
828 /* Add RIP enable network. */
829 static int
830 rip_enable_network_add (struct prefix *p)
832 struct route_node *node;
834 node = route_node_get (rip_enable_network, p);
836 if (node->info)
838 route_unlock_node (node);
839 return -1;
841 else
842 node->info = (char *) "enabled";
844 /* XXX: One should find a better solution than a generic one */
845 rip_enable_apply_all();
847 return 1;
850 /* Delete RIP enable network. */
851 static int
852 rip_enable_network_delete (struct prefix *p)
854 struct route_node *node;
856 node = route_node_lookup (rip_enable_network, p);
857 if (node)
859 node->info = NULL;
861 /* Unlock info lock. */
862 route_unlock_node (node);
864 /* Unlock lookup lock. */
865 route_unlock_node (node);
867 /* XXX: One should find a better solution than a generic one */
868 rip_enable_apply_all ();
870 return 1;
872 return -1;
875 /* Check interface is enabled by ifname statement. */
876 static int
877 rip_enable_if_lookup (const char *ifname)
879 unsigned int i;
880 char *str;
882 for (i = 0; i < vector_active (rip_enable_interface); i++)
883 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
884 if (strcmp (str, ifname) == 0)
885 return i;
886 return -1;
889 /* Add interface to rip_enable_if. */
890 static int
891 rip_enable_if_add (const char *ifname)
893 int ret;
895 ret = rip_enable_if_lookup (ifname);
896 if (ret >= 0)
897 return -1;
899 vector_set (rip_enable_interface, strdup (ifname));
901 rip_enable_apply_all(); /* TODOVJ */
903 return 1;
906 /* Delete interface from rip_enable_if. */
907 static int
908 rip_enable_if_delete (const char *ifname)
910 int index;
911 char *str;
913 index = rip_enable_if_lookup (ifname);
914 if (index < 0)
915 return -1;
917 str = vector_slot (rip_enable_interface, index);
918 free (str);
919 vector_unset (rip_enable_interface, index);
921 rip_enable_apply_all(); /* TODOVJ */
923 return 1;
926 /* Join to multicast group and send request to the interface. */
927 static int
928 rip_interface_wakeup (struct thread *t)
930 struct interface *ifp;
931 struct rip_interface *ri;
933 /* Get interface. */
934 ifp = THREAD_ARG (t);
936 ri = ifp->info;
937 ri->t_wakeup = NULL;
939 /* Join to multicast group. */
940 if (rip_multicast_join (ifp, rip->sock) < 0)
942 zlog_err ("multicast join failed, interface %s not running", ifp->name);
943 return 0;
946 /* Set running flag. */
947 ri->running = 1;
949 /* Send RIP request to the interface. */
950 rip_request_interface (ifp);
952 return 0;
955 static void
956 rip_connect_set (struct interface *ifp, int set)
958 struct listnode *node, *nnode;
959 struct connected *connected;
960 struct prefix_ipv4 address;
962 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
964 struct prefix *p;
965 p = connected->address;
967 if (p->family != AF_INET)
968 continue;
970 address.family = AF_INET;
971 address.prefix = p->u.prefix4;
972 address.prefixlen = p->prefixlen;
973 apply_mask_ipv4 (&address);
975 if (set) {
976 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
977 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
978 (rip_enable_network_lookup2(connected) >= 0))
979 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
980 &address, connected->ifp->ifindex,
981 NULL, 0, 0);
982 } else
984 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
985 &address, connected->ifp->ifindex);
986 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
987 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
988 &address, connected->ifp->ifindex,
989 NULL, 0, 0);
994 /* Update interface status. */
995 void
996 rip_enable_apply (struct interface *ifp)
998 int ret;
999 struct rip_interface *ri = NULL;
1001 /* Check interface. */
1002 if (! if_is_operative (ifp))
1003 return;
1005 ri = ifp->info;
1007 /* Check network configuration. */
1008 ret = rip_enable_network_lookup_if (ifp);
1010 /* If the interface is matched. */
1011 if (ret > 0)
1012 ri->enable_network = 1;
1013 else
1014 ri->enable_network = 0;
1016 /* Check interface name configuration. */
1017 ret = rip_enable_if_lookup (ifp->name);
1018 if (ret >= 0)
1019 ri->enable_interface = 1;
1020 else
1021 ri->enable_interface = 0;
1023 /* any interface MUST have an IPv4 address */
1024 if ( ! rip_if_ipv4_address_check (ifp) )
1026 ri->enable_network = 0;
1027 ri->enable_interface = 0;
1030 /* Update running status of the interface. */
1031 if (ri->enable_network || ri->enable_interface)
1034 if (IS_RIP_DEBUG_EVENT)
1035 zlog_debug ("turn on %s", ifp->name);
1037 /* Add interface wake up thread. */
1038 if (! ri->t_wakeup)
1039 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1040 ifp, 1);
1041 rip_connect_set (ifp, 1);
1044 else
1046 if (ri->running)
1048 /* Might as well clean up the route table as well
1049 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1050 **/
1051 rip_if_down(ifp);
1053 rip_connect_set (ifp, 0);
1058 /* Apply network configuration to all interface. */
1059 void
1060 rip_enable_apply_all ()
1062 struct interface *ifp;
1063 struct listnode *node, *nnode;
1065 /* Check each interface. */
1066 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1067 rip_enable_apply (ifp);
1071 rip_neighbor_lookup (struct sockaddr_in *from)
1073 struct prefix_ipv4 p;
1074 struct route_node *node;
1076 memset (&p, 0, sizeof (struct prefix_ipv4));
1077 p.family = AF_INET;
1078 p.prefix = from->sin_addr;
1079 p.prefixlen = IPV4_MAX_BITLEN;
1081 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1082 if (node)
1084 route_unlock_node (node);
1085 return 1;
1087 return 0;
1090 /* Add new RIP neighbor to the neighbor tree. */
1091 static int
1092 rip_neighbor_add (struct prefix_ipv4 *p)
1094 struct route_node *node;
1096 node = route_node_get (rip->neighbor, (struct prefix *) p);
1098 if (node->info)
1099 return -1;
1101 node->info = rip->neighbor;
1103 return 0;
1106 /* Delete RIP neighbor from the neighbor tree. */
1107 static int
1108 rip_neighbor_delete (struct prefix_ipv4 *p)
1110 struct route_node *node;
1112 /* Lock for look up. */
1113 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1114 if (! node)
1115 return -1;
1117 node->info = NULL;
1119 /* Unlock lookup lock. */
1120 route_unlock_node (node);
1122 /* Unlock real neighbor information lock. */
1123 route_unlock_node (node);
1125 return 0;
1128 /* Clear all network and neighbor configuration. */
1129 void
1130 rip_clean_network ()
1132 unsigned int i;
1133 char *str;
1134 struct route_node *rn;
1136 /* rip_enable_network. */
1137 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1138 if (rn->info)
1140 rn->info = NULL;
1141 route_unlock_node (rn);
1144 /* rip_enable_interface. */
1145 for (i = 0; i < vector_active (rip_enable_interface); i++)
1146 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1148 free (str);
1149 vector_slot (rip_enable_interface, i) = NULL;
1153 /* Utility function for looking up passive interface settings. */
1154 static int
1155 rip_passive_nondefault_lookup (const char *ifname)
1157 unsigned int i;
1158 char *str;
1160 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
1161 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
1162 if (strcmp (str, ifname) == 0)
1163 return i;
1164 return -1;
1167 void
1168 rip_passive_interface_apply (struct interface *ifp)
1170 struct rip_interface *ri;
1172 ri = ifp->info;
1174 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1175 passive_default : !passive_default);
1177 if (IS_RIP_DEBUG_ZEBRA)
1178 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
1181 static void
1182 rip_passive_interface_apply_all (void)
1184 struct interface *ifp;
1185 struct listnode *node, *nnode;
1187 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1188 rip_passive_interface_apply (ifp);
1191 /* Passive interface. */
1192 static int
1193 rip_passive_nondefault_set (struct vty *vty, const char *ifname)
1195 if (rip_passive_nondefault_lookup (ifname) >= 0)
1196 return CMD_WARNING;
1198 vector_set (Vrip_passive_nondefault, strdup (ifname));
1200 rip_passive_interface_apply_all ();
1202 return CMD_SUCCESS;
1205 static int
1206 rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
1208 int i;
1209 char *str;
1211 i = rip_passive_nondefault_lookup (ifname);
1212 if (i < 0)
1213 return CMD_WARNING;
1215 str = vector_slot (Vrip_passive_nondefault, i);
1216 free (str);
1217 vector_unset (Vrip_passive_nondefault, i);
1219 rip_passive_interface_apply_all ();
1221 return CMD_SUCCESS;
1224 /* Free all configured RIP passive-interface settings. */
1225 void
1226 rip_passive_nondefault_clean (void)
1228 unsigned int i;
1229 char *str;
1231 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
1232 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
1234 free (str);
1235 vector_slot (Vrip_passive_nondefault, i) = NULL;
1237 rip_passive_interface_apply_all ();
1240 /* RIP enable network or interface configuration. */
1241 DEFUN (rip_network,
1242 rip_network_cmd,
1243 "network (A.B.C.D/M|WORD)",
1244 "Enable routing on an IP network\n"
1245 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1246 "Interface name\n")
1248 int ret;
1249 struct prefix_ipv4 p;
1251 ret = str2prefix_ipv4 (argv[0], &p);
1253 if (ret)
1254 ret = rip_enable_network_add ((struct prefix *) &p);
1255 else
1256 ret = rip_enable_if_add (argv[0]);
1258 if (ret < 0)
1260 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1261 VTY_NEWLINE);
1262 return CMD_WARNING;
1265 return CMD_SUCCESS;
1268 /* RIP enable network or interface configuration. */
1269 DEFUN (no_rip_network,
1270 no_rip_network_cmd,
1271 "no network (A.B.C.D/M|WORD)",
1272 NO_STR
1273 "Enable routing on an IP network\n"
1274 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1275 "Interface name\n")
1277 int ret;
1278 struct prefix_ipv4 p;
1280 ret = str2prefix_ipv4 (argv[0], &p);
1282 if (ret)
1283 ret = rip_enable_network_delete ((struct prefix *) &p);
1284 else
1285 ret = rip_enable_if_delete (argv[0]);
1287 if (ret < 0)
1289 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1290 VTY_NEWLINE);
1291 return CMD_WARNING;
1294 return CMD_SUCCESS;
1297 /* RIP neighbor configuration set. */
1298 DEFUN (rip_neighbor,
1299 rip_neighbor_cmd,
1300 "neighbor A.B.C.D",
1301 "Specify a neighbor router\n"
1302 "Neighbor address\n")
1304 int ret;
1305 struct prefix_ipv4 p;
1307 ret = str2prefix_ipv4 (argv[0], &p);
1309 if (ret <= 0)
1311 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1312 return CMD_WARNING;
1315 rip_neighbor_add (&p);
1317 return CMD_SUCCESS;
1320 /* RIP neighbor configuration unset. */
1321 DEFUN (no_rip_neighbor,
1322 no_rip_neighbor_cmd,
1323 "no neighbor A.B.C.D",
1324 NO_STR
1325 "Specify a neighbor router\n"
1326 "Neighbor address\n")
1328 int ret;
1329 struct prefix_ipv4 p;
1331 ret = str2prefix_ipv4 (argv[0], &p);
1333 if (ret <= 0)
1335 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1336 return CMD_WARNING;
1339 rip_neighbor_delete (&p);
1341 return CMD_SUCCESS;
1344 DEFUN (ip_rip_receive_version,
1345 ip_rip_receive_version_cmd,
1346 "ip rip receive version (1|2)",
1347 IP_STR
1348 "Routing Information Protocol\n"
1349 "Advertisement reception\n"
1350 "Version control\n"
1351 "RIP version 1\n"
1352 "RIP version 2\n")
1354 struct interface *ifp;
1355 struct rip_interface *ri;
1357 ifp = (struct interface *)vty->index;
1358 ri = ifp->info;
1360 /* Version 1. */
1361 if (atoi (argv[0]) == 1)
1363 ri->ri_receive = RI_RIP_VERSION_1;
1364 return CMD_SUCCESS;
1366 if (atoi (argv[0]) == 2)
1368 ri->ri_receive = RI_RIP_VERSION_2;
1369 return CMD_SUCCESS;
1371 return CMD_WARNING;
1374 DEFUN (ip_rip_receive_version_1,
1375 ip_rip_receive_version_1_cmd,
1376 "ip rip receive version 1 2",
1377 IP_STR
1378 "Routing Information Protocol\n"
1379 "Advertisement reception\n"
1380 "Version control\n"
1381 "RIP version 1\n"
1382 "RIP version 2\n")
1384 struct interface *ifp;
1385 struct rip_interface *ri;
1387 ifp = (struct interface *)vty->index;
1388 ri = ifp->info;
1390 /* Version 1 and 2. */
1391 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1392 return CMD_SUCCESS;
1395 DEFUN (ip_rip_receive_version_2,
1396 ip_rip_receive_version_2_cmd,
1397 "ip rip receive version 2 1",
1398 IP_STR
1399 "Routing Information Protocol\n"
1400 "Advertisement reception\n"
1401 "Version control\n"
1402 "RIP version 2\n"
1403 "RIP version 1\n")
1405 struct interface *ifp;
1406 struct rip_interface *ri;
1408 ifp = (struct interface *)vty->index;
1409 ri = ifp->info;
1411 /* Version 1 and 2. */
1412 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1413 return CMD_SUCCESS;
1416 DEFUN (no_ip_rip_receive_version,
1417 no_ip_rip_receive_version_cmd,
1418 "no ip rip receive version",
1419 NO_STR
1420 IP_STR
1421 "Routing Information Protocol\n"
1422 "Advertisement reception\n"
1423 "Version control\n")
1425 struct interface *ifp;
1426 struct rip_interface *ri;
1428 ifp = (struct interface *)vty->index;
1429 ri = ifp->info;
1431 ri->ri_receive = RI_RIP_UNSPEC;
1432 return CMD_SUCCESS;
1435 ALIAS (no_ip_rip_receive_version,
1436 no_ip_rip_receive_version_num_cmd,
1437 "no ip rip receive version (1|2)",
1438 NO_STR
1439 IP_STR
1440 "Routing Information Protocol\n"
1441 "Advertisement reception\n"
1442 "Version control\n"
1443 "Version 1\n"
1444 "Version 2\n")
1446 DEFUN (ip_rip_send_version,
1447 ip_rip_send_version_cmd,
1448 "ip rip send version (1|2)",
1449 IP_STR
1450 "Routing Information Protocol\n"
1451 "Advertisement transmission\n"
1452 "Version control\n"
1453 "RIP version 1\n"
1454 "RIP version 2\n")
1456 struct interface *ifp;
1457 struct rip_interface *ri;
1459 ifp = (struct interface *)vty->index;
1460 ri = ifp->info;
1462 /* Version 1. */
1463 if (atoi (argv[0]) == 1)
1465 ri->ri_send = RI_RIP_VERSION_1;
1466 return CMD_SUCCESS;
1468 if (atoi (argv[0]) == 2)
1470 ri->ri_send = RI_RIP_VERSION_2;
1471 return CMD_SUCCESS;
1473 return CMD_WARNING;
1476 DEFUN (ip_rip_send_version_1,
1477 ip_rip_send_version_1_cmd,
1478 "ip rip send version 1 2",
1479 IP_STR
1480 "Routing Information Protocol\n"
1481 "Advertisement transmission\n"
1482 "Version control\n"
1483 "RIP version 1\n"
1484 "RIP version 2\n")
1486 struct interface *ifp;
1487 struct rip_interface *ri;
1489 ifp = (struct interface *)vty->index;
1490 ri = ifp->info;
1492 /* Version 1 and 2. */
1493 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1494 return CMD_SUCCESS;
1497 DEFUN (ip_rip_send_version_2,
1498 ip_rip_send_version_2_cmd,
1499 "ip rip send version 2 1",
1500 IP_STR
1501 "Routing Information Protocol\n"
1502 "Advertisement transmission\n"
1503 "Version control\n"
1504 "RIP version 2\n"
1505 "RIP version 1\n")
1507 struct interface *ifp;
1508 struct rip_interface *ri;
1510 ifp = (struct interface *)vty->index;
1511 ri = ifp->info;
1513 /* Version 1 and 2. */
1514 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1515 return CMD_SUCCESS;
1518 DEFUN (no_ip_rip_send_version,
1519 no_ip_rip_send_version_cmd,
1520 "no ip rip send version",
1521 NO_STR
1522 IP_STR
1523 "Routing Information Protocol\n"
1524 "Advertisement transmission\n"
1525 "Version control\n")
1527 struct interface *ifp;
1528 struct rip_interface *ri;
1530 ifp = (struct interface *)vty->index;
1531 ri = ifp->info;
1533 ri->ri_send = RI_RIP_UNSPEC;
1534 return CMD_SUCCESS;
1537 ALIAS (no_ip_rip_send_version,
1538 no_ip_rip_send_version_num_cmd,
1539 "no ip rip send version (1|2)",
1540 NO_STR
1541 IP_STR
1542 "Routing Information Protocol\n"
1543 "Advertisement transmission\n"
1544 "Version control\n"
1545 "Version 1\n"
1546 "Version 2\n")
1548 DEFUN (ip_rip_authentication_mode,
1549 ip_rip_authentication_mode_cmd,
1550 "ip rip authentication mode (md5|text)",
1551 IP_STR
1552 "Routing Information Protocol\n"
1553 "Authentication control\n"
1554 "Authentication mode\n"
1555 "Keyed message digest\n"
1556 "Clear text authentication\n")
1558 struct interface *ifp;
1559 struct rip_interface *ri;
1560 int auth_type;
1562 ifp = (struct interface *)vty->index;
1563 ri = ifp->info;
1565 if ( (argc < 1) || (argc > 2) )
1567 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1568 return CMD_WARNING;
1571 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1572 auth_type = RIP_AUTH_MD5;
1573 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1574 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1575 else
1577 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1578 return CMD_WARNING;
1581 if (argc == 1)
1583 ri->auth_type = auth_type;
1584 return CMD_SUCCESS;
1587 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
1589 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1590 return CMD_WARNING;
1593 if (strncmp ("r", argv[1], 1) == 0)
1594 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1595 else if (strncmp ("o", argv[1], 1) == 0)
1596 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1597 else
1598 return CMD_WARNING;
1600 ri->auth_type = auth_type;
1602 return CMD_SUCCESS;
1605 ALIAS (ip_rip_authentication_mode,
1606 ip_rip_authentication_mode_authlen_cmd,
1607 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1608 IP_STR
1609 "Routing Information Protocol\n"
1610 "Authentication control\n"
1611 "Authentication mode\n"
1612 "Keyed message digest\n"
1613 "Clear text authentication\n"
1614 "MD5 authentication data length\n"
1615 "RFC compatible\n"
1616 "Old ripd compatible\n")
1618 DEFUN (no_ip_rip_authentication_mode,
1619 no_ip_rip_authentication_mode_cmd,
1620 "no ip rip authentication mode",
1621 NO_STR
1622 IP_STR
1623 "Routing Information Protocol\n"
1624 "Authentication control\n"
1625 "Authentication mode\n")
1627 struct interface *ifp;
1628 struct rip_interface *ri;
1630 ifp = (struct interface *)vty->index;
1631 ri = ifp->info;
1633 ri->auth_type = RIP_NO_AUTH;
1634 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1636 return CMD_SUCCESS;
1639 ALIAS (no_ip_rip_authentication_mode,
1640 no_ip_rip_authentication_mode_type_cmd,
1641 "no ip rip authentication mode (md5|text)",
1642 NO_STR
1643 IP_STR
1644 "Routing Information Protocol\n"
1645 "Authentication control\n"
1646 "Authentication mode\n"
1647 "Keyed message digest\n"
1648 "Clear text authentication\n")
1650 ALIAS (no_ip_rip_authentication_mode,
1651 no_ip_rip_authentication_mode_type_authlen_cmd,
1652 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1653 NO_STR
1654 IP_STR
1655 "Routing Information Protocol\n"
1656 "Authentication control\n"
1657 "Authentication mode\n"
1658 "Keyed message digest\n"
1659 "Clear text authentication\n"
1660 "MD5 authentication data length\n"
1661 "RFC compatible\n"
1662 "Old ripd compatible\n")
1664 DEFUN (ip_rip_authentication_string,
1665 ip_rip_authentication_string_cmd,
1666 "ip rip authentication string LINE",
1667 IP_STR
1668 "Routing Information Protocol\n"
1669 "Authentication control\n"
1670 "Authentication string\n"
1671 "Authentication string\n")
1673 struct interface *ifp;
1674 struct rip_interface *ri;
1676 ifp = (struct interface *)vty->index;
1677 ri = ifp->info;
1679 if (strlen (argv[0]) > 16)
1681 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1682 VTY_NEWLINE);
1683 return CMD_WARNING;
1686 if (ri->key_chain)
1688 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1689 return CMD_WARNING;
1692 if (ri->auth_str)
1693 free (ri->auth_str);
1695 ri->auth_str = strdup (argv[0]);
1697 return CMD_SUCCESS;
1700 DEFUN (no_ip_rip_authentication_string,
1701 no_ip_rip_authentication_string_cmd,
1702 "no ip rip authentication string",
1703 NO_STR
1704 IP_STR
1705 "Routing Information Protocol\n"
1706 "Authentication control\n"
1707 "Authentication string\n")
1709 struct interface *ifp;
1710 struct rip_interface *ri;
1712 ifp = (struct interface *)vty->index;
1713 ri = ifp->info;
1715 if (ri->auth_str)
1716 free (ri->auth_str);
1718 ri->auth_str = NULL;
1720 return CMD_SUCCESS;
1723 ALIAS (no_ip_rip_authentication_string,
1724 no_ip_rip_authentication_string2_cmd,
1725 "no ip rip authentication string LINE",
1726 NO_STR
1727 IP_STR
1728 "Routing Information Protocol\n"
1729 "Authentication control\n"
1730 "Authentication string\n"
1731 "Authentication string\n")
1733 DEFUN (ip_rip_authentication_key_chain,
1734 ip_rip_authentication_key_chain_cmd,
1735 "ip rip authentication key-chain LINE",
1736 IP_STR
1737 "Routing Information Protocol\n"
1738 "Authentication control\n"
1739 "Authentication key-chain\n"
1740 "name of key-chain\n")
1742 struct interface *ifp;
1743 struct rip_interface *ri;
1745 ifp = (struct interface *) vty->index;
1746 ri = ifp->info;
1748 if (ri->auth_str)
1750 vty_out (vty, "%% authentication string configuration exists%s",
1751 VTY_NEWLINE);
1752 return CMD_WARNING;
1755 if (ri->key_chain)
1756 free (ri->key_chain);
1758 ri->key_chain = strdup (argv[0]);
1760 return CMD_SUCCESS;
1763 DEFUN (no_ip_rip_authentication_key_chain,
1764 no_ip_rip_authentication_key_chain_cmd,
1765 "no ip rip authentication key-chain",
1766 NO_STR
1767 IP_STR
1768 "Routing Information Protocol\n"
1769 "Authentication control\n"
1770 "Authentication key-chain\n")
1772 struct interface *ifp;
1773 struct rip_interface *ri;
1775 ifp = (struct interface *) vty->index;
1776 ri = ifp->info;
1778 if (ri->key_chain)
1779 free (ri->key_chain);
1781 ri->key_chain = NULL;
1783 return CMD_SUCCESS;
1786 ALIAS (no_ip_rip_authentication_key_chain,
1787 no_ip_rip_authentication_key_chain2_cmd,
1788 "no ip rip authentication key-chain LINE",
1789 NO_STR
1790 IP_STR
1791 "Routing Information Protocol\n"
1792 "Authentication control\n"
1793 "Authentication key-chain\n"
1794 "name of key-chain\n")
1796 /* CHANGED: ip rip split-horizon
1797 Cisco and Zebra's command is
1798 ip split-horizon
1800 DEFUN (ip_rip_split_horizon,
1801 ip_rip_split_horizon_cmd,
1802 "ip rip split-horizon",
1803 IP_STR
1804 "Routing Information Protocol\n"
1805 "Perform split horizon\n")
1807 struct interface *ifp;
1808 struct rip_interface *ri;
1810 ifp = vty->index;
1811 ri = ifp->info;
1813 ri->split_horizon = RIP_SPLIT_HORIZON;
1814 return CMD_SUCCESS;
1817 DEFUN (ip_rip_split_horizon_poisoned_reverse,
1818 ip_rip_split_horizon_poisoned_reverse_cmd,
1819 "ip rip split-horizon poisoned-reverse",
1820 IP_STR
1821 "Routing Information Protocol\n"
1822 "Perform split horizon\n"
1823 "With poisoned-reverse\n")
1825 struct interface *ifp;
1826 struct rip_interface *ri;
1828 ifp = vty->index;
1829 ri = ifp->info;
1831 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1832 return CMD_SUCCESS;
1835 /* CHANGED: no ip rip split-horizon
1836 Cisco and Zebra's command is
1837 no ip split-horizon
1839 DEFUN (no_ip_rip_split_horizon,
1840 no_ip_rip_split_horizon_cmd,
1841 "no ip rip split-horizon",
1842 NO_STR
1843 IP_STR
1844 "Routing Information Protocol\n"
1845 "Perform split horizon\n")
1847 struct interface *ifp;
1848 struct rip_interface *ri;
1850 ifp = vty->index;
1851 ri = ifp->info;
1853 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
1854 return CMD_SUCCESS;
1857 DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
1858 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1859 "no ip rip split-horizon poisoned-reverse",
1860 NO_STR
1861 IP_STR
1862 "Routing Information Protocol\n"
1863 "Perform split horizon\n"
1864 "With poisoned-reverse\n")
1866 struct interface *ifp;
1867 struct rip_interface *ri;
1869 ifp = vty->index;
1870 ri = ifp->info;
1872 switch( ri->split_horizon )
1874 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1875 ri->split_horizon = RIP_SPLIT_HORIZON;
1876 default:
1877 break;
1880 return CMD_SUCCESS;
1883 DEFUN (rip_passive_interface,
1884 rip_passive_interface_cmd,
1885 "passive-interface (IFNAME|default)",
1886 "Suppress routing updates on an interface\n"
1887 "Interface name\n"
1888 "default for all interfaces\n")
1890 const char *ifname = argv[0];
1892 if (!strcmp(ifname,"default")) {
1893 passive_default = 1;
1894 rip_passive_nondefault_clean();
1895 return CMD_SUCCESS;
1897 if (passive_default)
1898 return rip_passive_nondefault_unset (vty, ifname);
1899 else
1900 return rip_passive_nondefault_set (vty, ifname);
1903 DEFUN (no_rip_passive_interface,
1904 no_rip_passive_interface_cmd,
1905 "no passive-interface (IFNAME|default)",
1906 NO_STR
1907 "Suppress routing updates on an interface\n"
1908 "Interface name\n"
1909 "default for all interfaces\n")
1911 const char *ifname = argv[0];
1913 if (!strcmp(ifname,"default")) {
1914 passive_default = 0;
1915 rip_passive_nondefault_clean();
1916 return CMD_SUCCESS;
1918 if (passive_default)
1919 return rip_passive_nondefault_set (vty, ifname);
1920 else
1921 return rip_passive_nondefault_unset (vty, ifname);
1924 /* Write rip configuration of each interface. */
1925 static int
1926 rip_interface_config_write (struct vty *vty)
1928 struct listnode *node;
1929 struct interface *ifp;
1931 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
1933 struct rip_interface *ri;
1935 ri = ifp->info;
1937 /* Do not display the interface if there is no
1938 * configuration about it.
1940 if ((!ifp->desc) &&
1941 (ri->split_horizon == ri->split_horizon_default) &&
1942 (ri->ri_send == RI_RIP_UNSPEC) &&
1943 (ri->ri_receive == RI_RIP_UNSPEC) &&
1944 (ri->auth_type != RIP_AUTH_MD5) &&
1945 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
1946 (!ri->auth_str) &&
1947 (!ri->key_chain) )
1948 continue;
1950 vty_out (vty, "interface %s%s", ifp->name,
1951 VTY_NEWLINE);
1953 if (ifp->desc)
1954 vty_out (vty, " description %s%s", ifp->desc,
1955 VTY_NEWLINE);
1957 /* Split horizon. */
1958 if (ri->split_horizon != ri->split_horizon_default)
1960 switch (ri->split_horizon) {
1961 case RIP_SPLIT_HORIZON:
1962 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1963 break;
1964 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1965 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1966 VTY_NEWLINE);
1967 break;
1968 case RIP_NO_SPLIT_HORIZON:
1969 default:
1970 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1971 break;
1975 /* RIP version setting. */
1976 if (ri->ri_send != RI_RIP_UNSPEC)
1977 vty_out (vty, " ip rip send version %s%s",
1978 lookup (ri_version_msg, ri->ri_send),
1979 VTY_NEWLINE);
1981 if (ri->ri_receive != RI_RIP_UNSPEC)
1982 vty_out (vty, " ip rip receive version %s%s",
1983 lookup (ri_version_msg, ri->ri_receive),
1984 VTY_NEWLINE);
1986 /* RIP authentication. */
1987 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1988 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
1990 if (ri->auth_type == RIP_AUTH_MD5)
1992 vty_out (vty, " ip rip authentication mode md5");
1993 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1994 vty_out (vty, " auth-length old-ripd");
1995 else
1996 vty_out (vty, " auth-length rfc");
1997 vty_out (vty, "%s", VTY_NEWLINE);
2000 if (ri->auth_str)
2001 vty_out (vty, " ip rip authentication string %s%s",
2002 ri->auth_str, VTY_NEWLINE);
2004 if (ri->key_chain)
2005 vty_out (vty, " ip rip authentication key-chain %s%s",
2006 ri->key_chain, VTY_NEWLINE);
2008 vty_out (vty, "!%s", VTY_NEWLINE);
2010 return 0;
2014 config_write_rip_network (struct vty *vty, int config_mode)
2016 unsigned int i;
2017 char *ifname;
2018 struct route_node *node;
2020 /* Network type RIP enable interface statement. */
2021 for (node = route_top (rip_enable_network); node; node = route_next (node))
2022 if (node->info)
2023 vty_out (vty, "%s%s/%d%s",
2024 config_mode ? " network " : " ",
2025 inet_ntoa (node->p.u.prefix4),
2026 node->p.prefixlen,
2027 VTY_NEWLINE);
2029 /* Interface name RIP enable statement. */
2030 for (i = 0; i < vector_active (rip_enable_interface); i++)
2031 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2032 vty_out (vty, "%s%s%s",
2033 config_mode ? " network " : " ",
2034 ifname,
2035 VTY_NEWLINE);
2037 /* RIP neighbors listing. */
2038 for (node = route_top (rip->neighbor); node; node = route_next (node))
2039 if (node->info)
2040 vty_out (vty, "%s%s%s",
2041 config_mode ? " neighbor " : " ",
2042 inet_ntoa (node->p.u.prefix4),
2043 VTY_NEWLINE);
2045 /* RIP passive interface listing. */
2046 if (config_mode) {
2047 if (passive_default)
2048 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
2049 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
2050 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2051 vty_out (vty, " %spassive-interface %s%s",
2052 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2055 return 0;
2058 static struct cmd_node interface_node =
2060 INTERFACE_NODE,
2061 "%s(config-if)# ",
2065 /* Called when interface structure allocated. */
2066 static int
2067 rip_interface_new_hook (struct interface *ifp)
2069 ifp->info = rip_interface_new ();
2070 return 0;
2073 /* Called when interface structure deleted. */
2074 static int
2075 rip_interface_delete_hook (struct interface *ifp)
2077 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
2078 ifp->info = NULL;
2079 return 0;
2082 /* Allocate and initialize interface vector. */
2083 void
2084 rip_if_init (void)
2086 /* Default initial size of interface vector. */
2087 if_init();
2088 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2089 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2091 /* RIP network init. */
2092 rip_enable_interface = vector_init (1);
2093 rip_enable_network = route_table_init ();
2095 /* RIP passive interface. */
2096 Vrip_passive_nondefault = vector_init (1);
2098 /* Install interface node. */
2099 install_node (&interface_node, rip_interface_config_write);
2101 /* Install commands. */
2102 install_element (CONFIG_NODE, &interface_cmd);
2103 install_element (CONFIG_NODE, &no_interface_cmd);
2104 install_default (INTERFACE_NODE);
2105 install_element (INTERFACE_NODE, &interface_desc_cmd);
2106 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2107 install_element (RIP_NODE, &rip_network_cmd);
2108 install_element (RIP_NODE, &no_rip_network_cmd);
2109 install_element (RIP_NODE, &rip_neighbor_cmd);
2110 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2112 install_element (RIP_NODE, &rip_passive_interface_cmd);
2113 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2115 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2116 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2117 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2118 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2119 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2121 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2122 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2123 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2124 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2125 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2127 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
2128 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
2129 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2130 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
2131 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
2133 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2134 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2135 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2137 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2138 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2139 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2141 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2142 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2143 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2144 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);