blob: 4daa5b3816297ef280bcf6c140a228586311e260 [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;
paulca5e5162004-06-06 22:06:33 +0000128 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +0000129
130 /* Set default split-horizon behavior. If the interface is Frame
131 Relay or SMDS is enabled, the default value for split-horizon is
132 off. But currently Zebra does detect Frame Relay or SMDS
133 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000134 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000135 ri->split_horizon = ri->split_horizon_default;
136
137 return ri;
138}
139
140void
paulcc1131a2003-10-15 23:20:17 +0000141rip_interface_multicast_set (int sock, struct connected *connected,
142 int if_pointopoint)
paul718e3742002-12-13 20:15:29 +0000143{
144 int ret;
paul718e3742002-12-13 20:15:29 +0000145 struct servent *sp;
146 struct sockaddr_in from;
paul718e3742002-12-13 20:15:29 +0000147 struct in_addr addr;
paulcc1131a2003-10-15 23:20:17 +0000148 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000149
paul931cd542004-01-23 15:31:42 +0000150 if (connected != NULL)
151 {
paulcc1131a2003-10-15 23:20:17 +0000152 if (if_pointopoint)
153 p = (struct prefix_ipv4 *) connected->destination;
154 else
paul718e3742002-12-13 20:15:29 +0000155 p = (struct prefix_ipv4 *) connected->address;
paul718e3742002-12-13 20:15:29 +0000156 addr = p->prefix;
paul931cd542004-01-23 15:31:42 +0000157 }
158 else
159 {
160 addr.s_addr = INADDR_ANY;
161 }
paul718e3742002-12-13 20:15:29 +0000162
paul931cd542004-01-23 15:31:42 +0000163 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0, 0) < 0)
paul718e3742002-12-13 20:15:29 +0000164 {
165 zlog_warn ("Can't setsockopt IP_MULTICAST_IF to fd %d", sock);
166 return;
167 }
168
169 /* Bind myself. */
170 memset (&from, 0, sizeof (struct sockaddr_in));
171
172 /* Set RIP port. */
173 sp = getservbyname ("router", "udp");
174 if (sp)
175 from.sin_port = sp->s_port;
176 else
177 from.sin_port = htons (RIP_PORT_DEFAULT);
178
paul931cd542004-01-23 15:31:42 +0000179 /* Address should be any address. */
paul718e3742002-12-13 20:15:29 +0000180 from.sin_family = AF_INET;
paul931cd542004-01-23 15:31:42 +0000181 if (connected)
paulcc1131a2003-10-15 23:20:17 +0000182 addr = ((struct prefix_ipv4 *) connected->address)->prefix;
paul718e3742002-12-13 20:15:29 +0000183 from.sin_addr = addr;
184#ifdef HAVE_SIN_LEN
185 from.sin_len = sizeof (struct sockaddr_in);
186#endif /* HAVE_SIN_LEN */
187
pauledd7c242003-06-04 13:59:38 +0000188 if (ripd_privs.change (ZPRIVS_RAISE))
189 zlog_err ("rip_interface_multicast_set: could not raise privs");
190
paulcc1131a2003-10-15 23:20:17 +0000191 ret = bind (sock, (struct sockaddr *) & from, sizeof (struct sockaddr_in));
paul718e3742002-12-13 20:15:29 +0000192 if (ret < 0)
193 {
194 zlog_warn ("Can't bind socket: %s", strerror (errno));
paul718e3742002-12-13 20:15:29 +0000195 }
196
pauledd7c242003-06-04 13:59:38 +0000197 if (ripd_privs.change (ZPRIVS_LOWER))
198 zlog_err ("rip_interface_multicast_set: could not lower privs");
199
paul718e3742002-12-13 20:15:29 +0000200 return;
201
202 }
paul718e3742002-12-13 20:15:29 +0000203
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
paul931cd542004-01-23 15:31:42 +0000217 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000218 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
paul931cd542004-01-23 15:31:42 +0000246 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000247 }
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
paul931cd542004-01-23 15:31:42 +0000292 rip_request_send (&to, NULL, rip->version_send, NULL);
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
paul0a589352004-05-08 11:48:26 +0000790 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
791 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000792
793 if (ifc == NULL)
794 return 0;
795
796 p = ifc->address;
797
798 if (p->family == AF_INET)
799 {
800 if (IS_RIP_DEBUG_ZEBRA)
801 zlog_info ("connected address %s/%d is added",
802 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000803
paul878ef2e2003-09-23 23:41:50 +0000804 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000805 /* Check if this prefix needs to be redistributed */
806 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000807
808#ifdef HAVE_SNMP
809 rip_ifaddr_add (ifc->ifp, ifc);
810#endif /* HAVE_SNMP */
811 }
812
813 return 0;
814}
815
hasso16705132003-05-25 14:49:19 +0000816static void
817rip_apply_address_del (struct connected *ifc) {
818 struct prefix_ipv4 address;
819 struct prefix *p;
820
821 if (!rip)
822 return;
823
824 if (! if_is_up(ifc->ifp))
825 return;
826
827 p = ifc->address;
828
829 memset (&address, 0, sizeof (address));
830 address.family = p->family;
831 address.prefix = p->u.prefix4;
832 address.prefixlen = p->prefixlen;
833 apply_mask_ipv4(&address);
834
835 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
836 &address, ifc->ifp->ifindex);
837}
838
paul718e3742002-12-13 20:15:29 +0000839int
840rip_interface_address_delete (int command, struct zclient *zclient,
841 zebra_size_t length)
842{
843 struct connected *ifc;
844 struct prefix *p;
845
paul0a589352004-05-08 11:48:26 +0000846 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
847 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000848
849 if (ifc)
850 {
851 p = ifc->address;
852 if (p->family == AF_INET)
853 {
854 if (IS_RIP_DEBUG_ZEBRA)
855
856 zlog_info ("connected address %s/%d is deleted",
857 inet_ntoa (p->u.prefix4), p->prefixlen);
858
859#ifdef HAVE_SNMP
860 rip_ifaddr_delete (ifc->ifp, ifc);
861#endif /* HAVE_SNMP */
862
hasso16705132003-05-25 14:49:19 +0000863 /* Chech wether this prefix needs to be removed */
864 rip_apply_address_del(ifc);
865
paul718e3742002-12-13 20:15:29 +0000866 }
867
868 connected_free (ifc);
869
870 }
871
872 return 0;
873}
874
875/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000876/* Check wether the interface has at least a connected prefix that
877 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000878int
hasso16705132003-05-25 14:49:19 +0000879rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000880{
881 struct listnode *nn;
882 struct connected *connected;
883 struct prefix_ipv4 address;
884
885 for (nn = listhead (ifp->connected); nn; nextnode (nn))
886 if ((connected = getdata (nn)) != NULL)
887 {
888 struct prefix *p;
889 struct route_node *node;
890
891 p = connected->address;
892
893 if (p->family == AF_INET)
894 {
895 address.family = AF_INET;
896 address.prefix = p->u.prefix4;
897 address.prefixlen = IPV4_MAX_BITLEN;
898
899 node = route_node_match (rip_enable_network,
900 (struct prefix *)&address);
901 if (node)
902 {
903 route_unlock_node (node);
904 return 1;
905 }
906 }
907 }
908 return -1;
909}
910
hasso16705132003-05-25 14:49:19 +0000911/* Check wether connected is within the ripng_enable_network table. */
912int
913rip_enable_network_lookup2 (struct connected *connected)
914{
915 struct prefix_ipv4 address;
916 struct prefix *p;
917
918 p = connected->address;
919
920 if (p->family == AF_INET) {
921 struct route_node *node;
922
923 address.family = p->family;
924 address.prefix = p->u.prefix4;
925 address.prefixlen = IPV4_MAX_BITLEN;
926
927 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
928 node = route_node_match (rip_enable_network,
929 (struct prefix *)&address);
930
931 if (node) {
932 route_unlock_node (node);
933 return 1;
934 }
935 }
936
937 return -1;
938}
paul718e3742002-12-13 20:15:29 +0000939/* Add RIP enable network. */
940int
941rip_enable_network_add (struct prefix *p)
942{
943 struct route_node *node;
944
945 node = route_node_get (rip_enable_network, p);
946
947 if (node->info)
948 {
949 route_unlock_node (node);
950 return -1;
951 }
952 else
953 node->info = "enabled";
954
hasso16705132003-05-25 14:49:19 +0000955 /* XXX: One should find a better solution than a generic one */
956 rip_enable_apply_all();
957
paul718e3742002-12-13 20:15:29 +0000958 return 1;
959}
960
961/* Delete RIP enable network. */
962int
963rip_enable_network_delete (struct prefix *p)
964{
965 struct route_node *node;
966
967 node = route_node_lookup (rip_enable_network, p);
968 if (node)
969 {
970 node->info = NULL;
971
972 /* Unlock info lock. */
973 route_unlock_node (node);
974
975 /* Unlock lookup lock. */
976 route_unlock_node (node);
977
hasso16705132003-05-25 14:49:19 +0000978 /* XXX: One should find a better solution than a generic one */
979 rip_enable_apply_all ();
980
paul718e3742002-12-13 20:15:29 +0000981 return 1;
982 }
983 return -1;
984}
985
986/* Check interface is enabled by ifname statement. */
987int
988rip_enable_if_lookup (char *ifname)
989{
990 int i;
991 char *str;
992
993 for (i = 0; i < vector_max (rip_enable_interface); i++)
994 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
995 if (strcmp (str, ifname) == 0)
996 return i;
997 return -1;
998}
999
1000/* Add interface to rip_enable_if. */
1001int
1002rip_enable_if_add (char *ifname)
1003{
1004 int ret;
1005
1006 ret = rip_enable_if_lookup (ifname);
1007 if (ret >= 0)
1008 return -1;
1009
1010 vector_set (rip_enable_interface, strdup (ifname));
1011
hasso16705132003-05-25 14:49:19 +00001012 rip_enable_apply_all(); /* TODOVJ */
1013
paul718e3742002-12-13 20:15:29 +00001014 return 1;
1015}
1016
1017/* Delete interface from rip_enable_if. */
1018int
1019rip_enable_if_delete (char *ifname)
1020{
1021 int index;
1022 char *str;
1023
1024 index = rip_enable_if_lookup (ifname);
1025 if (index < 0)
1026 return -1;
1027
1028 str = vector_slot (rip_enable_interface, index);
1029 free (str);
1030 vector_unset (rip_enable_interface, index);
1031
hasso16705132003-05-25 14:49:19 +00001032 rip_enable_apply_all(); /* TODOVJ */
1033
paul718e3742002-12-13 20:15:29 +00001034 return 1;
1035}
1036
1037/* Join to multicast group and send request to the interface. */
1038int
1039rip_interface_wakeup (struct thread *t)
1040{
1041 struct interface *ifp;
1042 struct rip_interface *ri;
1043
1044 /* Get interface. */
1045 ifp = THREAD_ARG (t);
1046
1047 ri = ifp->info;
1048 ri->t_wakeup = NULL;
1049
1050 /* Join to multicast group. */
1051 if (rip_multicast_join (ifp, rip->sock) < 0)
1052 {
1053 zlog_err ("multicast join failed, interface %s not running", ifp->name);
1054 return 0;
1055 }
1056
1057 /* Set running flag. */
1058 ri->running = 1;
1059
1060 /* Send RIP request to the interface. */
1061 rip_request_interface (ifp);
1062
1063 return 0;
1064}
1065
1066int rip_redistribute_check (int);
1067
1068void
1069rip_connect_set (struct interface *ifp, int set)
1070{
1071 struct listnode *nn;
1072 struct connected *connected;
1073 struct prefix_ipv4 address;
1074
1075 for (nn = listhead (ifp->connected); nn; nextnode (nn))
1076 if ((connected = getdata (nn)) != NULL)
1077 {
1078 struct prefix *p;
1079 p = connected->address;
1080
1081 if (p->family != AF_INET)
1082 continue;
1083
1084 address.family = AF_INET;
1085 address.prefix = p->u.prefix4;
1086 address.prefixlen = p->prefixlen;
1087 apply_mask_ipv4 (&address);
1088
hasso16705132003-05-25 14:49:19 +00001089 if (set) {
1090 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1091 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1092 (rip_enable_network_lookup2(connected) >= 0))
1093 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1094 &address, connected->ifp->ifindex, NULL);
1095 } else
paul718e3742002-12-13 20:15:29 +00001096 {
1097 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1098 &address, connected->ifp->ifindex);
1099 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1100 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1101 &address, connected->ifp->ifindex, NULL);
1102 }
1103 }
1104}
1105
1106/* Update interface status. */
1107void
1108rip_enable_apply (struct interface *ifp)
1109{
1110 int ret;
1111 struct rip_interface *ri = NULL;
1112
1113 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001114 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001115 return;
1116
1117 ri = ifp->info;
1118
1119 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001120 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001121
1122 /* If the interface is matched. */
1123 if (ret > 0)
1124 ri->enable_network = 1;
1125 else
1126 ri->enable_network = 0;
1127
1128 /* Check interface name configuration. */
1129 ret = rip_enable_if_lookup (ifp->name);
1130 if (ret >= 0)
1131 ri->enable_interface = 1;
1132 else
1133 ri->enable_interface = 0;
1134
1135 /* any interface MUST have an IPv4 address */
1136 if ( ! rip_if_ipv4_address_check (ifp) )
1137 {
1138 ri->enable_network = 0;
1139 ri->enable_interface = 0;
1140 }
1141
1142 /* Update running status of the interface. */
1143 if (ri->enable_network || ri->enable_interface)
1144 {
paul718e3742002-12-13 20:15:29 +00001145 {
1146 if (IS_RIP_DEBUG_EVENT)
1147 zlog_info ("turn on %s", ifp->name);
1148
1149 /* Add interface wake up thread. */
1150 if (! ri->t_wakeup)
1151 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1152 ifp, 1);
1153 rip_connect_set (ifp, 1);
1154 }
1155 }
1156 else
1157 {
1158 if (ri->running)
1159 {
hasso16705132003-05-25 14:49:19 +00001160 /* Might as well clean up the route table as well
1161 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1162 **/
paul718e3742002-12-13 20:15:29 +00001163 rip_if_down(ifp);
1164
paul718e3742002-12-13 20:15:29 +00001165 rip_connect_set (ifp, 0);
1166 }
1167 }
1168}
1169
1170/* Apply network configuration to all interface. */
1171void
1172rip_enable_apply_all ()
1173{
1174 struct interface *ifp;
1175 listnode node;
1176
1177 /* Check each interface. */
1178 for (node = listhead (iflist); node; nextnode (node))
1179 {
1180 ifp = getdata (node);
1181 rip_enable_apply (ifp);
1182 }
1183}
1184
1185int
1186rip_neighbor_lookup (struct sockaddr_in *from)
1187{
1188 struct prefix_ipv4 p;
1189 struct route_node *node;
1190
1191 memset (&p, 0, sizeof (struct prefix_ipv4));
1192 p.family = AF_INET;
1193 p.prefix = from->sin_addr;
1194 p.prefixlen = IPV4_MAX_BITLEN;
1195
1196 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1197 if (node)
1198 {
1199 route_unlock_node (node);
1200 return 1;
1201 }
1202 return 0;
1203}
1204
1205/* Add new RIP neighbor to the neighbor tree. */
1206int
1207rip_neighbor_add (struct prefix_ipv4 *p)
1208{
1209 struct route_node *node;
1210
1211 node = route_node_get (rip->neighbor, (struct prefix *) p);
1212
1213 if (node->info)
1214 return -1;
1215
1216 node->info = rip->neighbor;
1217
1218 return 0;
1219}
1220
1221/* Delete RIP neighbor from the neighbor tree. */
1222int
1223rip_neighbor_delete (struct prefix_ipv4 *p)
1224{
1225 struct route_node *node;
1226
1227 /* Lock for look up. */
1228 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1229 if (! node)
1230 return -1;
1231
1232 node->info = NULL;
1233
1234 /* Unlock lookup lock. */
1235 route_unlock_node (node);
1236
1237 /* Unlock real neighbor information lock. */
1238 route_unlock_node (node);
1239
1240 return 0;
1241}
1242
1243/* Clear all network and neighbor configuration. */
1244void
1245rip_clean_network ()
1246{
1247 int i;
1248 char *str;
1249 struct route_node *rn;
1250
1251 /* rip_enable_network. */
1252 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1253 if (rn->info)
1254 {
1255 rn->info = NULL;
1256 route_unlock_node (rn);
1257 }
1258
1259 /* rip_enable_interface. */
1260 for (i = 0; i < vector_max (rip_enable_interface); i++)
1261 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1262 {
1263 free (str);
1264 vector_slot (rip_enable_interface, i) = NULL;
1265 }
1266}
1267
1268/* Utility function for looking up passive interface settings. */
1269int
paul4aaff3f2003-06-07 01:04:45 +00001270rip_passive_nondefault_lookup (char *ifname)
paul718e3742002-12-13 20:15:29 +00001271{
1272 int i;
1273 char *str;
1274
paul4aaff3f2003-06-07 01:04:45 +00001275 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1276 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001277 if (strcmp (str, ifname) == 0)
1278 return i;
1279 return -1;
1280}
1281
1282void
1283rip_passive_interface_apply (struct interface *ifp)
1284{
paul718e3742002-12-13 20:15:29 +00001285 struct rip_interface *ri;
1286
1287 ri = ifp->info;
1288
paul4aaff3f2003-06-07 01:04:45 +00001289 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1290 passive_default : !passive_default);
1291
1292 if (IS_RIP_DEBUG_ZEBRA)
1293 zlog_info ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001294}
1295
1296void
1297rip_passive_interface_apply_all ()
1298{
1299 struct interface *ifp;
1300 listnode node;
1301
1302 for (node = listhead (iflist); node; nextnode (node))
1303 {
1304 ifp = getdata (node);
1305 rip_passive_interface_apply (ifp);
1306 }
1307}
1308
1309/* Passive interface. */
1310int
paul4aaff3f2003-06-07 01:04:45 +00001311rip_passive_nondefault_set (struct vty *vty, char *ifname)
paul718e3742002-12-13 20:15:29 +00001312{
paul4aaff3f2003-06-07 01:04:45 +00001313 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001314 return CMD_WARNING;
1315
paul4aaff3f2003-06-07 01:04:45 +00001316 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001317
1318 rip_passive_interface_apply_all ();
1319
1320 return CMD_SUCCESS;
1321}
1322
1323int
paul4aaff3f2003-06-07 01:04:45 +00001324rip_passive_nondefault_unset (struct vty *vty, char *ifname)
paul718e3742002-12-13 20:15:29 +00001325{
1326 int i;
1327 char *str;
1328
paul4aaff3f2003-06-07 01:04:45 +00001329 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001330 if (i < 0)
1331 return CMD_WARNING;
1332
paul4aaff3f2003-06-07 01:04:45 +00001333 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001334 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001335 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001336
1337 rip_passive_interface_apply_all ();
1338
1339 return CMD_SUCCESS;
1340}
1341
1342/* Free all configured RIP passive-interface settings. */
1343void
paul4aaff3f2003-06-07 01:04:45 +00001344rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001345{
1346 int i;
1347 char *str;
1348
paul4aaff3f2003-06-07 01:04:45 +00001349 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1350 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001351 {
1352 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001353 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001354 }
1355 rip_passive_interface_apply_all ();
1356}
1357
1358/* RIP enable network or interface configuration. */
1359DEFUN (rip_network,
1360 rip_network_cmd,
1361 "network (A.B.C.D/M|WORD)",
1362 "Enable routing on an IP network\n"
1363 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1364 "Interface name\n")
1365{
1366 int ret;
1367 struct prefix_ipv4 p;
1368
1369 ret = str2prefix_ipv4 (argv[0], &p);
1370
1371 if (ret)
1372 ret = rip_enable_network_add ((struct prefix *) &p);
1373 else
1374 ret = rip_enable_if_add (argv[0]);
1375
1376 if (ret < 0)
1377 {
1378 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1379 VTY_NEWLINE);
1380 return CMD_WARNING;
1381 }
1382
paul718e3742002-12-13 20:15:29 +00001383 return CMD_SUCCESS;
1384}
1385
1386/* RIP enable network or interface configuration. */
1387DEFUN (no_rip_network,
1388 no_rip_network_cmd,
1389 "no network (A.B.C.D/M|WORD)",
1390 NO_STR
1391 "Enable routing on an IP network\n"
1392 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1393 "Interface name\n")
1394{
1395 int ret;
1396 struct prefix_ipv4 p;
1397
1398 ret = str2prefix_ipv4 (argv[0], &p);
1399
1400 if (ret)
1401 ret = rip_enable_network_delete ((struct prefix *) &p);
1402 else
1403 ret = rip_enable_if_delete (argv[0]);
1404
1405 if (ret < 0)
1406 {
1407 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1408 VTY_NEWLINE);
1409 return CMD_WARNING;
1410 }
1411
paul718e3742002-12-13 20:15:29 +00001412 return CMD_SUCCESS;
1413}
1414
1415/* RIP neighbor configuration set. */
1416DEFUN (rip_neighbor,
1417 rip_neighbor_cmd,
1418 "neighbor A.B.C.D",
1419 "Specify a neighbor router\n"
1420 "Neighbor address\n")
1421{
1422 int ret;
1423 struct prefix_ipv4 p;
1424
1425 ret = str2prefix_ipv4 (argv[0], &p);
1426
1427 if (ret <= 0)
1428 {
1429 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1430 return CMD_WARNING;
1431 }
1432
1433 rip_neighbor_add (&p);
1434
1435 return CMD_SUCCESS;
1436}
1437
1438/* RIP neighbor configuration unset. */
1439DEFUN (no_rip_neighbor,
1440 no_rip_neighbor_cmd,
1441 "no neighbor A.B.C.D",
1442 NO_STR
1443 "Specify a neighbor router\n"
1444 "Neighbor address\n")
1445{
1446 int ret;
1447 struct prefix_ipv4 p;
1448
1449 ret = str2prefix_ipv4 (argv[0], &p);
1450
1451 if (ret <= 0)
1452 {
1453 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1454 return CMD_WARNING;
1455 }
1456
1457 rip_neighbor_delete (&p);
1458
1459 return CMD_SUCCESS;
1460}
1461
1462DEFUN (ip_rip_receive_version,
1463 ip_rip_receive_version_cmd,
1464 "ip rip receive version (1|2)",
1465 IP_STR
1466 "Routing Information Protocol\n"
1467 "Advertisement reception\n"
1468 "Version control\n"
1469 "RIP version 1\n"
1470 "RIP version 2\n")
1471{
1472 struct interface *ifp;
1473 struct rip_interface *ri;
1474
1475 ifp = (struct interface *)vty->index;
1476 ri = ifp->info;
1477
1478 /* Version 1. */
1479 if (atoi (argv[0]) == 1)
1480 {
1481 ri->ri_receive = RI_RIP_VERSION_1;
1482 return CMD_SUCCESS;
1483 }
1484 if (atoi (argv[0]) == 2)
1485 {
1486 ri->ri_receive = RI_RIP_VERSION_2;
1487 return CMD_SUCCESS;
1488 }
1489 return CMD_WARNING;
1490}
1491
1492DEFUN (ip_rip_receive_version_1,
1493 ip_rip_receive_version_1_cmd,
1494 "ip rip receive version 1 2",
1495 IP_STR
1496 "Routing Information Protocol\n"
1497 "Advertisement reception\n"
1498 "Version control\n"
1499 "RIP version 1\n"
1500 "RIP version 2\n")
1501{
1502 struct interface *ifp;
1503 struct rip_interface *ri;
1504
1505 ifp = (struct interface *)vty->index;
1506 ri = ifp->info;
1507
1508 /* Version 1 and 2. */
1509 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1510 return CMD_SUCCESS;
1511}
1512
1513DEFUN (ip_rip_receive_version_2,
1514 ip_rip_receive_version_2_cmd,
1515 "ip rip receive version 2 1",
1516 IP_STR
1517 "Routing Information Protocol\n"
1518 "Advertisement reception\n"
1519 "Version control\n"
1520 "RIP version 2\n"
1521 "RIP version 1\n")
1522{
1523 struct interface *ifp;
1524 struct rip_interface *ri;
1525
1526 ifp = (struct interface *)vty->index;
1527 ri = ifp->info;
1528
1529 /* Version 1 and 2. */
1530 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1531 return CMD_SUCCESS;
1532}
1533
1534DEFUN (no_ip_rip_receive_version,
1535 no_ip_rip_receive_version_cmd,
1536 "no ip rip receive version",
1537 NO_STR
1538 IP_STR
1539 "Routing Information Protocol\n"
1540 "Advertisement reception\n"
1541 "Version control\n")
1542{
1543 struct interface *ifp;
1544 struct rip_interface *ri;
1545
1546 ifp = (struct interface *)vty->index;
1547 ri = ifp->info;
1548
1549 ri->ri_receive = RI_RIP_UNSPEC;
1550 return CMD_SUCCESS;
1551}
1552
1553ALIAS (no_ip_rip_receive_version,
1554 no_ip_rip_receive_version_num_cmd,
1555 "no ip rip receive version (1|2)",
1556 NO_STR
1557 IP_STR
1558 "Routing Information Protocol\n"
1559 "Advertisement reception\n"
1560 "Version control\n"
1561 "Version 1\n"
1562 "Version 2\n")
1563
1564DEFUN (ip_rip_send_version,
1565 ip_rip_send_version_cmd,
1566 "ip rip send version (1|2)",
1567 IP_STR
1568 "Routing Information Protocol\n"
1569 "Advertisement transmission\n"
1570 "Version control\n"
1571 "RIP version 1\n"
1572 "RIP version 2\n")
1573{
1574 struct interface *ifp;
1575 struct rip_interface *ri;
1576
1577 ifp = (struct interface *)vty->index;
1578 ri = ifp->info;
1579
1580 /* Version 1. */
1581 if (atoi (argv[0]) == 1)
1582 {
1583 ri->ri_send = RI_RIP_VERSION_1;
1584 return CMD_SUCCESS;
1585 }
1586 if (atoi (argv[0]) == 2)
1587 {
1588 ri->ri_send = RI_RIP_VERSION_2;
1589 return CMD_SUCCESS;
1590 }
1591 return CMD_WARNING;
1592}
1593
1594DEFUN (ip_rip_send_version_1,
1595 ip_rip_send_version_1_cmd,
1596 "ip rip send version 1 2",
1597 IP_STR
1598 "Routing Information Protocol\n"
1599 "Advertisement transmission\n"
1600 "Version control\n"
1601 "RIP version 1\n"
1602 "RIP version 2\n")
1603{
1604 struct interface *ifp;
1605 struct rip_interface *ri;
1606
1607 ifp = (struct interface *)vty->index;
1608 ri = ifp->info;
1609
1610 /* Version 1 and 2. */
1611 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1612 return CMD_SUCCESS;
1613}
1614
1615DEFUN (ip_rip_send_version_2,
1616 ip_rip_send_version_2_cmd,
1617 "ip rip send version 2 1",
1618 IP_STR
1619 "Routing Information Protocol\n"
1620 "Advertisement transmission\n"
1621 "Version control\n"
1622 "RIP version 2\n"
1623 "RIP version 1\n")
1624{
1625 struct interface *ifp;
1626 struct rip_interface *ri;
1627
1628 ifp = (struct interface *)vty->index;
1629 ri = ifp->info;
1630
1631 /* Version 1 and 2. */
1632 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1633 return CMD_SUCCESS;
1634}
1635
1636DEFUN (no_ip_rip_send_version,
1637 no_ip_rip_send_version_cmd,
1638 "no ip rip send version",
1639 NO_STR
1640 IP_STR
1641 "Routing Information Protocol\n"
1642 "Advertisement transmission\n"
1643 "Version control\n")
1644{
1645 struct interface *ifp;
1646 struct rip_interface *ri;
1647
1648 ifp = (struct interface *)vty->index;
1649 ri = ifp->info;
1650
1651 ri->ri_send = RI_RIP_UNSPEC;
1652 return CMD_SUCCESS;
1653}
1654
1655ALIAS (no_ip_rip_send_version,
1656 no_ip_rip_send_version_num_cmd,
1657 "no ip rip send version (1|2)",
1658 NO_STR
1659 IP_STR
1660 "Routing Information Protocol\n"
1661 "Advertisement transmission\n"
1662 "Version control\n"
1663 "Version 1\n"
1664 "Version 2\n")
1665
1666DEFUN (ip_rip_authentication_mode,
1667 ip_rip_authentication_mode_cmd,
1668 "ip rip authentication mode (md5|text)",
1669 IP_STR
1670 "Routing Information Protocol\n"
1671 "Authentication control\n"
1672 "Authentication mode\n"
1673 "Keyed message digest\n"
1674 "Clear text authentication\n")
1675{
1676 struct interface *ifp;
1677 struct rip_interface *ri;
1678
1679 ifp = (struct interface *)vty->index;
1680 ri = ifp->info;
1681
paulca5e5162004-06-06 22:06:33 +00001682 if ( (argc < 1) || (argc > 2) )
1683 {
1684 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1685 return CMD_WARNING;
1686 }
1687
paul718e3742002-12-13 20:15:29 +00001688 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1689 ri->auth_type = RIP_AUTH_MD5;
1690 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1691 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1692 else
1693 {
1694 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1695 return CMD_WARNING;
1696 }
1697
paulca5e5162004-06-06 22:06:33 +00001698 if (argc == 1)
1699 return CMD_SUCCESS;
1700
1701 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1702 {
1703 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1704 return CMD_WARNING;
1705}
1706
1707 if (strncmp ("r", argv[1], 1) == 0)
1708 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1709 else if (strncmp ("o", argv[1], 1) == 0)
1710 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1711 else
1712 return CMD_WARNING;
1713
paul718e3742002-12-13 20:15:29 +00001714 return CMD_SUCCESS;
1715}
1716
paulca5e5162004-06-06 22:06:33 +00001717ALIAS (ip_rip_authentication_mode,
1718 ip_rip_authentication_mode_authlen_cmd,
1719 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1720 IP_STR
1721 "Routing Information Protocol\n"
1722 "Authentication control\n"
1723 "Authentication mode\n"
1724 "Keyed message digest\n"
1725 "Clear text authentication\n"
1726 "MD5 authentication data length\n"
1727 "RFC compatible\n"
1728 "Old ripd compatible\n")
1729
paul718e3742002-12-13 20:15:29 +00001730DEFUN (no_ip_rip_authentication_mode,
1731 no_ip_rip_authentication_mode_cmd,
1732 "no ip rip authentication mode",
1733 NO_STR
1734 IP_STR
1735 "Routing Information Protocol\n"
1736 "Authentication control\n"
1737 "Authentication mode\n")
1738{
1739 struct interface *ifp;
1740 struct rip_interface *ri;
1741
1742 ifp = (struct interface *)vty->index;
1743 ri = ifp->info;
1744
1745 /* ri->auth_type = RIP_NO_AUTH; */
1746 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paulca5e5162004-06-06 22:06:33 +00001747 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001748
1749 return CMD_SUCCESS;
1750}
1751
1752ALIAS (no_ip_rip_authentication_mode,
1753 no_ip_rip_authentication_mode_type_cmd,
1754 "no ip rip authentication mode (md5|text)",
1755 NO_STR
1756 IP_STR
1757 "Routing Information Protocol\n"
1758 "Authentication control\n"
1759 "Authentication mode\n"
1760 "Keyed message digest\n"
1761 "Clear text authentication\n")
1762
paulca5e5162004-06-06 22:06:33 +00001763ALIAS (no_ip_rip_authentication_mode,
1764 no_ip_rip_authentication_mode_type_authlen_cmd,
1765 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1766 NO_STR
1767 IP_STR
1768 "Routing Information Protocol\n"
1769 "Authentication control\n"
1770 "Authentication mode\n"
1771 "Keyed message digest\n"
1772 "Clear text authentication\n"
1773 "MD5 authentication data length\n"
1774 "RFC compatible\n"
1775 "Old ripd compatible\n")
1776
paul718e3742002-12-13 20:15:29 +00001777DEFUN (ip_rip_authentication_string,
1778 ip_rip_authentication_string_cmd,
1779 "ip rip authentication string LINE",
1780 IP_STR
1781 "Routing Information Protocol\n"
1782 "Authentication control\n"
1783 "Authentication string\n"
1784 "Authentication string\n")
1785{
1786 struct interface *ifp;
1787 struct rip_interface *ri;
1788
1789 ifp = (struct interface *)vty->index;
1790 ri = ifp->info;
1791
1792 if (strlen (argv[0]) > 16)
1793 {
1794 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1795 VTY_NEWLINE);
1796 return CMD_WARNING;
1797 }
1798
1799 if (ri->key_chain)
1800 {
1801 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1802 return CMD_WARNING;
1803 }
1804
1805 if (ri->auth_str)
1806 free (ri->auth_str);
1807
1808 ri->auth_str = strdup (argv[0]);
1809
1810 return CMD_SUCCESS;
1811}
1812
1813DEFUN (no_ip_rip_authentication_string,
1814 no_ip_rip_authentication_string_cmd,
1815 "no ip rip authentication string",
1816 NO_STR
1817 IP_STR
1818 "Routing Information Protocol\n"
1819 "Authentication control\n"
1820 "Authentication string\n")
1821{
1822 struct interface *ifp;
1823 struct rip_interface *ri;
1824
1825 ifp = (struct interface *)vty->index;
1826 ri = ifp->info;
1827
1828 if (ri->auth_str)
1829 free (ri->auth_str);
1830
1831 ri->auth_str = NULL;
1832
1833 return CMD_SUCCESS;
1834}
1835
1836ALIAS (no_ip_rip_authentication_string,
1837 no_ip_rip_authentication_string2_cmd,
1838 "no ip rip authentication string LINE",
1839 NO_STR
1840 IP_STR
1841 "Routing Information Protocol\n"
1842 "Authentication control\n"
1843 "Authentication string\n"
1844 "Authentication string\n")
1845
1846DEFUN (ip_rip_authentication_key_chain,
1847 ip_rip_authentication_key_chain_cmd,
1848 "ip rip authentication key-chain LINE",
1849 IP_STR
1850 "Routing Information Protocol\n"
1851 "Authentication control\n"
1852 "Authentication key-chain\n"
1853 "name of key-chain\n")
1854{
1855 struct interface *ifp;
1856 struct rip_interface *ri;
1857
1858 ifp = (struct interface *) vty->index;
1859 ri = ifp->info;
1860
1861 if (ri->auth_str)
1862 {
1863 vty_out (vty, "%% authentication string configuration exists%s",
1864 VTY_NEWLINE);
1865 return CMD_WARNING;
1866 }
1867
1868 if (ri->key_chain)
1869 free (ri->key_chain);
1870
1871 ri->key_chain = strdup (argv[0]);
1872
1873 return CMD_SUCCESS;
1874}
1875
1876DEFUN (no_ip_rip_authentication_key_chain,
1877 no_ip_rip_authentication_key_chain_cmd,
1878 "no ip rip authentication key-chain",
1879 NO_STR
1880 IP_STR
1881 "Routing Information Protocol\n"
1882 "Authentication control\n"
1883 "Authentication key-chain\n")
1884{
1885 struct interface *ifp;
1886 struct rip_interface *ri;
1887
1888 ifp = (struct interface *) vty->index;
1889 ri = ifp->info;
1890
1891 if (ri->key_chain)
1892 free (ri->key_chain);
1893
1894 ri->key_chain = NULL;
1895
1896 return CMD_SUCCESS;
1897}
1898
1899ALIAS (no_ip_rip_authentication_key_chain,
1900 no_ip_rip_authentication_key_chain2_cmd,
1901 "no ip rip authentication key-chain LINE",
1902 NO_STR
1903 IP_STR
1904 "Routing Information Protocol\n"
1905 "Authentication control\n"
1906 "Authentication key-chain\n"
1907 "name of key-chain\n")
1908
hasso16705132003-05-25 14:49:19 +00001909/* CHANGED: ip rip split-horizon
1910 Cisco and Zebra's command is
1911 ip split-horizon
1912 */
1913DEFUN (ip_rip_split_horizon,
1914 ip_rip_split_horizon_cmd,
1915 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001916 IP_STR
hasso16705132003-05-25 14:49:19 +00001917 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001918 "Perform split horizon\n")
1919{
1920 struct interface *ifp;
1921 struct rip_interface *ri;
1922
1923 ifp = vty->index;
1924 ri = ifp->info;
1925
hasso16705132003-05-25 14:49:19 +00001926 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001927 return CMD_SUCCESS;
1928}
1929
hasso16705132003-05-25 14:49:19 +00001930DEFUN (ip_rip_split_horizon_poisoned_reverse,
1931 ip_rip_split_horizon_poisoned_reverse_cmd,
1932 "ip rip split-horizon poisoned-reverse",
1933 IP_STR
1934 "Routing Information Protocol\n"
1935 "Perform split horizon\n"
1936 "With poisoned-reverse\n")
1937{
1938 struct interface *ifp;
1939 struct rip_interface *ri;
1940
1941 ifp = vty->index;
1942 ri = ifp->info;
1943
1944 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1945 return CMD_SUCCESS;
1946}
1947
1948/* CHANGED: no ip rip split-horizon
1949 Cisco and Zebra's command is
1950 no ip split-horizon
1951 */
1952DEFUN (no_ip_rip_split_horizon,
1953 no_ip_rip_split_horizon_cmd,
1954 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001955 NO_STR
1956 IP_STR
hasso16705132003-05-25 14:49:19 +00001957 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001958 "Perform split horizon\n")
1959{
1960 struct interface *ifp;
1961 struct rip_interface *ri;
1962
1963 ifp = vty->index;
1964 ri = ifp->info;
1965
hasso16705132003-05-25 14:49:19 +00001966 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001967 return CMD_SUCCESS;
1968}
1969
hasso16705132003-05-25 14:49:19 +00001970ALIAS (no_ip_rip_split_horizon,
1971 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1972 "no ip rip split-horizon poisoned-reverse",
1973 NO_STR
1974 IP_STR
1975 "Routing Information Protocol\n"
1976 "Perform split horizon\n"
1977 "With poisoned-reverse\n")
1978
paul718e3742002-12-13 20:15:29 +00001979DEFUN (rip_passive_interface,
1980 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001981 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001982 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001983 "Interface name\n"
1984 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001985{
paul4aaff3f2003-06-07 01:04:45 +00001986 char *ifname = argv[0];
1987
1988 if (!strcmp(ifname,"default")) {
1989 passive_default = 1;
1990 rip_passive_nondefault_clean();
1991 return CMD_SUCCESS;
1992 }
1993 if (passive_default)
1994 return rip_passive_nondefault_unset (vty, ifname);
1995 else
1996 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001997}
1998
1999DEFUN (no_rip_passive_interface,
2000 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00002001 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00002002 NO_STR
2003 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00002004 "Interface name\n"
2005 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00002006{
paul4aaff3f2003-06-07 01:04:45 +00002007 char *ifname = argv[0];
2008
2009 if (!strcmp(ifname,"default")) {
2010 passive_default = 0;
2011 rip_passive_nondefault_clean();
2012 return CMD_SUCCESS;
2013 }
2014 if (passive_default)
2015 return rip_passive_nondefault_set (vty, ifname);
2016 else
2017 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00002018}
2019
2020/* Write rip configuration of each interface. */
2021int
2022rip_interface_config_write (struct vty *vty)
2023{
2024 listnode node;
2025 struct interface *ifp;
2026
2027 for (node = listhead (iflist); node; nextnode (node))
2028 {
2029 struct rip_interface *ri;
2030
2031 ifp = getdata (node);
2032 ri = ifp->info;
2033
hasso16705132003-05-25 14:49:19 +00002034 /* Do not display the interface if there is no
2035 * configuration about it.
2036 **/
2037 if ((!ifp->desc) &&
2038 (ri->split_horizon == ri->split_horizon_default) &&
2039 (ri->ri_send == RI_RIP_UNSPEC) &&
2040 (ri->ri_receive == RI_RIP_UNSPEC) &&
2041 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00002042 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00002043 (!ri->auth_str) &&
2044 (!ri->key_chain) )
2045 continue;
2046
paul718e3742002-12-13 20:15:29 +00002047 vty_out (vty, "interface %s%s", ifp->name,
2048 VTY_NEWLINE);
2049
2050 if (ifp->desc)
2051 vty_out (vty, " description %s%s", ifp->desc,
2052 VTY_NEWLINE);
2053
2054 /* Split horizon. */
2055 if (ri->split_horizon != ri->split_horizon_default)
2056 {
hasso16705132003-05-25 14:49:19 +00002057 switch (ri->split_horizon) {
2058 case RIP_SPLIT_HORIZON:
2059 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
2060 break;
2061 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
2062 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
2063 VTY_NEWLINE);
2064 break;
2065 case RIP_NO_SPLIT_HORIZON:
2066 default:
2067 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2068 break;
2069 }
paul718e3742002-12-13 20:15:29 +00002070 }
2071
2072 /* RIP version setting. */
2073 if (ri->ri_send != RI_RIP_UNSPEC)
2074 vty_out (vty, " ip rip send version %s%s",
2075 lookup (ri_version_msg, ri->ri_send),
2076 VTY_NEWLINE);
2077
2078 if (ri->ri_receive != RI_RIP_UNSPEC)
2079 vty_out (vty, " ip rip receive version %s%s",
2080 lookup (ri_version_msg, ri->ri_receive),
2081 VTY_NEWLINE);
2082
2083 /* RIP authentication. */
2084#if 0
2085 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
2086 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2087 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
2088#endif /* 0 */
paulca5e5162004-06-06 22:06:33 +00002089
paul718e3742002-12-13 20:15:29 +00002090 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002091 {
2092 vty_out (vty, " ip rip authentication mode md5");
2093 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2094 vty_out (vty, " auth-length old-ripd");
2095 else
2096 vty_out (vty, " auth-length rfc");
2097 vty_out (vty, "%s", VTY_NEWLINE);
2098 }
paul718e3742002-12-13 20:15:29 +00002099
2100 if (ri->auth_str)
2101 vty_out (vty, " ip rip authentication string %s%s",
2102 ri->auth_str, VTY_NEWLINE);
2103
2104 if (ri->key_chain)
2105 vty_out (vty, " ip rip authentication key-chain %s%s",
2106 ri->key_chain, VTY_NEWLINE);
2107
2108 vty_out (vty, "!%s", VTY_NEWLINE);
2109 }
2110 return 0;
2111}
2112
2113int
2114config_write_rip_network (struct vty *vty, int config_mode)
2115{
2116 int i;
2117 char *ifname;
2118 struct route_node *node;
2119
2120 /* Network type RIP enable interface statement. */
2121 for (node = route_top (rip_enable_network); node; node = route_next (node))
2122 if (node->info)
2123 vty_out (vty, "%s%s/%d%s",
2124 config_mode ? " network " : " ",
2125 inet_ntoa (node->p.u.prefix4),
2126 node->p.prefixlen,
2127 VTY_NEWLINE);
2128
2129 /* Interface name RIP enable statement. */
2130 for (i = 0; i < vector_max (rip_enable_interface); i++)
2131 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2132 vty_out (vty, "%s%s%s",
2133 config_mode ? " network " : " ",
2134 ifname,
2135 VTY_NEWLINE);
2136
2137 /* RIP neighbors listing. */
2138 for (node = route_top (rip->neighbor); node; node = route_next (node))
2139 if (node->info)
2140 vty_out (vty, "%s%s%s",
2141 config_mode ? " neighbor " : " ",
2142 inet_ntoa (node->p.u.prefix4),
2143 VTY_NEWLINE);
2144
2145 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002146 if (config_mode) {
2147 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002148 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul4aaff3f2003-06-07 01:04:45 +00002149 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
2150 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2151 vty_out (vty, " %spassive-interface %s%s",
2152 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2153 }
paul718e3742002-12-13 20:15:29 +00002154
2155 return 0;
2156}
2157
2158struct cmd_node interface_node =
2159{
2160 INTERFACE_NODE,
2161 "%s(config-if)# ",
2162 1,
2163};
2164
2165/* Called when interface structure allocated. */
2166int
2167rip_interface_new_hook (struct interface *ifp)
2168{
2169 ifp->info = rip_interface_new ();
2170 return 0;
2171}
2172
2173/* Called when interface structure deleted. */
2174int
2175rip_interface_delete_hook (struct interface *ifp)
2176{
2177 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002178 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002179 return 0;
2180}
2181
2182/* Allocate and initialize interface vector. */
2183void
2184rip_if_init ()
2185{
2186 /* Default initial size of interface vector. */
2187 if_init();
2188 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2189 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2190
2191 /* RIP network init. */
2192 rip_enable_interface = vector_init (1);
2193 rip_enable_network = route_table_init ();
2194
2195 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002196 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002197
2198 /* Install interface node. */
2199 install_node (&interface_node, rip_interface_config_write);
2200
2201 /* Install commands. */
2202 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002203 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002204 install_default (INTERFACE_NODE);
2205 install_element (INTERFACE_NODE, &interface_desc_cmd);
2206 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2207 install_element (RIP_NODE, &rip_network_cmd);
2208 install_element (RIP_NODE, &no_rip_network_cmd);
2209 install_element (RIP_NODE, &rip_neighbor_cmd);
2210 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2211
2212 install_element (RIP_NODE, &rip_passive_interface_cmd);
2213 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2214
2215 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2216 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2217 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2218 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2219 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2220
2221 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2222 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2223 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2224 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2225 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2226
2227 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002228 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002229 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2230 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002231 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002232
2233 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2234 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2235 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2236
2237 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2238 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2239 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2240
hasso16705132003-05-25 14:49:19 +00002241 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2242 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2243 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2244 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002245}