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