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