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