]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_interface.c
2003-06-04 Paul Jakma <paul@dishone.st>
[mirror_frr.git] / ripd / rip_interface.c
1 /* Interface related function for RIP.
2 * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
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.
10 *
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.
15 *
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.
20 */
21
22 #include <zebra.h>
23
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"
38
39 #include "zebra/connected.h"
40
41 #include "ripd/ripd.h"
42 #include "ripd/rip_debug.h"
43
44 void rip_enable_apply (struct interface *);
45 void rip_passive_interface_apply (struct interface *);
46 int rip_if_down(struct interface *ifp);
47 int rip_enable_if_lookup (char *ifname);
48 int rip_enable_network_lookup2 (struct connected *connected);
49 void rip_enable_apply_all ();
50
51
52 struct message ri_version_msg[] =
53 {
54 {RI_RIP_VERSION_1, "1"},
55 {RI_RIP_VERSION_2, "2"},
56 {RI_RIP_VERSION_1_AND_2, "1 2"},
57 {0, NULL}
58 };
59
60 extern struct zebra_privs_t ripd_privs;
61
62 /* RIP enabled network vector. */
63 vector rip_enable_interface;
64
65 /* RIP enabled interface table. */
66 struct route_table *rip_enable_network;
67
68 /* Vector to store passive-interface name. */
69 vector Vrip_passive_interface;
70 \f
71 /* Join to the RIP version 2 multicast group. */
72 int
73 ipv4_multicast_join (int sock,
74 struct in_addr group,
75 struct in_addr ifa,
76 unsigned int ifindex)
77 {
78 int ret;
79
80 ret = setsockopt_multicast_ipv4 (sock,
81 IP_ADD_MEMBERSHIP,
82 ifa,
83 group.s_addr,
84 ifindex);
85
86 if (ret < 0)
87 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
88 strerror (errno));
89
90 return ret;
91 }
92
93 /* Leave from the RIP version 2 multicast group. */
94 int
95 ipv4_multicast_leave (int sock,
96 struct in_addr group,
97 struct in_addr ifa,
98 unsigned int ifindex)
99 {
100 int ret;
101
102 ret = setsockopt_multicast_ipv4 (sock,
103 IP_DROP_MEMBERSHIP,
104 ifa,
105 group.s_addr,
106 ifindex);
107
108 if (ret < 0)
109 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
110
111 return ret;
112 }
113 \f
114 /* Allocate new RIP's interface configuration. */
115 struct rip_interface *
116 rip_interface_new ()
117 {
118 struct rip_interface *ri;
119
120 ri = XMALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
121 memset (ri, 0, sizeof (struct rip_interface));
122
123 /* Default authentication type is simple password for Cisco
124 compatibility. */
125 /* ri->auth_type = RIP_NO_AUTH; */
126 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
127
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;
134
135 return ri;
136 }
137
138 void
139 rip_interface_multicast_set (int sock, struct interface *ifp)
140 {
141 int ret;
142 listnode node;
143 struct servent *sp;
144 struct sockaddr_in from;
145
146 for (node = listhead (ifp->connected); node; nextnode (node))
147 {
148 struct prefix_ipv4 *p;
149 struct connected *connected;
150 struct in_addr addr;
151
152 connected = getdata (node);
153 p = (struct prefix_ipv4 *) connected->address;
154
155 if (p->family == AF_INET)
156 {
157 addr = p->prefix;
158
159 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF,
160 addr, 0, ifp->ifindex) < 0)
161 {
162 zlog_warn ("Can't setsockopt IP_MULTICAST_IF to fd %d", sock);
163 return;
164 }
165
166 /* Bind myself. */
167 memset (&from, 0, sizeof (struct sockaddr_in));
168
169 /* Set RIP port. */
170 sp = getservbyname ("router", "udp");
171 if (sp)
172 from.sin_port = sp->s_port;
173 else
174 from.sin_port = htons (RIP_PORT_DEFAULT);
175
176 /* Address shoud be any address. */
177 from.sin_family = AF_INET;
178 from.sin_addr = addr;
179 #ifdef HAVE_SIN_LEN
180 from.sin_len = sizeof (struct sockaddr_in);
181 #endif /* HAVE_SIN_LEN */
182
183 if (ripd_privs.change (ZPRIVS_RAISE))
184 zlog_err ("rip_interface_multicast_set: could not raise privs");
185
186 ret = bind (sock, (struct sockaddr *) & from,
187 sizeof (struct sockaddr_in));
188 if (ret < 0)
189 {
190 zlog_warn ("Can't bind socket: %s", strerror (errno));
191 return;
192 }
193
194 if (ripd_privs.change (ZPRIVS_LOWER))
195 zlog_err ("rip_interface_multicast_set: could not lower privs");
196
197 return;
198
199 }
200 }
201 }
202
203 /* Send RIP request packet to specified interface. */
204 void
205 rip_request_interface_send (struct interface *ifp, u_char version)
206 {
207 struct sockaddr_in to;
208
209 /* RIPv2 support multicast. */
210 if (version == RIPv2 && if_is_multicast (ifp))
211 {
212
213 if (IS_RIP_DEBUG_EVENT)
214 zlog_info ("multicast request on %s", ifp->name);
215
216 rip_request_send (NULL, ifp, version);
217 return;
218 }
219
220 /* RIPv1 and non multicast interface. */
221 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
222 {
223 listnode cnode;
224
225 if (IS_RIP_DEBUG_EVENT)
226 zlog_info ("broadcast request to %s", ifp->name);
227
228 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
229 {
230 struct prefix_ipv4 *p;
231 struct connected *connected;
232
233 connected = getdata (cnode);
234 p = (struct prefix_ipv4 *) connected->destination;
235
236 if (p->family == AF_INET)
237 {
238 memset (&to, 0, sizeof (struct sockaddr_in));
239 to.sin_port = htons (RIP_PORT_DEFAULT);
240 to.sin_addr = p->prefix;
241
242 if (IS_RIP_DEBUG_EVENT)
243 zlog_info ("SEND request to %s", inet_ntoa (to.sin_addr));
244
245 rip_request_send (&to, ifp, version);
246 }
247 }
248 }
249 }
250
251 /* This will be executed when interface goes up. */
252 void
253 rip_request_interface (struct interface *ifp)
254 {
255 struct rip_interface *ri;
256
257 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
258 if (if_is_loopback (ifp))
259 return;
260
261 /* If interface is down, don't send RIP packet. */
262 if (! if_is_operative (ifp))
263 return;
264
265 /* Fetch RIP interface information. */
266 ri = ifp->info;
267
268
269 /* If there is no version configuration in the interface,
270 use rip's version setting. */
271 if (ri->ri_send == RI_RIP_UNSPEC)
272 {
273 if (rip->version == RIPv1)
274 rip_request_interface_send (ifp, RIPv1);
275 else
276 rip_request_interface_send (ifp, RIPv2);
277 }
278 /* If interface has RIP version configuration use it. */
279 else
280 {
281 if (ri->ri_send & RIPv1)
282 rip_request_interface_send (ifp, RIPv1);
283 if (ri->ri_send & RIPv2)
284 rip_request_interface_send (ifp, RIPv2);
285 }
286 }
287
288 /* Send RIP request to the neighbor. */
289 void
290 rip_request_neighbor (struct in_addr addr)
291 {
292 struct sockaddr_in to;
293
294 memset (&to, 0, sizeof (struct sockaddr_in));
295 to.sin_port = htons (RIP_PORT_DEFAULT);
296 to.sin_addr = addr;
297
298 rip_request_send (&to, NULL, rip->version);
299 }
300
301 /* Request routes at all interfaces. */
302 void
303 rip_request_neighbor_all ()
304 {
305 struct route_node *rp;
306
307 if (! rip)
308 return;
309
310 if (IS_RIP_DEBUG_EVENT)
311 zlog_info ("request to the all neighbor");
312
313 /* Send request to all neighbor. */
314 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
315 if (rp->info)
316 rip_request_neighbor (rp->p.u.prefix4);
317 }
318
319 /* Multicast packet receive socket. */
320 int
321 rip_multicast_join (struct interface *ifp, int sock)
322 {
323 listnode cnode;
324
325 if (if_is_operative (ifp) && if_is_multicast (ifp))
326 {
327 if (IS_RIP_DEBUG_EVENT)
328 zlog_info ("multicast join at %s", ifp->name);
329
330 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
331 {
332 struct prefix_ipv4 *p;
333 struct connected *connected;
334 struct in_addr group;
335
336 connected = getdata (cnode);
337 p = (struct prefix_ipv4 *) connected->address;
338
339 if (p->family != AF_INET)
340 continue;
341
342 group.s_addr = htonl (INADDR_RIP_GROUP);
343 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
344 return -1;
345 else
346 return 0;
347 }
348 }
349 return 0;
350 }
351
352 /* Leave from multicast group. */
353 void
354 rip_multicast_leave (struct interface *ifp, int sock)
355 {
356 listnode cnode;
357
358 if (if_is_up (ifp) && if_is_multicast (ifp))
359 {
360 if (IS_RIP_DEBUG_EVENT)
361 zlog_info ("multicast leave from %s", ifp->name);
362
363 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
364 {
365 struct prefix_ipv4 *p;
366 struct connected *connected;
367 struct in_addr group;
368
369 connected = getdata (cnode);
370 p = (struct prefix_ipv4 *) connected->address;
371
372 if (p->family != AF_INET)
373 continue;
374
375 group.s_addr = htonl (INADDR_RIP_GROUP);
376 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
377 return;
378 }
379 }
380 }
381
382 /* Is there and address on interface that I could use ? */
383 int
384 rip_if_ipv4_address_check (struct interface *ifp)
385 {
386 struct listnode *nn;
387 struct connected *connected;
388 int count = 0;
389
390 for (nn = listhead (ifp->connected); nn; nextnode (nn))
391 if ((connected = getdata (nn)) != NULL)
392 {
393 struct prefix *p;
394
395 p = connected->address;
396
397 if (p->family == AF_INET)
398 {
399 count++;
400 }
401 }
402
403 return count;
404 }
405
406 /* Inteface link down message processing. */
407 int
408 rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
409 {
410 struct interface *ifp;
411 struct stream *s;
412
413 s = zclient->ibuf;
414
415 /* zebra_interface_state_read() updates interface structure in
416 iflist. */
417 ifp = zebra_interface_state_read(s);
418
419 if (ifp == NULL)
420 return 0;
421
422 rip_if_down(ifp);
423
424 if (IS_RIP_DEBUG_ZEBRA)
425 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is down",
426 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
427
428 return 0;
429 }
430
431 /* Inteface link up message processing */
432 int
433 rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
434 {
435 struct interface *ifp;
436
437 /* zebra_interface_state_read () updates interface structure in
438 iflist. */
439 ifp = zebra_interface_state_read (zclient->ibuf);
440
441 if (ifp == NULL)
442 return 0;
443
444 if (IS_RIP_DEBUG_ZEBRA)
445 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is up",
446 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
447
448 /* Check if this interface is RIP enabled or not.*/
449 rip_enable_apply (ifp);
450
451 /* Check for a passive interface */
452 rip_passive_interface_apply (ifp);
453
454 /* Apply distribute list to the all interface. */
455 rip_distribute_update_interface (ifp);
456
457 return 0;
458 }
459
460 /* Inteface addition message from zebra. */
461 int
462 rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
463 {
464 struct interface *ifp;
465
466 ifp = zebra_interface_add_read (zclient->ibuf);
467
468 if (IS_RIP_DEBUG_ZEBRA)
469 zlog_info ("interface add %s index %d flags %ld metric %d mtu %d",
470 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
471
472 /* Check if this interface is RIP enabled or not.*/
473 rip_enable_apply (ifp);
474
475 /* Apply distribute list to the all interface. */
476 rip_distribute_update_interface (ifp);
477
478 /* rip_request_neighbor_all (); */
479
480 /* Check interface routemap. */
481 rip_if_rmap_update_interface (ifp);
482
483 return 0;
484 }
485
486 int
487 rip_interface_delete (int command, struct zclient *zclient,
488 zebra_size_t length)
489 {
490 struct interface *ifp;
491 struct stream *s;
492
493
494 s = zclient->ibuf;
495 /* zebra_interface_state_read() updates interface structure in iflist */
496 ifp = zebra_interface_state_read(s);
497
498 if (ifp == NULL)
499 return 0;
500
501 if (if_is_up (ifp)) {
502 rip_if_down(ifp);
503 }
504
505 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
506 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
507
508 /* To support pseudo interface do not free interface structure. */
509 /* if_delete(ifp); */
510
511 return 0;
512 }
513
514 void
515 rip_interface_clean ()
516 {
517 listnode node;
518 struct interface *ifp;
519 struct rip_interface *ri;
520
521 for (node = listhead (iflist); node; nextnode (node))
522 {
523 ifp = getdata (node);
524 ri = ifp->info;
525
526 ri->enable_network = 0;
527 ri->enable_interface = 0;
528 ri->running = 0;
529
530 if (ri->t_wakeup)
531 {
532 thread_cancel (ri->t_wakeup);
533 ri->t_wakeup = NULL;
534 }
535 }
536 }
537
538 void
539 rip_interface_reset ()
540 {
541 listnode node;
542 struct interface *ifp;
543 struct rip_interface *ri;
544
545 for (node = listhead (iflist); node; nextnode (node))
546 {
547 ifp = getdata (node);
548 ri = ifp->info;
549
550 ri->enable_network = 0;
551 ri->enable_interface = 0;
552 ri->running = 0;
553
554 ri->ri_send = RI_RIP_UNSPEC;
555 ri->ri_receive = RI_RIP_UNSPEC;
556
557 /* ri->auth_type = RIP_NO_AUTH; */
558 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
559
560 if (ri->auth_str)
561 {
562 free (ri->auth_str);
563 ri->auth_str = NULL;
564 }
565 if (ri->key_chain)
566 {
567 free (ri->key_chain);
568 ri->key_chain = NULL;
569 }
570
571 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
572 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
573
574 ri->list[RIP_FILTER_IN] = NULL;
575 ri->list[RIP_FILTER_OUT] = NULL;
576
577 ri->prefix[RIP_FILTER_IN] = NULL;
578 ri->prefix[RIP_FILTER_OUT] = NULL;
579
580 if (ri->t_wakeup)
581 {
582 thread_cancel (ri->t_wakeup);
583 ri->t_wakeup = NULL;
584 }
585
586 ri->recv_badpackets = 0;
587 ri->recv_badroutes = 0;
588 ri->sent_updates = 0;
589
590 ri->passive = 0;
591 }
592 }
593
594 int
595 rip_if_down(struct interface *ifp)
596 {
597 struct route_node *rp;
598 struct rip_info *rinfo;
599 struct rip_interface *ri = NULL;
600 if (rip)
601 {
602 for (rp = route_top (rip->table); rp; rp = route_next (rp))
603 if ((rinfo = rp->info) != NULL)
604 {
605 /* Routes got through this interface. */
606 if (rinfo->ifindex == ifp->ifindex &&
607 rinfo->type == ZEBRA_ROUTE_RIP &&
608 rinfo->sub_type == RIP_ROUTE_RTE)
609 {
610 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
611 &rinfo->nexthop,
612 rinfo->ifindex);
613
614 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
615 (struct prefix_ipv4 *)&rp->p,
616 rinfo->ifindex);
617 }
618 else
619 {
620 /* All redistributed routes but static and system */
621 if ((rinfo->ifindex == ifp->ifindex) &&
622 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
623 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
624 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
625 (struct prefix_ipv4 *)&rp->p,
626 rinfo->ifindex);
627 }
628 }
629 }
630
631 ri = ifp->info;
632
633 if (ri->running)
634 {
635 if (IS_RIP_DEBUG_EVENT)
636 zlog_info ("turn off %s", ifp->name);
637
638 /* Leave from multicast group. */
639 rip_multicast_leave (ifp, rip->sock);
640
641 ri->running = 0;
642 }
643
644 return 0;
645 }
646
647 /* Needed for stop RIP process. */
648 void
649 rip_if_down_all ()
650 {
651 struct interface *ifp;
652 listnode node;
653
654 for (node = listhead (iflist); node; nextnode (node))
655 {
656 ifp = getdata (node);
657 rip_if_down (ifp);
658 }
659 }
660
661 static void
662 rip_apply_address_add (struct connected *ifc) {
663 struct prefix_ipv4 address;
664 struct prefix *p;
665
666 if (!rip)
667 return;
668
669 if (! if_is_up(ifc->ifp))
670 return;
671
672 p = ifc->address;
673
674 memset (&address, 0, sizeof (address));
675 address.family = p->family;
676 address.prefix = p->u.prefix4;
677 address.prefixlen = p->prefixlen;
678 apply_mask_ipv4(&address);
679
680 /* Check if this interface is RIP enabled or not
681 or Check if this address's prefix is RIP enabled */
682 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
683 (rip_enable_network_lookup2(ifc) >= 0))
684 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
685 &address, ifc->ifp->ifindex, NULL);
686
687 }
688
689 int
690 rip_interface_address_add (int command, struct zclient *zclient,
691 zebra_size_t length)
692 {
693 struct connected *ifc;
694 struct prefix *p;
695
696 ifc = zebra_interface_address_add_read (zclient->ibuf);
697
698 if (ifc == NULL)
699 return 0;
700
701 p = ifc->address;
702
703 if (p->family == AF_INET)
704 {
705 if (IS_RIP_DEBUG_ZEBRA)
706 zlog_info ("connected address %s/%d is added",
707 inet_ntoa (p->u.prefix4), p->prefixlen);
708
709 /* Check if this prefix needs to be redistributed */
710 rip_apply_address_add(ifc);
711
712 #ifdef HAVE_SNMP
713 rip_ifaddr_add (ifc->ifp, ifc);
714 #endif /* HAVE_SNMP */
715 }
716
717 return 0;
718 }
719
720 static void
721 rip_apply_address_del (struct connected *ifc) {
722 struct prefix_ipv4 address;
723 struct prefix *p;
724
725 if (!rip)
726 return;
727
728 if (! if_is_up(ifc->ifp))
729 return;
730
731 p = ifc->address;
732
733 memset (&address, 0, sizeof (address));
734 address.family = p->family;
735 address.prefix = p->u.prefix4;
736 address.prefixlen = p->prefixlen;
737 apply_mask_ipv4(&address);
738
739 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
740 &address, ifc->ifp->ifindex);
741 }
742
743 int
744 rip_interface_address_delete (int command, struct zclient *zclient,
745 zebra_size_t length)
746 {
747 struct connected *ifc;
748 struct prefix *p;
749
750 ifc = zebra_interface_address_delete_read (zclient->ibuf);
751
752 if (ifc)
753 {
754 p = ifc->address;
755 if (p->family == AF_INET)
756 {
757 if (IS_RIP_DEBUG_ZEBRA)
758
759 zlog_info ("connected address %s/%d is deleted",
760 inet_ntoa (p->u.prefix4), p->prefixlen);
761
762 #ifdef HAVE_SNMP
763 rip_ifaddr_delete (ifc->ifp, ifc);
764 #endif /* HAVE_SNMP */
765
766 /* Chech wether this prefix needs to be removed */
767 rip_apply_address_del(ifc);
768
769 }
770
771 connected_free (ifc);
772
773 }
774
775 return 0;
776 }
777 \f
778 /* Check interface is enabled by network statement. */
779 /* Check wether the interface has at least a connected prefix that
780 * is within the ripng_enable_network table. */
781 int
782 rip_enable_network_lookup_if (struct interface *ifp)
783 {
784 struct listnode *nn;
785 struct connected *connected;
786 struct prefix_ipv4 address;
787
788 for (nn = listhead (ifp->connected); nn; nextnode (nn))
789 if ((connected = getdata (nn)) != NULL)
790 {
791 struct prefix *p;
792 struct route_node *node;
793
794 p = connected->address;
795
796 if (p->family == AF_INET)
797 {
798 address.family = AF_INET;
799 address.prefix = p->u.prefix4;
800 address.prefixlen = IPV4_MAX_BITLEN;
801
802 node = route_node_match (rip_enable_network,
803 (struct prefix *)&address);
804 if (node)
805 {
806 route_unlock_node (node);
807 return 1;
808 }
809 }
810 }
811 return -1;
812 }
813
814 /* Check wether connected is within the ripng_enable_network table. */
815 int
816 rip_enable_network_lookup2 (struct connected *connected)
817 {
818 struct prefix_ipv4 address;
819 struct prefix *p;
820
821 p = connected->address;
822
823 if (p->family == AF_INET) {
824 struct route_node *node;
825
826 address.family = p->family;
827 address.prefix = p->u.prefix4;
828 address.prefixlen = IPV4_MAX_BITLEN;
829
830 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
831 node = route_node_match (rip_enable_network,
832 (struct prefix *)&address);
833
834 if (node) {
835 route_unlock_node (node);
836 return 1;
837 }
838 }
839
840 return -1;
841 }
842 /* Add RIP enable network. */
843 int
844 rip_enable_network_add (struct prefix *p)
845 {
846 struct route_node *node;
847
848 node = route_node_get (rip_enable_network, p);
849
850 if (node->info)
851 {
852 route_unlock_node (node);
853 return -1;
854 }
855 else
856 node->info = "enabled";
857
858 /* XXX: One should find a better solution than a generic one */
859 rip_enable_apply_all();
860
861 return 1;
862 }
863
864 /* Delete RIP enable network. */
865 int
866 rip_enable_network_delete (struct prefix *p)
867 {
868 struct route_node *node;
869
870 node = route_node_lookup (rip_enable_network, p);
871 if (node)
872 {
873 node->info = NULL;
874
875 /* Unlock info lock. */
876 route_unlock_node (node);
877
878 /* Unlock lookup lock. */
879 route_unlock_node (node);
880
881 /* XXX: One should find a better solution than a generic one */
882 rip_enable_apply_all ();
883
884 return 1;
885 }
886 return -1;
887 }
888
889 /* Check interface is enabled by ifname statement. */
890 int
891 rip_enable_if_lookup (char *ifname)
892 {
893 int i;
894 char *str;
895
896 for (i = 0; i < vector_max (rip_enable_interface); i++)
897 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
898 if (strcmp (str, ifname) == 0)
899 return i;
900 return -1;
901 }
902
903 /* Add interface to rip_enable_if. */
904 int
905 rip_enable_if_add (char *ifname)
906 {
907 int ret;
908
909 ret = rip_enable_if_lookup (ifname);
910 if (ret >= 0)
911 return -1;
912
913 vector_set (rip_enable_interface, strdup (ifname));
914
915 rip_enable_apply_all(); /* TODOVJ */
916
917 return 1;
918 }
919
920 /* Delete interface from rip_enable_if. */
921 int
922 rip_enable_if_delete (char *ifname)
923 {
924 int index;
925 char *str;
926
927 index = rip_enable_if_lookup (ifname);
928 if (index < 0)
929 return -1;
930
931 str = vector_slot (rip_enable_interface, index);
932 free (str);
933 vector_unset (rip_enable_interface, index);
934
935 rip_enable_apply_all(); /* TODOVJ */
936
937 return 1;
938 }
939
940 /* Join to multicast group and send request to the interface. */
941 int
942 rip_interface_wakeup (struct thread *t)
943 {
944 struct interface *ifp;
945 struct rip_interface *ri;
946
947 /* Get interface. */
948 ifp = THREAD_ARG (t);
949
950 ri = ifp->info;
951 ri->t_wakeup = NULL;
952
953 /* Join to multicast group. */
954 if (rip_multicast_join (ifp, rip->sock) < 0)
955 {
956 zlog_err ("multicast join failed, interface %s not running", ifp->name);
957 return 0;
958 }
959
960 /* Set running flag. */
961 ri->running = 1;
962
963 /* Send RIP request to the interface. */
964 rip_request_interface (ifp);
965
966 return 0;
967 }
968
969 int rip_redistribute_check (int);
970
971 void
972 rip_connect_set (struct interface *ifp, int set)
973 {
974 struct listnode *nn;
975 struct connected *connected;
976 struct prefix_ipv4 address;
977
978 for (nn = listhead (ifp->connected); nn; nextnode (nn))
979 if ((connected = getdata (nn)) != NULL)
980 {
981 struct prefix *p;
982 p = connected->address;
983
984 if (p->family != AF_INET)
985 continue;
986
987 address.family = AF_INET;
988 address.prefix = p->u.prefix4;
989 address.prefixlen = p->prefixlen;
990 apply_mask_ipv4 (&address);
991
992 if (set) {
993 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
994 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
995 (rip_enable_network_lookup2(connected) >= 0))
996 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
997 &address, connected->ifp->ifindex, NULL);
998 } else
999 {
1000 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1001 &address, connected->ifp->ifindex);
1002 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1003 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1004 &address, connected->ifp->ifindex, NULL);
1005 }
1006 }
1007 }
1008
1009 /* Update interface status. */
1010 void
1011 rip_enable_apply (struct interface *ifp)
1012 {
1013 int ret;
1014 struct rip_interface *ri = NULL;
1015
1016 /* Check interface. */
1017 if (! if_is_operative (ifp))
1018 return;
1019
1020 ri = ifp->info;
1021
1022 /* Check network configuration. */
1023 ret = rip_enable_network_lookup_if (ifp);
1024
1025 /* If the interface is matched. */
1026 if (ret > 0)
1027 ri->enable_network = 1;
1028 else
1029 ri->enable_network = 0;
1030
1031 /* Check interface name configuration. */
1032 ret = rip_enable_if_lookup (ifp->name);
1033 if (ret >= 0)
1034 ri->enable_interface = 1;
1035 else
1036 ri->enable_interface = 0;
1037
1038 /* any interface MUST have an IPv4 address */
1039 if ( ! rip_if_ipv4_address_check (ifp) )
1040 {
1041 ri->enable_network = 0;
1042 ri->enable_interface = 0;
1043 }
1044
1045 /* Update running status of the interface. */
1046 if (ri->enable_network || ri->enable_interface)
1047 {
1048 {
1049 if (IS_RIP_DEBUG_EVENT)
1050 zlog_info ("turn on %s", ifp->name);
1051
1052 /* Add interface wake up thread. */
1053 if (! ri->t_wakeup)
1054 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1055 ifp, 1);
1056 rip_connect_set (ifp, 1);
1057 }
1058 }
1059 else
1060 {
1061 if (ri->running)
1062 {
1063 /* Might as well clean up the route table as well
1064 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1065 **/
1066 rip_if_down(ifp);
1067
1068 rip_connect_set (ifp, 0);
1069 }
1070 }
1071 }
1072
1073 /* Apply network configuration to all interface. */
1074 void
1075 rip_enable_apply_all ()
1076 {
1077 struct interface *ifp;
1078 listnode node;
1079
1080 /* Check each interface. */
1081 for (node = listhead (iflist); node; nextnode (node))
1082 {
1083 ifp = getdata (node);
1084 rip_enable_apply (ifp);
1085 }
1086 }
1087
1088 int
1089 rip_neighbor_lookup (struct sockaddr_in *from)
1090 {
1091 struct prefix_ipv4 p;
1092 struct route_node *node;
1093
1094 memset (&p, 0, sizeof (struct prefix_ipv4));
1095 p.family = AF_INET;
1096 p.prefix = from->sin_addr;
1097 p.prefixlen = IPV4_MAX_BITLEN;
1098
1099 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1100 if (node)
1101 {
1102 route_unlock_node (node);
1103 return 1;
1104 }
1105 return 0;
1106 }
1107
1108 /* Add new RIP neighbor to the neighbor tree. */
1109 int
1110 rip_neighbor_add (struct prefix_ipv4 *p)
1111 {
1112 struct route_node *node;
1113
1114 node = route_node_get (rip->neighbor, (struct prefix *) p);
1115
1116 if (node->info)
1117 return -1;
1118
1119 node->info = rip->neighbor;
1120
1121 return 0;
1122 }
1123
1124 /* Delete RIP neighbor from the neighbor tree. */
1125 int
1126 rip_neighbor_delete (struct prefix_ipv4 *p)
1127 {
1128 struct route_node *node;
1129
1130 /* Lock for look up. */
1131 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1132 if (! node)
1133 return -1;
1134
1135 node->info = NULL;
1136
1137 /* Unlock lookup lock. */
1138 route_unlock_node (node);
1139
1140 /* Unlock real neighbor information lock. */
1141 route_unlock_node (node);
1142
1143 return 0;
1144 }
1145
1146 /* Clear all network and neighbor configuration. */
1147 void
1148 rip_clean_network ()
1149 {
1150 int i;
1151 char *str;
1152 struct route_node *rn;
1153
1154 /* rip_enable_network. */
1155 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1156 if (rn->info)
1157 {
1158 rn->info = NULL;
1159 route_unlock_node (rn);
1160 }
1161
1162 /* rip_enable_interface. */
1163 for (i = 0; i < vector_max (rip_enable_interface); i++)
1164 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1165 {
1166 free (str);
1167 vector_slot (rip_enable_interface, i) = NULL;
1168 }
1169 }
1170 \f
1171 /* Utility function for looking up passive interface settings. */
1172 int
1173 rip_passive_interface_lookup (char *ifname)
1174 {
1175 int i;
1176 char *str;
1177
1178 for (i = 0; i < vector_max (Vrip_passive_interface); i++)
1179 if ((str = vector_slot (Vrip_passive_interface, i)) != NULL)
1180 if (strcmp (str, ifname) == 0)
1181 return i;
1182 return -1;
1183 }
1184
1185 void
1186 rip_passive_interface_apply (struct interface *ifp)
1187 {
1188 int ret;
1189 struct rip_interface *ri;
1190
1191 ri = ifp->info;
1192
1193 ret = rip_passive_interface_lookup (ifp->name);
1194 if (ret < 0)
1195 ri->passive = 0;
1196 else
1197 ri->passive = 1;
1198 }
1199
1200 void
1201 rip_passive_interface_apply_all ()
1202 {
1203 struct interface *ifp;
1204 listnode node;
1205
1206 for (node = listhead (iflist); node; nextnode (node))
1207 {
1208 ifp = getdata (node);
1209 rip_passive_interface_apply (ifp);
1210 }
1211 }
1212
1213 /* Passive interface. */
1214 int
1215 rip_passive_interface_set (struct vty *vty, char *ifname)
1216 {
1217 if (rip_passive_interface_lookup (ifname) >= 0)
1218 return CMD_WARNING;
1219
1220 vector_set (Vrip_passive_interface, strdup (ifname));
1221
1222 rip_passive_interface_apply_all ();
1223
1224 return CMD_SUCCESS;
1225 }
1226
1227 int
1228 rip_passive_interface_unset (struct vty *vty, char *ifname)
1229 {
1230 int i;
1231 char *str;
1232
1233 i = rip_passive_interface_lookup (ifname);
1234 if (i < 0)
1235 return CMD_WARNING;
1236
1237 str = vector_slot (Vrip_passive_interface, i);
1238 free (str);
1239 vector_unset (Vrip_passive_interface, i);
1240
1241 rip_passive_interface_apply_all ();
1242
1243 return CMD_SUCCESS;
1244 }
1245
1246 /* Free all configured RIP passive-interface settings. */
1247 void
1248 rip_passive_interface_clean ()
1249 {
1250 int i;
1251 char *str;
1252
1253 for (i = 0; i < vector_max (Vrip_passive_interface); i++)
1254 if ((str = vector_slot (Vrip_passive_interface, i)) != NULL)
1255 {
1256 free (str);
1257 vector_slot (Vrip_passive_interface, i) = NULL;
1258 }
1259 rip_passive_interface_apply_all ();
1260 }
1261 \f
1262 /* RIP enable network or interface configuration. */
1263 DEFUN (rip_network,
1264 rip_network_cmd,
1265 "network (A.B.C.D/M|WORD)",
1266 "Enable routing on an IP network\n"
1267 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1268 "Interface name\n")
1269 {
1270 int ret;
1271 struct prefix_ipv4 p;
1272
1273 ret = str2prefix_ipv4 (argv[0], &p);
1274
1275 if (ret)
1276 ret = rip_enable_network_add ((struct prefix *) &p);
1277 else
1278 ret = rip_enable_if_add (argv[0]);
1279
1280 if (ret < 0)
1281 {
1282 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1283 VTY_NEWLINE);
1284 return CMD_WARNING;
1285 }
1286
1287 return CMD_SUCCESS;
1288 }
1289
1290 /* RIP enable network or interface configuration. */
1291 DEFUN (no_rip_network,
1292 no_rip_network_cmd,
1293 "no network (A.B.C.D/M|WORD)",
1294 NO_STR
1295 "Enable routing on an IP network\n"
1296 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1297 "Interface name\n")
1298 {
1299 int ret;
1300 struct prefix_ipv4 p;
1301
1302 ret = str2prefix_ipv4 (argv[0], &p);
1303
1304 if (ret)
1305 ret = rip_enable_network_delete ((struct prefix *) &p);
1306 else
1307 ret = rip_enable_if_delete (argv[0]);
1308
1309 if (ret < 0)
1310 {
1311 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1312 VTY_NEWLINE);
1313 return CMD_WARNING;
1314 }
1315
1316 return CMD_SUCCESS;
1317 }
1318
1319 /* RIP neighbor configuration set. */
1320 DEFUN (rip_neighbor,
1321 rip_neighbor_cmd,
1322 "neighbor A.B.C.D",
1323 "Specify a neighbor router\n"
1324 "Neighbor address\n")
1325 {
1326 int ret;
1327 struct prefix_ipv4 p;
1328
1329 ret = str2prefix_ipv4 (argv[0], &p);
1330
1331 if (ret <= 0)
1332 {
1333 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1334 return CMD_WARNING;
1335 }
1336
1337 rip_neighbor_add (&p);
1338
1339 return CMD_SUCCESS;
1340 }
1341
1342 /* RIP neighbor configuration unset. */
1343 DEFUN (no_rip_neighbor,
1344 no_rip_neighbor_cmd,
1345 "no neighbor A.B.C.D",
1346 NO_STR
1347 "Specify a neighbor router\n"
1348 "Neighbor address\n")
1349 {
1350 int ret;
1351 struct prefix_ipv4 p;
1352
1353 ret = str2prefix_ipv4 (argv[0], &p);
1354
1355 if (ret <= 0)
1356 {
1357 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1358 return CMD_WARNING;
1359 }
1360
1361 rip_neighbor_delete (&p);
1362
1363 return CMD_SUCCESS;
1364 }
1365
1366 DEFUN (ip_rip_receive_version,
1367 ip_rip_receive_version_cmd,
1368 "ip rip receive version (1|2)",
1369 IP_STR
1370 "Routing Information Protocol\n"
1371 "Advertisement reception\n"
1372 "Version control\n"
1373 "RIP version 1\n"
1374 "RIP version 2\n")
1375 {
1376 struct interface *ifp;
1377 struct rip_interface *ri;
1378
1379 ifp = (struct interface *)vty->index;
1380 ri = ifp->info;
1381
1382 /* Version 1. */
1383 if (atoi (argv[0]) == 1)
1384 {
1385 ri->ri_receive = RI_RIP_VERSION_1;
1386 return CMD_SUCCESS;
1387 }
1388 if (atoi (argv[0]) == 2)
1389 {
1390 ri->ri_receive = RI_RIP_VERSION_2;
1391 return CMD_SUCCESS;
1392 }
1393 return CMD_WARNING;
1394 }
1395
1396 DEFUN (ip_rip_receive_version_1,
1397 ip_rip_receive_version_1_cmd,
1398 "ip rip receive version 1 2",
1399 IP_STR
1400 "Routing Information Protocol\n"
1401 "Advertisement reception\n"
1402 "Version control\n"
1403 "RIP version 1\n"
1404 "RIP version 2\n")
1405 {
1406 struct interface *ifp;
1407 struct rip_interface *ri;
1408
1409 ifp = (struct interface *)vty->index;
1410 ri = ifp->info;
1411
1412 /* Version 1 and 2. */
1413 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1414 return CMD_SUCCESS;
1415 }
1416
1417 DEFUN (ip_rip_receive_version_2,
1418 ip_rip_receive_version_2_cmd,
1419 "ip rip receive version 2 1",
1420 IP_STR
1421 "Routing Information Protocol\n"
1422 "Advertisement reception\n"
1423 "Version control\n"
1424 "RIP version 2\n"
1425 "RIP version 1\n")
1426 {
1427 struct interface *ifp;
1428 struct rip_interface *ri;
1429
1430 ifp = (struct interface *)vty->index;
1431 ri = ifp->info;
1432
1433 /* Version 1 and 2. */
1434 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1435 return CMD_SUCCESS;
1436 }
1437
1438 DEFUN (no_ip_rip_receive_version,
1439 no_ip_rip_receive_version_cmd,
1440 "no ip rip receive version",
1441 NO_STR
1442 IP_STR
1443 "Routing Information Protocol\n"
1444 "Advertisement reception\n"
1445 "Version control\n")
1446 {
1447 struct interface *ifp;
1448 struct rip_interface *ri;
1449
1450 ifp = (struct interface *)vty->index;
1451 ri = ifp->info;
1452
1453 ri->ri_receive = RI_RIP_UNSPEC;
1454 return CMD_SUCCESS;
1455 }
1456
1457 ALIAS (no_ip_rip_receive_version,
1458 no_ip_rip_receive_version_num_cmd,
1459 "no ip rip receive version (1|2)",
1460 NO_STR
1461 IP_STR
1462 "Routing Information Protocol\n"
1463 "Advertisement reception\n"
1464 "Version control\n"
1465 "Version 1\n"
1466 "Version 2\n")
1467
1468 DEFUN (ip_rip_send_version,
1469 ip_rip_send_version_cmd,
1470 "ip rip send version (1|2)",
1471 IP_STR
1472 "Routing Information Protocol\n"
1473 "Advertisement transmission\n"
1474 "Version control\n"
1475 "RIP version 1\n"
1476 "RIP version 2\n")
1477 {
1478 struct interface *ifp;
1479 struct rip_interface *ri;
1480
1481 ifp = (struct interface *)vty->index;
1482 ri = ifp->info;
1483
1484 /* Version 1. */
1485 if (atoi (argv[0]) == 1)
1486 {
1487 ri->ri_send = RI_RIP_VERSION_1;
1488 return CMD_SUCCESS;
1489 }
1490 if (atoi (argv[0]) == 2)
1491 {
1492 ri->ri_send = RI_RIP_VERSION_2;
1493 return CMD_SUCCESS;
1494 }
1495 return CMD_WARNING;
1496 }
1497
1498 DEFUN (ip_rip_send_version_1,
1499 ip_rip_send_version_1_cmd,
1500 "ip rip send version 1 2",
1501 IP_STR
1502 "Routing Information Protocol\n"
1503 "Advertisement transmission\n"
1504 "Version control\n"
1505 "RIP version 1\n"
1506 "RIP version 2\n")
1507 {
1508 struct interface *ifp;
1509 struct rip_interface *ri;
1510
1511 ifp = (struct interface *)vty->index;
1512 ri = ifp->info;
1513
1514 /* Version 1 and 2. */
1515 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1516 return CMD_SUCCESS;
1517 }
1518
1519 DEFUN (ip_rip_send_version_2,
1520 ip_rip_send_version_2_cmd,
1521 "ip rip send version 2 1",
1522 IP_STR
1523 "Routing Information Protocol\n"
1524 "Advertisement transmission\n"
1525 "Version control\n"
1526 "RIP version 2\n"
1527 "RIP version 1\n")
1528 {
1529 struct interface *ifp;
1530 struct rip_interface *ri;
1531
1532 ifp = (struct interface *)vty->index;
1533 ri = ifp->info;
1534
1535 /* Version 1 and 2. */
1536 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1537 return CMD_SUCCESS;
1538 }
1539
1540 DEFUN (no_ip_rip_send_version,
1541 no_ip_rip_send_version_cmd,
1542 "no ip rip send version",
1543 NO_STR
1544 IP_STR
1545 "Routing Information Protocol\n"
1546 "Advertisement transmission\n"
1547 "Version control\n")
1548 {
1549 struct interface *ifp;
1550 struct rip_interface *ri;
1551
1552 ifp = (struct interface *)vty->index;
1553 ri = ifp->info;
1554
1555 ri->ri_send = RI_RIP_UNSPEC;
1556 return CMD_SUCCESS;
1557 }
1558
1559 ALIAS (no_ip_rip_send_version,
1560 no_ip_rip_send_version_num_cmd,
1561 "no ip rip send version (1|2)",
1562 NO_STR
1563 IP_STR
1564 "Routing Information Protocol\n"
1565 "Advertisement transmission\n"
1566 "Version control\n"
1567 "Version 1\n"
1568 "Version 2\n")
1569
1570 DEFUN (ip_rip_authentication_mode,
1571 ip_rip_authentication_mode_cmd,
1572 "ip rip authentication mode (md5|text)",
1573 IP_STR
1574 "Routing Information Protocol\n"
1575 "Authentication control\n"
1576 "Authentication mode\n"
1577 "Keyed message digest\n"
1578 "Clear text authentication\n")
1579 {
1580 struct interface *ifp;
1581 struct rip_interface *ri;
1582
1583 ifp = (struct interface *)vty->index;
1584 ri = ifp->info;
1585
1586 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1587 ri->auth_type = RIP_AUTH_MD5;
1588 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1589 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1590 else
1591 {
1592 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1593 return CMD_WARNING;
1594 }
1595
1596 return CMD_SUCCESS;
1597 }
1598
1599 DEFUN (no_ip_rip_authentication_mode,
1600 no_ip_rip_authentication_mode_cmd,
1601 "no ip rip authentication mode",
1602 NO_STR
1603 IP_STR
1604 "Routing Information Protocol\n"
1605 "Authentication control\n"
1606 "Authentication mode\n")
1607 {
1608 struct interface *ifp;
1609 struct rip_interface *ri;
1610
1611 ifp = (struct interface *)vty->index;
1612 ri = ifp->info;
1613
1614 /* ri->auth_type = RIP_NO_AUTH; */
1615 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1616
1617 return CMD_SUCCESS;
1618 }
1619
1620 ALIAS (no_ip_rip_authentication_mode,
1621 no_ip_rip_authentication_mode_type_cmd,
1622 "no ip rip authentication mode (md5|text)",
1623 NO_STR
1624 IP_STR
1625 "Routing Information Protocol\n"
1626 "Authentication control\n"
1627 "Authentication mode\n"
1628 "Keyed message digest\n"
1629 "Clear text authentication\n")
1630
1631 DEFUN (ip_rip_authentication_string,
1632 ip_rip_authentication_string_cmd,
1633 "ip rip authentication string LINE",
1634 IP_STR
1635 "Routing Information Protocol\n"
1636 "Authentication control\n"
1637 "Authentication string\n"
1638 "Authentication string\n")
1639 {
1640 struct interface *ifp;
1641 struct rip_interface *ri;
1642
1643 ifp = (struct interface *)vty->index;
1644 ri = ifp->info;
1645
1646 if (strlen (argv[0]) > 16)
1647 {
1648 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1649 VTY_NEWLINE);
1650 return CMD_WARNING;
1651 }
1652
1653 if (ri->key_chain)
1654 {
1655 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1656 return CMD_WARNING;
1657 }
1658
1659 if (ri->auth_str)
1660 free (ri->auth_str);
1661
1662 ri->auth_str = strdup (argv[0]);
1663
1664 return CMD_SUCCESS;
1665 }
1666
1667 DEFUN (no_ip_rip_authentication_string,
1668 no_ip_rip_authentication_string_cmd,
1669 "no ip rip authentication string",
1670 NO_STR
1671 IP_STR
1672 "Routing Information Protocol\n"
1673 "Authentication control\n"
1674 "Authentication string\n")
1675 {
1676 struct interface *ifp;
1677 struct rip_interface *ri;
1678
1679 ifp = (struct interface *)vty->index;
1680 ri = ifp->info;
1681
1682 if (ri->auth_str)
1683 free (ri->auth_str);
1684
1685 ri->auth_str = NULL;
1686
1687 return CMD_SUCCESS;
1688 }
1689
1690 ALIAS (no_ip_rip_authentication_string,
1691 no_ip_rip_authentication_string2_cmd,
1692 "no ip rip authentication string LINE",
1693 NO_STR
1694 IP_STR
1695 "Routing Information Protocol\n"
1696 "Authentication control\n"
1697 "Authentication string\n"
1698 "Authentication string\n")
1699
1700 DEFUN (ip_rip_authentication_key_chain,
1701 ip_rip_authentication_key_chain_cmd,
1702 "ip rip authentication key-chain LINE",
1703 IP_STR
1704 "Routing Information Protocol\n"
1705 "Authentication control\n"
1706 "Authentication key-chain\n"
1707 "name of key-chain\n")
1708 {
1709 struct interface *ifp;
1710 struct rip_interface *ri;
1711
1712 ifp = (struct interface *) vty->index;
1713 ri = ifp->info;
1714
1715 if (ri->auth_str)
1716 {
1717 vty_out (vty, "%% authentication string configuration exists%s",
1718 VTY_NEWLINE);
1719 return CMD_WARNING;
1720 }
1721
1722 if (ri->key_chain)
1723 free (ri->key_chain);
1724
1725 ri->key_chain = strdup (argv[0]);
1726
1727 return CMD_SUCCESS;
1728 }
1729
1730 DEFUN (no_ip_rip_authentication_key_chain,
1731 no_ip_rip_authentication_key_chain_cmd,
1732 "no ip rip authentication key-chain",
1733 NO_STR
1734 IP_STR
1735 "Routing Information Protocol\n"
1736 "Authentication control\n"
1737 "Authentication key-chain\n")
1738 {
1739 struct interface *ifp;
1740 struct rip_interface *ri;
1741
1742 ifp = (struct interface *) vty->index;
1743 ri = ifp->info;
1744
1745 if (ri->key_chain)
1746 free (ri->key_chain);
1747
1748 ri->key_chain = NULL;
1749
1750 return CMD_SUCCESS;
1751 }
1752
1753 ALIAS (no_ip_rip_authentication_key_chain,
1754 no_ip_rip_authentication_key_chain2_cmd,
1755 "no ip rip authentication key-chain LINE",
1756 NO_STR
1757 IP_STR
1758 "Routing Information Protocol\n"
1759 "Authentication control\n"
1760 "Authentication key-chain\n"
1761 "name of key-chain\n")
1762
1763 /* CHANGED: ip rip split-horizon
1764 Cisco and Zebra's command is
1765 ip split-horizon
1766 */
1767 DEFUN (ip_rip_split_horizon,
1768 ip_rip_split_horizon_cmd,
1769 "ip rip split-horizon",
1770 IP_STR
1771 "Routing Information Protocol\n"
1772 "Perform split horizon\n")
1773 {
1774 struct interface *ifp;
1775 struct rip_interface *ri;
1776
1777 ifp = vty->index;
1778 ri = ifp->info;
1779
1780 ri->split_horizon = RIP_SPLIT_HORIZON;
1781 return CMD_SUCCESS;
1782 }
1783
1784 DEFUN (ip_rip_split_horizon_poisoned_reverse,
1785 ip_rip_split_horizon_poisoned_reverse_cmd,
1786 "ip rip split-horizon poisoned-reverse",
1787 IP_STR
1788 "Routing Information Protocol\n"
1789 "Perform split horizon\n"
1790 "With poisoned-reverse\n")
1791 {
1792 struct interface *ifp;
1793 struct rip_interface *ri;
1794
1795 ifp = vty->index;
1796 ri = ifp->info;
1797
1798 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1799 return CMD_SUCCESS;
1800 }
1801
1802 /* CHANGED: no ip rip split-horizon
1803 Cisco and Zebra's command is
1804 no ip split-horizon
1805 */
1806 DEFUN (no_ip_rip_split_horizon,
1807 no_ip_rip_split_horizon_cmd,
1808 "no ip rip split-horizon",
1809 NO_STR
1810 IP_STR
1811 "Routing Information Protocol\n"
1812 "Perform split horizon\n")
1813 {
1814 struct interface *ifp;
1815 struct rip_interface *ri;
1816
1817 ifp = vty->index;
1818 ri = ifp->info;
1819
1820 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
1821 return CMD_SUCCESS;
1822 }
1823
1824 ALIAS (no_ip_rip_split_horizon,
1825 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1826 "no ip rip split-horizon poisoned-reverse",
1827 NO_STR
1828 IP_STR
1829 "Routing Information Protocol\n"
1830 "Perform split horizon\n"
1831 "With poisoned-reverse\n")
1832
1833 DEFUN (rip_passive_interface,
1834 rip_passive_interface_cmd,
1835 "passive-interface IFNAME",
1836 "Suppress routing updates on an interface\n"
1837 "Interface name\n")
1838 {
1839 return rip_passive_interface_set (vty, argv[0]);
1840 }
1841
1842 DEFUN (no_rip_passive_interface,
1843 no_rip_passive_interface_cmd,
1844 "no passive-interface IFNAME",
1845 NO_STR
1846 "Suppress routing updates on an interface\n"
1847 "Interface name\n")
1848 {
1849 return rip_passive_interface_unset (vty, argv[0]);
1850 }
1851 \f
1852 /* Write rip configuration of each interface. */
1853 int
1854 rip_interface_config_write (struct vty *vty)
1855 {
1856 listnode node;
1857 struct interface *ifp;
1858
1859 for (node = listhead (iflist); node; nextnode (node))
1860 {
1861 struct rip_interface *ri;
1862
1863 ifp = getdata (node);
1864 ri = ifp->info;
1865
1866 /* Do not display the interface if there is no
1867 * configuration about it.
1868 **/
1869 if ((!ifp->desc) &&
1870 (ri->split_horizon == ri->split_horizon_default) &&
1871 (ri->ri_send == RI_RIP_UNSPEC) &&
1872 (ri->ri_receive == RI_RIP_UNSPEC) &&
1873 (ri->auth_type != RIP_AUTH_MD5) &&
1874 (!ri->auth_str) &&
1875 (!ri->key_chain) )
1876 continue;
1877
1878 vty_out (vty, "interface %s%s", ifp->name,
1879 VTY_NEWLINE);
1880
1881 if (ifp->desc)
1882 vty_out (vty, " description %s%s", ifp->desc,
1883 VTY_NEWLINE);
1884
1885 /* Split horizon. */
1886 if (ri->split_horizon != ri->split_horizon_default)
1887 {
1888 switch (ri->split_horizon) {
1889 case RIP_SPLIT_HORIZON:
1890 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1891 break;
1892 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1893 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1894 VTY_NEWLINE);
1895 break;
1896 case RIP_NO_SPLIT_HORIZON:
1897 default:
1898 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1899 break;
1900 }
1901 }
1902
1903 /* RIP version setting. */
1904 if (ri->ri_send != RI_RIP_UNSPEC)
1905 vty_out (vty, " ip rip send version %s%s",
1906 lookup (ri_version_msg, ri->ri_send),
1907 VTY_NEWLINE);
1908
1909 if (ri->ri_receive != RI_RIP_UNSPEC)
1910 vty_out (vty, " ip rip receive version %s%s",
1911 lookup (ri_version_msg, ri->ri_receive),
1912 VTY_NEWLINE);
1913
1914 /* RIP authentication. */
1915 #if 0
1916 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
1917 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1918 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
1919 #endif /* 0 */
1920 if (ri->auth_type == RIP_AUTH_MD5)
1921 vty_out (vty, " ip rip authentication mode md5%s", VTY_NEWLINE);
1922
1923 if (ri->auth_str)
1924 vty_out (vty, " ip rip authentication string %s%s",
1925 ri->auth_str, VTY_NEWLINE);
1926
1927 if (ri->key_chain)
1928 vty_out (vty, " ip rip authentication key-chain %s%s",
1929 ri->key_chain, VTY_NEWLINE);
1930
1931 vty_out (vty, "!%s", VTY_NEWLINE);
1932 }
1933 return 0;
1934 }
1935
1936 int
1937 config_write_rip_network (struct vty *vty, int config_mode)
1938 {
1939 int i;
1940 char *ifname;
1941 struct route_node *node;
1942
1943 /* Network type RIP enable interface statement. */
1944 for (node = route_top (rip_enable_network); node; node = route_next (node))
1945 if (node->info)
1946 vty_out (vty, "%s%s/%d%s",
1947 config_mode ? " network " : " ",
1948 inet_ntoa (node->p.u.prefix4),
1949 node->p.prefixlen,
1950 VTY_NEWLINE);
1951
1952 /* Interface name RIP enable statement. */
1953 for (i = 0; i < vector_max (rip_enable_interface); i++)
1954 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
1955 vty_out (vty, "%s%s%s",
1956 config_mode ? " network " : " ",
1957 ifname,
1958 VTY_NEWLINE);
1959
1960 /* RIP neighbors listing. */
1961 for (node = route_top (rip->neighbor); node; node = route_next (node))
1962 if (node->info)
1963 vty_out (vty, "%s%s%s",
1964 config_mode ? " neighbor " : " ",
1965 inet_ntoa (node->p.u.prefix4),
1966 VTY_NEWLINE);
1967
1968 /* RIP passive interface listing. */
1969 if (config_mode)
1970 for (i = 0; i < vector_max (Vrip_passive_interface); i++)
1971 if ((ifname = vector_slot (Vrip_passive_interface, i)) != NULL)
1972 vty_out (vty, " passive-interface %s%s", ifname, VTY_NEWLINE);
1973
1974 return 0;
1975 }
1976
1977 struct cmd_node interface_node =
1978 {
1979 INTERFACE_NODE,
1980 "%s(config-if)# ",
1981 1,
1982 };
1983
1984 /* Called when interface structure allocated. */
1985 int
1986 rip_interface_new_hook (struct interface *ifp)
1987 {
1988 ifp->info = rip_interface_new ();
1989 return 0;
1990 }
1991
1992 /* Called when interface structure deleted. */
1993 int
1994 rip_interface_delete_hook (struct interface *ifp)
1995 {
1996 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
1997 ifp->info = NULL;
1998 return 0;
1999 }
2000
2001 /* Allocate and initialize interface vector. */
2002 void
2003 rip_if_init ()
2004 {
2005 /* Default initial size of interface vector. */
2006 if_init();
2007 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2008 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2009
2010 /* RIP network init. */
2011 rip_enable_interface = vector_init (1);
2012 rip_enable_network = route_table_init ();
2013
2014 /* RIP passive interface. */
2015 Vrip_passive_interface = vector_init (1);
2016
2017 /* Install interface node. */
2018 install_node (&interface_node, rip_interface_config_write);
2019
2020 /* Install commands. */
2021 install_element (CONFIG_NODE, &interface_cmd);
2022 install_element (CONFIG_NODE, &no_interface_cmd);
2023 install_default (INTERFACE_NODE);
2024 install_element (INTERFACE_NODE, &interface_desc_cmd);
2025 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2026 install_element (RIP_NODE, &rip_network_cmd);
2027 install_element (RIP_NODE, &no_rip_network_cmd);
2028 install_element (RIP_NODE, &rip_neighbor_cmd);
2029 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2030
2031 install_element (RIP_NODE, &rip_passive_interface_cmd);
2032 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2033
2034 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2035 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2036 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2037 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2038 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2039
2040 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2041 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2042 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2043 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2044 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2045
2046 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
2047 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2048 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
2049
2050 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2051 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2052 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2053
2054 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2055 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2056 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2057
2058 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2059 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2060 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2061 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
2062 }