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