blob: c1c0a45a9403c7af3eab3687884a1b4a1d54d9be [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);
hasso98b718a2004-10-11 12:57:57 +000047int rip_enable_if_lookup (const char *ifname);
hasso16705132003-05-25 14:49:19 +000048int 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;
hasso3fb9cd62004-10-19 19:44:43 +0000146 struct in_addr addr;
paulcc1131a2003-10-15 23:20:17 +0000147 struct prefix_ipv4 *p;
paulc49ad8f2004-10-22 10:27:28 +0000148
149 assert (connected != NULL);
150
151 if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected))
152 p = (struct prefix_ipv4 *) connected->destination;
153 else
154 p = (struct prefix_ipv4 *) connected->address;
155
156 addr = p->prefix;
paul718e3742002-12-13 20:15:29 +0000157
paul1a517862004-08-19 04:03:08 +0000158 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
159 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000160 {
161 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
162 "source address %s for interface %s",
163 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000164 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000165 return;
166 }
paul718e3742002-12-13 20:15:29 +0000167
hasso3fb9cd62004-10-19 19:44:43 +0000168 /* Bind myself. */
169 memset (&from, 0, sizeof (struct sockaddr_in));
paul718e3742002-12-13 20:15:29 +0000170
hasso3fb9cd62004-10-19 19:44:43 +0000171 /* Set RIP port. */
172 sp = getservbyname ("router", "udp");
173 if (sp)
174 from.sin_port = sp->s_port;
175 else
176 from.sin_port = htons (RIP_PORT_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000177
paul931cd542004-01-23 15:31:42 +0000178 /* Address should be any address. */
hasso3fb9cd62004-10-19 19:44:43 +0000179 from.sin_family = AF_INET;
paulc49ad8f2004-10-22 10:27:28 +0000180 from.sin_addr = connected->address->u.prefix4;
paul718e3742002-12-13 20:15:29 +0000181#ifdef HAVE_SIN_LEN
hasso3fb9cd62004-10-19 19:44:43 +0000182 from.sin_len = sizeof (struct sockaddr_in);
paul718e3742002-12-13 20:15:29 +0000183#endif /* HAVE_SIN_LEN */
184
hasso3fb9cd62004-10-19 19:44:43 +0000185 if (ripd_privs.change (ZPRIVS_RAISE))
186 zlog_err ("rip_interface_multicast_set: could not raise privs");
pauledd7c242003-06-04 13:59:38 +0000187
paulcc1131a2003-10-15 23:20:17 +0000188 ret = bind (sock, (struct sockaddr *) & from, sizeof (struct sockaddr_in));
hasso3fb9cd62004-10-19 19:44:43 +0000189 if (ret < 0)
190 {
191 zlog_warn ("Can't bind socket fd %d to %s port %d for "
192 "interface %s: %s",
193 sock,inet_ntoa(from.sin_addr),
194 (int)ntohs(from.sin_port),
paulc49ad8f2004-10-22 10:27:28 +0000195 connected->ifp->name,
hasso3fb9cd62004-10-19 19:44:43 +0000196 strerror (errno));
197 }
paul718e3742002-12-13 20:15:29 +0000198
hasso3fb9cd62004-10-19 19:44:43 +0000199 if (ripd_privs.change (ZPRIVS_LOWER))
200 zlog_err ("rip_interface_multicast_set: could not lower privs");
pauledd7c242003-06-04 13:59:38 +0000201
hasso3fb9cd62004-10-19 19:44:43 +0000202 return;
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 {
hasso52dc7ee2004-09-23 19:18:23 +0000225 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000226
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 {
paul718e3742002-12-13 20:15:29 +0000232 struct connected *connected;
233
234 connected = getdata (cnode);
paul718e3742002-12-13 20:15:29 +0000235
hasso3fb9cd62004-10-19 19:44:43 +0000236 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000237 {
238 memset (&to, 0, sizeof (struct sockaddr_in));
239 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000240 if (connected->destination)
241 /* use specified broadcast or point-to-point destination addr */
242 to.sin_addr = connected->destination->u.prefix4;
243 else
244 /* calculate the appropriate broadcast address */
245 to.sin_addr.s_addr =
246 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
247 connected->address->prefixlen);
paul718e3742002-12-13 20:15:29 +0000248
paul718e3742002-12-13 20:15:29 +0000249 if (IS_RIP_DEBUG_EVENT)
250 zlog_info ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000251
paul931cd542004-01-23 15:31:42 +0000252 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000253 }
254 }
255 }
256}
257
258/* This will be executed when interface goes up. */
259void
260rip_request_interface (struct interface *ifp)
261{
262 struct rip_interface *ri;
263
264 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
265 if (if_is_loopback (ifp))
266 return;
267
268 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000269 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000270 return;
271
272 /* Fetch RIP interface information. */
273 ri = ifp->info;
274
275
276 /* If there is no version configuration in the interface,
277 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000278 {
279 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
280 rip->version_send : ri->ri_send);
281 if (vsend & RIPv1)
282 rip_request_interface_send (ifp, RIPv1);
283 if (vsend & RIPv2)
284 rip_request_interface_send (ifp, RIPv2);
285 }
paul718e3742002-12-13 20:15:29 +0000286}
287
288/* Send RIP request to the neighbor. */
289void
290rip_request_neighbor (struct in_addr addr)
291{
292 struct sockaddr_in to;
293
294 memset (&to, 0, sizeof (struct sockaddr_in));
295 to.sin_port = htons (RIP_PORT_DEFAULT);
296 to.sin_addr = addr;
297
paul931cd542004-01-23 15:31:42 +0000298 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000299}
300
301/* Request routes at all interfaces. */
302void
303rip_request_neighbor_all ()
304{
305 struct route_node *rp;
306
307 if (! rip)
308 return;
309
310 if (IS_RIP_DEBUG_EVENT)
311 zlog_info ("request to the all neighbor");
312
313 /* Send request to all neighbor. */
314 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
315 if (rp->info)
316 rip_request_neighbor (rp->p.u.prefix4);
317}
318
319/* Multicast packet receive socket. */
320int
321rip_multicast_join (struct interface *ifp, int sock)
322{
hasso52dc7ee2004-09-23 19:18:23 +0000323 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000324
paul2e3b2e42002-12-13 21:03:13 +0000325 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000326 {
327 if (IS_RIP_DEBUG_EVENT)
328 zlog_info ("multicast join at %s", ifp->name);
329
330 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
331 {
332 struct prefix_ipv4 *p;
333 struct connected *connected;
334 struct in_addr group;
335
336 connected = getdata (cnode);
337 p = (struct prefix_ipv4 *) connected->address;
338
339 if (p->family != AF_INET)
340 continue;
341
342 group.s_addr = htonl (INADDR_RIP_GROUP);
343 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
344 return -1;
345 else
346 return 0;
347 }
348 }
349 return 0;
350}
351
352/* Leave from multicast group. */
353void
354rip_multicast_leave (struct interface *ifp, int sock)
355{
hasso52dc7ee2004-09-23 19:18:23 +0000356 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000357
358 if (if_is_up (ifp) && if_is_multicast (ifp))
359 {
360 if (IS_RIP_DEBUG_EVENT)
361 zlog_info ("multicast leave from %s", ifp->name);
362
363 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
364 {
365 struct prefix_ipv4 *p;
366 struct connected *connected;
367 struct in_addr group;
368
369 connected = getdata (cnode);
370 p = (struct prefix_ipv4 *) connected->address;
371
372 if (p->family != AF_INET)
373 continue;
374
375 group.s_addr = htonl (INADDR_RIP_GROUP);
376 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
377 return;
378 }
379 }
380}
381
382/* Is there and address on interface that I could use ? */
383int
384rip_if_ipv4_address_check (struct interface *ifp)
385{
386 struct listnode *nn;
387 struct connected *connected;
388 int count = 0;
389
390 for (nn = listhead (ifp->connected); nn; nextnode (nn))
391 if ((connected = getdata (nn)) != NULL)
392 {
393 struct prefix *p;
394
395 p = connected->address;
396
397 if (p->family == AF_INET)
398 {
399 count++;
400 }
401 }
402
403 return count;
404}
paul31a476c2003-09-29 19:54:53 +0000405
406
407
408
409/* Does this address belongs to me ? */
410int
411if_check_address (struct in_addr addr)
412{
hasso52dc7ee2004-09-23 19:18:23 +0000413 struct listnode *node;
paul31a476c2003-09-29 19:54:53 +0000414
415 for (node = listhead (iflist); node; nextnode (node))
416 {
hasso52dc7ee2004-09-23 19:18:23 +0000417 struct listnode *cnode;
paul31a476c2003-09-29 19:54:53 +0000418 struct interface *ifp;
419
420 ifp = getdata (node);
421
422 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
423 {
424 struct connected *connected;
425 struct prefix_ipv4 *p;
426
427 connected = getdata (cnode);
428 p = (struct prefix_ipv4 *) connected->address;
429
430 if (p->family != AF_INET)
431 continue;
432
433 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
434 return 1;
435 }
436 }
437 return 0;
438}
439
440/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
441int
442if_valid_neighbor (struct in_addr addr)
443{
hasso52dc7ee2004-09-23 19:18:23 +0000444 struct listnode *node;
paul31a476c2003-09-29 19:54:53 +0000445 struct connected *connected = NULL;
446 struct prefix_ipv4 *p;
hasso3fb9cd62004-10-19 19:44:43 +0000447 struct prefix_ipv4 pa;
448
449 pa.family = AF_INET;
450 pa.prefix = addr;
451 pa.prefixlen = IPV4_MAX_PREFIXLEN;
paul31a476c2003-09-29 19:54:53 +0000452
453 for (node = listhead (iflist); node; nextnode (node))
454 {
hasso52dc7ee2004-09-23 19:18:23 +0000455 struct listnode *cnode;
paul31a476c2003-09-29 19:54:53 +0000456 struct interface *ifp;
457
458 ifp = getdata (node);
459
460 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
461 {
paul31a476c2003-09-29 19:54:53 +0000462 connected = getdata (cnode);
463
464 if (if_is_pointopoint (ifp))
465 {
466 p = (struct prefix_ipv4 *) connected->address;
467
468 if (p && p->family == AF_INET)
469 {
470 if (IPV4_ADDR_SAME (&p->prefix, &addr))
471 return 1;
472
473 p = (struct prefix_ipv4 *) connected->destination;
hasso3fb9cd62004-10-19 19:44:43 +0000474 if (p)
475 {
476 if (IPV4_ADDR_SAME (&p->prefix, &addr))
477 return 1;
478 }
479 else
480 {
481 if (prefix_match(connected->address,(struct prefix *)&pa))
482 return 1;
483 }
paul31a476c2003-09-29 19:54:53 +0000484 }
485 }
486 else
487 {
hasso3fb9cd62004-10-19 19:44:43 +0000488 if ((connected->address->family == AF_INET) &&
489 prefix_match(connected->address,(struct prefix *)&pa))
490 return 1;
paul31a476c2003-09-29 19:54:53 +0000491 }
492 }
493 }
494 return 0;
495}
paul718e3742002-12-13 20:15:29 +0000496
497/* Inteface link down message processing. */
498int
499rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
500{
501 struct interface *ifp;
502 struct stream *s;
503
504 s = zclient->ibuf;
505
506 /* zebra_interface_state_read() updates interface structure in
507 iflist. */
508 ifp = zebra_interface_state_read(s);
509
510 if (ifp == NULL)
511 return 0;
512
513 rip_if_down(ifp);
514
515 if (IS_RIP_DEBUG_ZEBRA)
516 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is down",
517 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
518
519 return 0;
520}
521
522/* Inteface link up message processing */
523int
524rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
525{
526 struct interface *ifp;
527
528 /* zebra_interface_state_read () updates interface structure in
529 iflist. */
530 ifp = zebra_interface_state_read (zclient->ibuf);
531
532 if (ifp == NULL)
533 return 0;
534
535 if (IS_RIP_DEBUG_ZEBRA)
536 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is up",
537 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
538
539 /* Check if this interface is RIP enabled or not.*/
540 rip_enable_apply (ifp);
541
542 /* Check for a passive interface */
543 rip_passive_interface_apply (ifp);
544
545 /* Apply distribute list to the all interface. */
546 rip_distribute_update_interface (ifp);
547
548 return 0;
549}
550
551/* Inteface addition message from zebra. */
552int
553rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
554{
555 struct interface *ifp;
556
557 ifp = zebra_interface_add_read (zclient->ibuf);
558
559 if (IS_RIP_DEBUG_ZEBRA)
560 zlog_info ("interface add %s index %d flags %ld metric %d mtu %d",
561 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
562
563 /* Check if this interface is RIP enabled or not.*/
564 rip_enable_apply (ifp);
565
566 /* Apply distribute list to the all interface. */
567 rip_distribute_update_interface (ifp);
568
569 /* rip_request_neighbor_all (); */
570
hasso16705132003-05-25 14:49:19 +0000571 /* Check interface routemap. */
572 rip_if_rmap_update_interface (ifp);
573
paul718e3742002-12-13 20:15:29 +0000574 return 0;
575}
576
577int
578rip_interface_delete (int command, struct zclient *zclient,
579 zebra_size_t length)
580{
581 struct interface *ifp;
582 struct stream *s;
583
584
585 s = zclient->ibuf;
586 /* zebra_interface_state_read() updates interface structure in iflist */
587 ifp = zebra_interface_state_read(s);
588
589 if (ifp == NULL)
590 return 0;
591
592 if (if_is_up (ifp)) {
593 rip_if_down(ifp);
594 }
595
596 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
597 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
598
599 /* To support pseudo interface do not free interface structure. */
600 /* if_delete(ifp); */
601
602 return 0;
603}
604
605void
606rip_interface_clean ()
607{
hasso52dc7ee2004-09-23 19:18:23 +0000608 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000609 struct interface *ifp;
610 struct rip_interface *ri;
611
612 for (node = listhead (iflist); node; nextnode (node))
613 {
614 ifp = getdata (node);
615 ri = ifp->info;
616
617 ri->enable_network = 0;
618 ri->enable_interface = 0;
619 ri->running = 0;
620
621 if (ri->t_wakeup)
622 {
623 thread_cancel (ri->t_wakeup);
624 ri->t_wakeup = NULL;
625 }
626 }
627}
628
629void
630rip_interface_reset ()
631{
hasso52dc7ee2004-09-23 19:18:23 +0000632 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000633 struct interface *ifp;
634 struct rip_interface *ri;
635
636 for (node = listhead (iflist); node; nextnode (node))
637 {
638 ifp = getdata (node);
639 ri = ifp->info;
640
641 ri->enable_network = 0;
642 ri->enable_interface = 0;
643 ri->running = 0;
644
645 ri->ri_send = RI_RIP_UNSPEC;
646 ri->ri_receive = RI_RIP_UNSPEC;
647
648 /* ri->auth_type = RIP_NO_AUTH; */
649 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
650
651 if (ri->auth_str)
652 {
653 free (ri->auth_str);
654 ri->auth_str = NULL;
655 }
656 if (ri->key_chain)
657 {
658 free (ri->key_chain);
659 ri->key_chain = NULL;
660 }
661
hasso16705132003-05-25 14:49:19 +0000662 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
663 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000664
665 ri->list[RIP_FILTER_IN] = NULL;
666 ri->list[RIP_FILTER_OUT] = NULL;
667
668 ri->prefix[RIP_FILTER_IN] = NULL;
669 ri->prefix[RIP_FILTER_OUT] = NULL;
670
671 if (ri->t_wakeup)
672 {
673 thread_cancel (ri->t_wakeup);
674 ri->t_wakeup = NULL;
675 }
676
677 ri->recv_badpackets = 0;
678 ri->recv_badroutes = 0;
679 ri->sent_updates = 0;
680
681 ri->passive = 0;
682 }
683}
684
685int
686rip_if_down(struct interface *ifp)
687{
688 struct route_node *rp;
689 struct rip_info *rinfo;
690 struct rip_interface *ri = NULL;
691 if (rip)
692 {
693 for (rp = route_top (rip->table); rp; rp = route_next (rp))
694 if ((rinfo = rp->info) != NULL)
695 {
696 /* Routes got through this interface. */
697 if (rinfo->ifindex == ifp->ifindex &&
698 rinfo->type == ZEBRA_ROUTE_RIP &&
699 rinfo->sub_type == RIP_ROUTE_RTE)
700 {
701 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
702 &rinfo->nexthop,
703 rinfo->ifindex);
704
705 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
706 (struct prefix_ipv4 *)&rp->p,
707 rinfo->ifindex);
708 }
709 else
710 {
711 /* All redistributed routes but static and system */
712 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000713 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000714 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
715 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
716 (struct prefix_ipv4 *)&rp->p,
717 rinfo->ifindex);
718 }
719 }
720 }
721
722 ri = ifp->info;
723
724 if (ri->running)
725 {
726 if (IS_RIP_DEBUG_EVENT)
727 zlog_info ("turn off %s", ifp->name);
728
729 /* Leave from multicast group. */
730 rip_multicast_leave (ifp, rip->sock);
731
732 ri->running = 0;
733 }
734
735 return 0;
736}
737
738/* Needed for stop RIP process. */
739void
740rip_if_down_all ()
741{
742 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000743 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000744
745 for (node = listhead (iflist); node; nextnode (node))
746 {
747 ifp = getdata (node);
748 rip_if_down (ifp);
749 }
750}
751
hasso16705132003-05-25 14:49:19 +0000752static void
753rip_apply_address_add (struct connected *ifc) {
754 struct prefix_ipv4 address;
755 struct prefix *p;
756
757 if (!rip)
758 return;
759
760 if (! if_is_up(ifc->ifp))
761 return;
762
763 p = ifc->address;
764
765 memset (&address, 0, sizeof (address));
766 address.family = p->family;
767 address.prefix = p->u.prefix4;
768 address.prefixlen = p->prefixlen;
769 apply_mask_ipv4(&address);
770
771 /* Check if this interface is RIP enabled or not
772 or Check if this address's prefix is RIP enabled */
773 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
774 (rip_enable_network_lookup2(ifc) >= 0))
775 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
776 &address, ifc->ifp->ifindex, NULL);
777
778}
779
paul718e3742002-12-13 20:15:29 +0000780int
781rip_interface_address_add (int command, struct zclient *zclient,
782 zebra_size_t length)
783{
784 struct connected *ifc;
785 struct prefix *p;
786
paul0a589352004-05-08 11:48:26 +0000787 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
788 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000789
790 if (ifc == NULL)
791 return 0;
792
793 p = ifc->address;
794
795 if (p->family == AF_INET)
796 {
797 if (IS_RIP_DEBUG_ZEBRA)
798 zlog_info ("connected address %s/%d is added",
799 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000800
paul878ef2e2003-09-23 23:41:50 +0000801 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000802 /* Check if this prefix needs to be redistributed */
803 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000804
805#ifdef HAVE_SNMP
806 rip_ifaddr_add (ifc->ifp, ifc);
807#endif /* HAVE_SNMP */
808 }
809
810 return 0;
811}
812
hasso16705132003-05-25 14:49:19 +0000813static void
814rip_apply_address_del (struct connected *ifc) {
815 struct prefix_ipv4 address;
816 struct prefix *p;
817
818 if (!rip)
819 return;
820
821 if (! if_is_up(ifc->ifp))
822 return;
823
824 p = ifc->address;
825
826 memset (&address, 0, sizeof (address));
827 address.family = p->family;
828 address.prefix = p->u.prefix4;
829 address.prefixlen = p->prefixlen;
830 apply_mask_ipv4(&address);
831
832 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
833 &address, ifc->ifp->ifindex);
834}
835
paul718e3742002-12-13 20:15:29 +0000836int
837rip_interface_address_delete (int command, struct zclient *zclient,
838 zebra_size_t length)
839{
840 struct connected *ifc;
841 struct prefix *p;
842
paul0a589352004-05-08 11:48:26 +0000843 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
844 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000845
846 if (ifc)
847 {
848 p = ifc->address;
849 if (p->family == AF_INET)
850 {
851 if (IS_RIP_DEBUG_ZEBRA)
852
853 zlog_info ("connected address %s/%d is deleted",
854 inet_ntoa (p->u.prefix4), p->prefixlen);
855
856#ifdef HAVE_SNMP
857 rip_ifaddr_delete (ifc->ifp, ifc);
858#endif /* HAVE_SNMP */
859
hasso16705132003-05-25 14:49:19 +0000860 /* Chech wether this prefix needs to be removed */
861 rip_apply_address_del(ifc);
862
paul718e3742002-12-13 20:15:29 +0000863 }
864
865 connected_free (ifc);
866
867 }
868
869 return 0;
870}
871
872/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000873/* Check wether the interface has at least a connected prefix that
874 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000875int
hasso16705132003-05-25 14:49:19 +0000876rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000877{
878 struct listnode *nn;
879 struct connected *connected;
880 struct prefix_ipv4 address;
881
882 for (nn = listhead (ifp->connected); nn; nextnode (nn))
883 if ((connected = getdata (nn)) != NULL)
884 {
885 struct prefix *p;
886 struct route_node *node;
887
888 p = connected->address;
889
890 if (p->family == AF_INET)
891 {
892 address.family = AF_INET;
893 address.prefix = p->u.prefix4;
894 address.prefixlen = IPV4_MAX_BITLEN;
895
896 node = route_node_match (rip_enable_network,
897 (struct prefix *)&address);
898 if (node)
899 {
900 route_unlock_node (node);
901 return 1;
902 }
903 }
904 }
905 return -1;
906}
907
hasso16705132003-05-25 14:49:19 +0000908/* Check wether connected is within the ripng_enable_network table. */
909int
910rip_enable_network_lookup2 (struct connected *connected)
911{
912 struct prefix_ipv4 address;
913 struct prefix *p;
914
915 p = connected->address;
916
917 if (p->family == AF_INET) {
918 struct route_node *node;
919
920 address.family = p->family;
921 address.prefix = p->u.prefix4;
922 address.prefixlen = IPV4_MAX_BITLEN;
923
924 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
925 node = route_node_match (rip_enable_network,
926 (struct prefix *)&address);
927
928 if (node) {
929 route_unlock_node (node);
930 return 1;
931 }
932 }
933
934 return -1;
935}
paul718e3742002-12-13 20:15:29 +0000936/* Add RIP enable network. */
937int
938rip_enable_network_add (struct prefix *p)
939{
940 struct route_node *node;
941
942 node = route_node_get (rip_enable_network, p);
943
944 if (node->info)
945 {
946 route_unlock_node (node);
947 return -1;
948 }
949 else
hasso8a676be2004-10-08 06:36:38 +0000950 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000951
hasso16705132003-05-25 14:49:19 +0000952 /* XXX: One should find a better solution than a generic one */
953 rip_enable_apply_all();
954
paul718e3742002-12-13 20:15:29 +0000955 return 1;
956}
957
958/* Delete RIP enable network. */
959int
960rip_enable_network_delete (struct prefix *p)
961{
962 struct route_node *node;
963
964 node = route_node_lookup (rip_enable_network, p);
965 if (node)
966 {
967 node->info = NULL;
968
969 /* Unlock info lock. */
970 route_unlock_node (node);
971
972 /* Unlock lookup lock. */
973 route_unlock_node (node);
974
hasso16705132003-05-25 14:49:19 +0000975 /* XXX: One should find a better solution than a generic one */
976 rip_enable_apply_all ();
977
paul718e3742002-12-13 20:15:29 +0000978 return 1;
979 }
980 return -1;
981}
982
983/* Check interface is enabled by ifname statement. */
984int
hasso98b718a2004-10-11 12:57:57 +0000985rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000986{
hasso8a676be2004-10-08 06:36:38 +0000987 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000988 char *str;
989
990 for (i = 0; i < vector_max (rip_enable_interface); i++)
991 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
992 if (strcmp (str, ifname) == 0)
993 return i;
994 return -1;
995}
996
997/* Add interface to rip_enable_if. */
998int
hasso98b718a2004-10-11 12:57:57 +0000999rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001000{
1001 int ret;
1002
1003 ret = rip_enable_if_lookup (ifname);
1004 if (ret >= 0)
1005 return -1;
1006
1007 vector_set (rip_enable_interface, strdup (ifname));
1008
hasso16705132003-05-25 14:49:19 +00001009 rip_enable_apply_all(); /* TODOVJ */
1010
paul718e3742002-12-13 20:15:29 +00001011 return 1;
1012}
1013
1014/* Delete interface from rip_enable_if. */
1015int
hasso98b718a2004-10-11 12:57:57 +00001016rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001017{
1018 int index;
1019 char *str;
1020
1021 index = rip_enable_if_lookup (ifname);
1022 if (index < 0)
1023 return -1;
1024
1025 str = vector_slot (rip_enable_interface, index);
1026 free (str);
1027 vector_unset (rip_enable_interface, index);
1028
hasso16705132003-05-25 14:49:19 +00001029 rip_enable_apply_all(); /* TODOVJ */
1030
paul718e3742002-12-13 20:15:29 +00001031 return 1;
1032}
1033
1034/* Join to multicast group and send request to the interface. */
1035int
1036rip_interface_wakeup (struct thread *t)
1037{
1038 struct interface *ifp;
1039 struct rip_interface *ri;
1040
1041 /* Get interface. */
1042 ifp = THREAD_ARG (t);
1043
1044 ri = ifp->info;
1045 ri->t_wakeup = NULL;
1046
1047 /* Join to multicast group. */
1048 if (rip_multicast_join (ifp, rip->sock) < 0)
1049 {
1050 zlog_err ("multicast join failed, interface %s not running", ifp->name);
1051 return 0;
1052 }
1053
1054 /* Set running flag. */
1055 ri->running = 1;
1056
1057 /* Send RIP request to the interface. */
1058 rip_request_interface (ifp);
1059
1060 return 0;
1061}
1062
1063int rip_redistribute_check (int);
1064
1065void
1066rip_connect_set (struct interface *ifp, int set)
1067{
1068 struct listnode *nn;
1069 struct connected *connected;
1070 struct prefix_ipv4 address;
1071
1072 for (nn = listhead (ifp->connected); nn; nextnode (nn))
1073 if ((connected = getdata (nn)) != NULL)
1074 {
1075 struct prefix *p;
1076 p = connected->address;
1077
1078 if (p->family != AF_INET)
1079 continue;
1080
1081 address.family = AF_INET;
1082 address.prefix = p->u.prefix4;
1083 address.prefixlen = p->prefixlen;
1084 apply_mask_ipv4 (&address);
1085
hasso16705132003-05-25 14:49:19 +00001086 if (set) {
1087 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1088 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1089 (rip_enable_network_lookup2(connected) >= 0))
1090 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1091 &address, connected->ifp->ifindex, NULL);
1092 } else
paul718e3742002-12-13 20:15:29 +00001093 {
1094 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1095 &address, connected->ifp->ifindex);
1096 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1097 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1098 &address, connected->ifp->ifindex, NULL);
1099 }
1100 }
1101}
1102
1103/* Update interface status. */
1104void
1105rip_enable_apply (struct interface *ifp)
1106{
1107 int ret;
1108 struct rip_interface *ri = NULL;
1109
1110 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001111 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001112 return;
1113
1114 ri = ifp->info;
1115
1116 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001117 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001118
1119 /* If the interface is matched. */
1120 if (ret > 0)
1121 ri->enable_network = 1;
1122 else
1123 ri->enable_network = 0;
1124
1125 /* Check interface name configuration. */
1126 ret = rip_enable_if_lookup (ifp->name);
1127 if (ret >= 0)
1128 ri->enable_interface = 1;
1129 else
1130 ri->enable_interface = 0;
1131
1132 /* any interface MUST have an IPv4 address */
1133 if ( ! rip_if_ipv4_address_check (ifp) )
1134 {
1135 ri->enable_network = 0;
1136 ri->enable_interface = 0;
1137 }
1138
1139 /* Update running status of the interface. */
1140 if (ri->enable_network || ri->enable_interface)
1141 {
paul718e3742002-12-13 20:15:29 +00001142 {
1143 if (IS_RIP_DEBUG_EVENT)
1144 zlog_info ("turn on %s", ifp->name);
1145
1146 /* Add interface wake up thread. */
1147 if (! ri->t_wakeup)
1148 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1149 ifp, 1);
1150 rip_connect_set (ifp, 1);
1151 }
1152 }
1153 else
1154 {
1155 if (ri->running)
1156 {
hasso16705132003-05-25 14:49:19 +00001157 /* Might as well clean up the route table as well
1158 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1159 **/
paul718e3742002-12-13 20:15:29 +00001160 rip_if_down(ifp);
1161
paul718e3742002-12-13 20:15:29 +00001162 rip_connect_set (ifp, 0);
1163 }
1164 }
1165}
1166
1167/* Apply network configuration to all interface. */
1168void
1169rip_enable_apply_all ()
1170{
1171 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +00001172 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001173
1174 /* Check each interface. */
1175 for (node = listhead (iflist); node; nextnode (node))
1176 {
1177 ifp = getdata (node);
1178 rip_enable_apply (ifp);
1179 }
1180}
1181
1182int
1183rip_neighbor_lookup (struct sockaddr_in *from)
1184{
1185 struct prefix_ipv4 p;
1186 struct route_node *node;
1187
1188 memset (&p, 0, sizeof (struct prefix_ipv4));
1189 p.family = AF_INET;
1190 p.prefix = from->sin_addr;
1191 p.prefixlen = IPV4_MAX_BITLEN;
1192
1193 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1194 if (node)
1195 {
1196 route_unlock_node (node);
1197 return 1;
1198 }
1199 return 0;
1200}
1201
1202/* Add new RIP neighbor to the neighbor tree. */
1203int
1204rip_neighbor_add (struct prefix_ipv4 *p)
1205{
1206 struct route_node *node;
1207
1208 node = route_node_get (rip->neighbor, (struct prefix *) p);
1209
1210 if (node->info)
1211 return -1;
1212
1213 node->info = rip->neighbor;
1214
1215 return 0;
1216}
1217
1218/* Delete RIP neighbor from the neighbor tree. */
1219int
1220rip_neighbor_delete (struct prefix_ipv4 *p)
1221{
1222 struct route_node *node;
1223
1224 /* Lock for look up. */
1225 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1226 if (! node)
1227 return -1;
1228
1229 node->info = NULL;
1230
1231 /* Unlock lookup lock. */
1232 route_unlock_node (node);
1233
1234 /* Unlock real neighbor information lock. */
1235 route_unlock_node (node);
1236
1237 return 0;
1238}
1239
1240/* Clear all network and neighbor configuration. */
1241void
1242rip_clean_network ()
1243{
hasso8a676be2004-10-08 06:36:38 +00001244 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001245 char *str;
1246 struct route_node *rn;
1247
1248 /* rip_enable_network. */
1249 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1250 if (rn->info)
1251 {
1252 rn->info = NULL;
1253 route_unlock_node (rn);
1254 }
1255
1256 /* rip_enable_interface. */
1257 for (i = 0; i < vector_max (rip_enable_interface); i++)
1258 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1259 {
1260 free (str);
1261 vector_slot (rip_enable_interface, i) = NULL;
1262 }
1263}
1264
1265/* Utility function for looking up passive interface settings. */
1266int
hasso98b718a2004-10-11 12:57:57 +00001267rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001268{
hasso8a676be2004-10-08 06:36:38 +00001269 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001270 char *str;
1271
paul4aaff3f2003-06-07 01:04:45 +00001272 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1273 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001274 if (strcmp (str, ifname) == 0)
1275 return i;
1276 return -1;
1277}
1278
1279void
1280rip_passive_interface_apply (struct interface *ifp)
1281{
paul718e3742002-12-13 20:15:29 +00001282 struct rip_interface *ri;
1283
1284 ri = ifp->info;
1285
paul4aaff3f2003-06-07 01:04:45 +00001286 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1287 passive_default : !passive_default);
1288
1289 if (IS_RIP_DEBUG_ZEBRA)
1290 zlog_info ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001291}
1292
1293void
1294rip_passive_interface_apply_all ()
1295{
1296 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +00001297 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001298
1299 for (node = listhead (iflist); node; nextnode (node))
1300 {
1301 ifp = getdata (node);
1302 rip_passive_interface_apply (ifp);
1303 }
1304}
1305
1306/* Passive interface. */
1307int
hasso98b718a2004-10-11 12:57:57 +00001308rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001309{
paul4aaff3f2003-06-07 01:04:45 +00001310 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001311 return CMD_WARNING;
1312
paul4aaff3f2003-06-07 01:04:45 +00001313 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001314
1315 rip_passive_interface_apply_all ();
1316
1317 return CMD_SUCCESS;
1318}
1319
1320int
hasso98b718a2004-10-11 12:57:57 +00001321rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001322{
1323 int i;
1324 char *str;
1325
paul4aaff3f2003-06-07 01:04:45 +00001326 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001327 if (i < 0)
1328 return CMD_WARNING;
1329
paul4aaff3f2003-06-07 01:04:45 +00001330 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001331 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001332 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001333
1334 rip_passive_interface_apply_all ();
1335
1336 return CMD_SUCCESS;
1337}
1338
1339/* Free all configured RIP passive-interface settings. */
1340void
paul4aaff3f2003-06-07 01:04:45 +00001341rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001342{
hasso8a676be2004-10-08 06:36:38 +00001343 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001344 char *str;
1345
paul4aaff3f2003-06-07 01:04:45 +00001346 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1347 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001348 {
1349 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001350 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001351 }
1352 rip_passive_interface_apply_all ();
1353}
1354
1355/* RIP enable network or interface configuration. */
1356DEFUN (rip_network,
1357 rip_network_cmd,
1358 "network (A.B.C.D/M|WORD)",
1359 "Enable routing on an IP network\n"
1360 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1361 "Interface name\n")
1362{
1363 int ret;
1364 struct prefix_ipv4 p;
1365
1366 ret = str2prefix_ipv4 (argv[0], &p);
1367
1368 if (ret)
1369 ret = rip_enable_network_add ((struct prefix *) &p);
1370 else
1371 ret = rip_enable_if_add (argv[0]);
1372
1373 if (ret < 0)
1374 {
1375 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1376 VTY_NEWLINE);
1377 return CMD_WARNING;
1378 }
1379
paul718e3742002-12-13 20:15:29 +00001380 return CMD_SUCCESS;
1381}
1382
1383/* RIP enable network or interface configuration. */
1384DEFUN (no_rip_network,
1385 no_rip_network_cmd,
1386 "no network (A.B.C.D/M|WORD)",
1387 NO_STR
1388 "Enable routing on an IP network\n"
1389 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1390 "Interface name\n")
1391{
1392 int ret;
1393 struct prefix_ipv4 p;
1394
1395 ret = str2prefix_ipv4 (argv[0], &p);
1396
1397 if (ret)
1398 ret = rip_enable_network_delete ((struct prefix *) &p);
1399 else
1400 ret = rip_enable_if_delete (argv[0]);
1401
1402 if (ret < 0)
1403 {
1404 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1405 VTY_NEWLINE);
1406 return CMD_WARNING;
1407 }
1408
paul718e3742002-12-13 20:15:29 +00001409 return CMD_SUCCESS;
1410}
1411
1412/* RIP neighbor configuration set. */
1413DEFUN (rip_neighbor,
1414 rip_neighbor_cmd,
1415 "neighbor A.B.C.D",
1416 "Specify a neighbor router\n"
1417 "Neighbor address\n")
1418{
1419 int ret;
1420 struct prefix_ipv4 p;
1421
1422 ret = str2prefix_ipv4 (argv[0], &p);
1423
1424 if (ret <= 0)
1425 {
1426 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1427 return CMD_WARNING;
1428 }
1429
1430 rip_neighbor_add (&p);
1431
1432 return CMD_SUCCESS;
1433}
1434
1435/* RIP neighbor configuration unset. */
1436DEFUN (no_rip_neighbor,
1437 no_rip_neighbor_cmd,
1438 "no neighbor A.B.C.D",
1439 NO_STR
1440 "Specify a neighbor router\n"
1441 "Neighbor address\n")
1442{
1443 int ret;
1444 struct prefix_ipv4 p;
1445
1446 ret = str2prefix_ipv4 (argv[0], &p);
1447
1448 if (ret <= 0)
1449 {
1450 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1451 return CMD_WARNING;
1452 }
1453
1454 rip_neighbor_delete (&p);
1455
1456 return CMD_SUCCESS;
1457}
1458
1459DEFUN (ip_rip_receive_version,
1460 ip_rip_receive_version_cmd,
1461 "ip rip receive version (1|2)",
1462 IP_STR
1463 "Routing Information Protocol\n"
1464 "Advertisement reception\n"
1465 "Version control\n"
1466 "RIP version 1\n"
1467 "RIP version 2\n")
1468{
1469 struct interface *ifp;
1470 struct rip_interface *ri;
1471
1472 ifp = (struct interface *)vty->index;
1473 ri = ifp->info;
1474
1475 /* Version 1. */
1476 if (atoi (argv[0]) == 1)
1477 {
1478 ri->ri_receive = RI_RIP_VERSION_1;
1479 return CMD_SUCCESS;
1480 }
1481 if (atoi (argv[0]) == 2)
1482 {
1483 ri->ri_receive = RI_RIP_VERSION_2;
1484 return CMD_SUCCESS;
1485 }
1486 return CMD_WARNING;
1487}
1488
1489DEFUN (ip_rip_receive_version_1,
1490 ip_rip_receive_version_1_cmd,
1491 "ip rip receive version 1 2",
1492 IP_STR
1493 "Routing Information Protocol\n"
1494 "Advertisement reception\n"
1495 "Version control\n"
1496 "RIP version 1\n"
1497 "RIP version 2\n")
1498{
1499 struct interface *ifp;
1500 struct rip_interface *ri;
1501
1502 ifp = (struct interface *)vty->index;
1503 ri = ifp->info;
1504
1505 /* Version 1 and 2. */
1506 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1507 return CMD_SUCCESS;
1508}
1509
1510DEFUN (ip_rip_receive_version_2,
1511 ip_rip_receive_version_2_cmd,
1512 "ip rip receive version 2 1",
1513 IP_STR
1514 "Routing Information Protocol\n"
1515 "Advertisement reception\n"
1516 "Version control\n"
1517 "RIP version 2\n"
1518 "RIP version 1\n")
1519{
1520 struct interface *ifp;
1521 struct rip_interface *ri;
1522
1523 ifp = (struct interface *)vty->index;
1524 ri = ifp->info;
1525
1526 /* Version 1 and 2. */
1527 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1528 return CMD_SUCCESS;
1529}
1530
1531DEFUN (no_ip_rip_receive_version,
1532 no_ip_rip_receive_version_cmd,
1533 "no ip rip receive version",
1534 NO_STR
1535 IP_STR
1536 "Routing Information Protocol\n"
1537 "Advertisement reception\n"
1538 "Version control\n")
1539{
1540 struct interface *ifp;
1541 struct rip_interface *ri;
1542
1543 ifp = (struct interface *)vty->index;
1544 ri = ifp->info;
1545
1546 ri->ri_receive = RI_RIP_UNSPEC;
1547 return CMD_SUCCESS;
1548}
1549
1550ALIAS (no_ip_rip_receive_version,
1551 no_ip_rip_receive_version_num_cmd,
1552 "no ip rip receive version (1|2)",
1553 NO_STR
1554 IP_STR
1555 "Routing Information Protocol\n"
1556 "Advertisement reception\n"
1557 "Version control\n"
1558 "Version 1\n"
1559 "Version 2\n")
1560
1561DEFUN (ip_rip_send_version,
1562 ip_rip_send_version_cmd,
1563 "ip rip send version (1|2)",
1564 IP_STR
1565 "Routing Information Protocol\n"
1566 "Advertisement transmission\n"
1567 "Version control\n"
1568 "RIP version 1\n"
1569 "RIP version 2\n")
1570{
1571 struct interface *ifp;
1572 struct rip_interface *ri;
1573
1574 ifp = (struct interface *)vty->index;
1575 ri = ifp->info;
1576
1577 /* Version 1. */
1578 if (atoi (argv[0]) == 1)
1579 {
1580 ri->ri_send = RI_RIP_VERSION_1;
1581 return CMD_SUCCESS;
1582 }
1583 if (atoi (argv[0]) == 2)
1584 {
1585 ri->ri_send = RI_RIP_VERSION_2;
1586 return CMD_SUCCESS;
1587 }
1588 return CMD_WARNING;
1589}
1590
1591DEFUN (ip_rip_send_version_1,
1592 ip_rip_send_version_1_cmd,
1593 "ip rip send version 1 2",
1594 IP_STR
1595 "Routing Information Protocol\n"
1596 "Advertisement transmission\n"
1597 "Version control\n"
1598 "RIP version 1\n"
1599 "RIP version 2\n")
1600{
1601 struct interface *ifp;
1602 struct rip_interface *ri;
1603
1604 ifp = (struct interface *)vty->index;
1605 ri = ifp->info;
1606
1607 /* Version 1 and 2. */
1608 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1609 return CMD_SUCCESS;
1610}
1611
1612DEFUN (ip_rip_send_version_2,
1613 ip_rip_send_version_2_cmd,
1614 "ip rip send version 2 1",
1615 IP_STR
1616 "Routing Information Protocol\n"
1617 "Advertisement transmission\n"
1618 "Version control\n"
1619 "RIP version 2\n"
1620 "RIP version 1\n")
1621{
1622 struct interface *ifp;
1623 struct rip_interface *ri;
1624
1625 ifp = (struct interface *)vty->index;
1626 ri = ifp->info;
1627
1628 /* Version 1 and 2. */
1629 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1630 return CMD_SUCCESS;
1631}
1632
1633DEFUN (no_ip_rip_send_version,
1634 no_ip_rip_send_version_cmd,
1635 "no ip rip send version",
1636 NO_STR
1637 IP_STR
1638 "Routing Information Protocol\n"
1639 "Advertisement transmission\n"
1640 "Version control\n")
1641{
1642 struct interface *ifp;
1643 struct rip_interface *ri;
1644
1645 ifp = (struct interface *)vty->index;
1646 ri = ifp->info;
1647
1648 ri->ri_send = RI_RIP_UNSPEC;
1649 return CMD_SUCCESS;
1650}
1651
1652ALIAS (no_ip_rip_send_version,
1653 no_ip_rip_send_version_num_cmd,
1654 "no ip rip send version (1|2)",
1655 NO_STR
1656 IP_STR
1657 "Routing Information Protocol\n"
1658 "Advertisement transmission\n"
1659 "Version control\n"
1660 "Version 1\n"
1661 "Version 2\n")
1662
1663DEFUN (ip_rip_authentication_mode,
1664 ip_rip_authentication_mode_cmd,
1665 "ip rip authentication mode (md5|text)",
1666 IP_STR
1667 "Routing Information Protocol\n"
1668 "Authentication control\n"
1669 "Authentication mode\n"
1670 "Keyed message digest\n"
1671 "Clear text authentication\n")
1672{
1673 struct interface *ifp;
1674 struct rip_interface *ri;
1675
1676 ifp = (struct interface *)vty->index;
1677 ri = ifp->info;
1678
paulca5e5162004-06-06 22:06:33 +00001679 if ( (argc < 1) || (argc > 2) )
1680 {
1681 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1682 return CMD_WARNING;
1683 }
1684
paul718e3742002-12-13 20:15:29 +00001685 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1686 ri->auth_type = RIP_AUTH_MD5;
1687 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1688 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1689 else
1690 {
1691 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1692 return CMD_WARNING;
1693 }
1694
paulca5e5162004-06-06 22:06:33 +00001695 if (argc == 1)
1696 return CMD_SUCCESS;
1697
1698 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1699 {
1700 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1701 return CMD_WARNING;
1702}
1703
1704 if (strncmp ("r", argv[1], 1) == 0)
1705 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1706 else if (strncmp ("o", argv[1], 1) == 0)
1707 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1708 else
1709 return CMD_WARNING;
1710
paul718e3742002-12-13 20:15:29 +00001711 return CMD_SUCCESS;
1712}
1713
paulca5e5162004-06-06 22:06:33 +00001714ALIAS (ip_rip_authentication_mode,
1715 ip_rip_authentication_mode_authlen_cmd,
1716 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1717 IP_STR
1718 "Routing Information Protocol\n"
1719 "Authentication control\n"
1720 "Authentication mode\n"
1721 "Keyed message digest\n"
1722 "Clear text authentication\n"
1723 "MD5 authentication data length\n"
1724 "RFC compatible\n"
1725 "Old ripd compatible\n")
1726
paul718e3742002-12-13 20:15:29 +00001727DEFUN (no_ip_rip_authentication_mode,
1728 no_ip_rip_authentication_mode_cmd,
1729 "no ip rip authentication mode",
1730 NO_STR
1731 IP_STR
1732 "Routing Information Protocol\n"
1733 "Authentication control\n"
1734 "Authentication mode\n")
1735{
1736 struct interface *ifp;
1737 struct rip_interface *ri;
1738
1739 ifp = (struct interface *)vty->index;
1740 ri = ifp->info;
1741
1742 /* ri->auth_type = RIP_NO_AUTH; */
1743 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paulca5e5162004-06-06 22:06:33 +00001744 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001745
1746 return CMD_SUCCESS;
1747}
1748
1749ALIAS (no_ip_rip_authentication_mode,
1750 no_ip_rip_authentication_mode_type_cmd,
1751 "no ip rip authentication mode (md5|text)",
1752 NO_STR
1753 IP_STR
1754 "Routing Information Protocol\n"
1755 "Authentication control\n"
1756 "Authentication mode\n"
1757 "Keyed message digest\n"
1758 "Clear text authentication\n")
1759
paulca5e5162004-06-06 22:06:33 +00001760ALIAS (no_ip_rip_authentication_mode,
1761 no_ip_rip_authentication_mode_type_authlen_cmd,
1762 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1763 NO_STR
1764 IP_STR
1765 "Routing Information Protocol\n"
1766 "Authentication control\n"
1767 "Authentication mode\n"
1768 "Keyed message digest\n"
1769 "Clear text authentication\n"
1770 "MD5 authentication data length\n"
1771 "RFC compatible\n"
1772 "Old ripd compatible\n")
1773
paul718e3742002-12-13 20:15:29 +00001774DEFUN (ip_rip_authentication_string,
1775 ip_rip_authentication_string_cmd,
1776 "ip rip authentication string LINE",
1777 IP_STR
1778 "Routing Information Protocol\n"
1779 "Authentication control\n"
1780 "Authentication string\n"
1781 "Authentication string\n")
1782{
1783 struct interface *ifp;
1784 struct rip_interface *ri;
1785
1786 ifp = (struct interface *)vty->index;
1787 ri = ifp->info;
1788
1789 if (strlen (argv[0]) > 16)
1790 {
1791 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1792 VTY_NEWLINE);
1793 return CMD_WARNING;
1794 }
1795
1796 if (ri->key_chain)
1797 {
1798 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1799 return CMD_WARNING;
1800 }
1801
1802 if (ri->auth_str)
1803 free (ri->auth_str);
1804
1805 ri->auth_str = strdup (argv[0]);
1806
1807 return CMD_SUCCESS;
1808}
1809
1810DEFUN (no_ip_rip_authentication_string,
1811 no_ip_rip_authentication_string_cmd,
1812 "no ip rip authentication string",
1813 NO_STR
1814 IP_STR
1815 "Routing Information Protocol\n"
1816 "Authentication control\n"
1817 "Authentication string\n")
1818{
1819 struct interface *ifp;
1820 struct rip_interface *ri;
1821
1822 ifp = (struct interface *)vty->index;
1823 ri = ifp->info;
1824
1825 if (ri->auth_str)
1826 free (ri->auth_str);
1827
1828 ri->auth_str = NULL;
1829
1830 return CMD_SUCCESS;
1831}
1832
1833ALIAS (no_ip_rip_authentication_string,
1834 no_ip_rip_authentication_string2_cmd,
1835 "no ip rip authentication string LINE",
1836 NO_STR
1837 IP_STR
1838 "Routing Information Protocol\n"
1839 "Authentication control\n"
1840 "Authentication string\n"
1841 "Authentication string\n")
1842
1843DEFUN (ip_rip_authentication_key_chain,
1844 ip_rip_authentication_key_chain_cmd,
1845 "ip rip authentication key-chain LINE",
1846 IP_STR
1847 "Routing Information Protocol\n"
1848 "Authentication control\n"
1849 "Authentication key-chain\n"
1850 "name of key-chain\n")
1851{
1852 struct interface *ifp;
1853 struct rip_interface *ri;
1854
1855 ifp = (struct interface *) vty->index;
1856 ri = ifp->info;
1857
1858 if (ri->auth_str)
1859 {
1860 vty_out (vty, "%% authentication string configuration exists%s",
1861 VTY_NEWLINE);
1862 return CMD_WARNING;
1863 }
1864
1865 if (ri->key_chain)
1866 free (ri->key_chain);
1867
1868 ri->key_chain = strdup (argv[0]);
1869
1870 return CMD_SUCCESS;
1871}
1872
1873DEFUN (no_ip_rip_authentication_key_chain,
1874 no_ip_rip_authentication_key_chain_cmd,
1875 "no ip rip authentication key-chain",
1876 NO_STR
1877 IP_STR
1878 "Routing Information Protocol\n"
1879 "Authentication control\n"
1880 "Authentication key-chain\n")
1881{
1882 struct interface *ifp;
1883 struct rip_interface *ri;
1884
1885 ifp = (struct interface *) vty->index;
1886 ri = ifp->info;
1887
1888 if (ri->key_chain)
1889 free (ri->key_chain);
1890
1891 ri->key_chain = NULL;
1892
1893 return CMD_SUCCESS;
1894}
1895
1896ALIAS (no_ip_rip_authentication_key_chain,
1897 no_ip_rip_authentication_key_chain2_cmd,
1898 "no ip rip authentication key-chain LINE",
1899 NO_STR
1900 IP_STR
1901 "Routing Information Protocol\n"
1902 "Authentication control\n"
1903 "Authentication key-chain\n"
1904 "name of key-chain\n")
1905
hasso16705132003-05-25 14:49:19 +00001906/* CHANGED: ip rip split-horizon
1907 Cisco and Zebra's command is
1908 ip split-horizon
1909 */
1910DEFUN (ip_rip_split_horizon,
1911 ip_rip_split_horizon_cmd,
1912 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001913 IP_STR
hasso16705132003-05-25 14:49:19 +00001914 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001915 "Perform split horizon\n")
1916{
1917 struct interface *ifp;
1918 struct rip_interface *ri;
1919
1920 ifp = vty->index;
1921 ri = ifp->info;
1922
hasso16705132003-05-25 14:49:19 +00001923 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001924 return CMD_SUCCESS;
1925}
1926
hasso16705132003-05-25 14:49:19 +00001927DEFUN (ip_rip_split_horizon_poisoned_reverse,
1928 ip_rip_split_horizon_poisoned_reverse_cmd,
1929 "ip rip split-horizon poisoned-reverse",
1930 IP_STR
1931 "Routing Information Protocol\n"
1932 "Perform split horizon\n"
1933 "With poisoned-reverse\n")
1934{
1935 struct interface *ifp;
1936 struct rip_interface *ri;
1937
1938 ifp = vty->index;
1939 ri = ifp->info;
1940
1941 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1942 return CMD_SUCCESS;
1943}
1944
1945/* CHANGED: no ip rip split-horizon
1946 Cisco and Zebra's command is
1947 no ip split-horizon
1948 */
1949DEFUN (no_ip_rip_split_horizon,
1950 no_ip_rip_split_horizon_cmd,
1951 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001952 NO_STR
1953 IP_STR
hasso16705132003-05-25 14:49:19 +00001954 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001955 "Perform split horizon\n")
1956{
1957 struct interface *ifp;
1958 struct rip_interface *ri;
1959
1960 ifp = vty->index;
1961 ri = ifp->info;
1962
hasso16705132003-05-25 14:49:19 +00001963 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001964 return CMD_SUCCESS;
1965}
1966
hasso16705132003-05-25 14:49:19 +00001967ALIAS (no_ip_rip_split_horizon,
1968 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1969 "no ip rip split-horizon poisoned-reverse",
1970 NO_STR
1971 IP_STR
1972 "Routing Information Protocol\n"
1973 "Perform split horizon\n"
1974 "With poisoned-reverse\n")
1975
paul718e3742002-12-13 20:15:29 +00001976DEFUN (rip_passive_interface,
1977 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001978 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001979 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001980 "Interface name\n"
1981 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001982{
hasso98b718a2004-10-11 12:57:57 +00001983 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001984
1985 if (!strcmp(ifname,"default")) {
1986 passive_default = 1;
1987 rip_passive_nondefault_clean();
1988 return CMD_SUCCESS;
1989 }
1990 if (passive_default)
1991 return rip_passive_nondefault_unset (vty, ifname);
1992 else
1993 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001994}
1995
1996DEFUN (no_rip_passive_interface,
1997 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001998 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001999 NO_STR
2000 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00002001 "Interface name\n"
2002 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00002003{
hasso98b718a2004-10-11 12:57:57 +00002004 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00002005
2006 if (!strcmp(ifname,"default")) {
2007 passive_default = 0;
2008 rip_passive_nondefault_clean();
2009 return CMD_SUCCESS;
2010 }
2011 if (passive_default)
2012 return rip_passive_nondefault_set (vty, ifname);
2013 else
2014 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00002015}
2016
2017/* Write rip configuration of each interface. */
2018int
2019rip_interface_config_write (struct vty *vty)
2020{
hasso52dc7ee2004-09-23 19:18:23 +00002021 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002022 struct interface *ifp;
2023
2024 for (node = listhead (iflist); node; nextnode (node))
2025 {
2026 struct rip_interface *ri;
2027
2028 ifp = getdata (node);
2029 ri = ifp->info;
2030
hasso16705132003-05-25 14:49:19 +00002031 /* Do not display the interface if there is no
2032 * configuration about it.
2033 **/
2034 if ((!ifp->desc) &&
2035 (ri->split_horizon == ri->split_horizon_default) &&
2036 (ri->ri_send == RI_RIP_UNSPEC) &&
2037 (ri->ri_receive == RI_RIP_UNSPEC) &&
2038 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00002039 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00002040 (!ri->auth_str) &&
2041 (!ri->key_chain) )
2042 continue;
2043
paul718e3742002-12-13 20:15:29 +00002044 vty_out (vty, "interface %s%s", ifp->name,
2045 VTY_NEWLINE);
2046
2047 if (ifp->desc)
2048 vty_out (vty, " description %s%s", ifp->desc,
2049 VTY_NEWLINE);
2050
2051 /* Split horizon. */
2052 if (ri->split_horizon != ri->split_horizon_default)
2053 {
hasso16705132003-05-25 14:49:19 +00002054 switch (ri->split_horizon) {
2055 case RIP_SPLIT_HORIZON:
2056 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
2057 break;
2058 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
2059 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
2060 VTY_NEWLINE);
2061 break;
2062 case RIP_NO_SPLIT_HORIZON:
2063 default:
2064 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2065 break;
2066 }
paul718e3742002-12-13 20:15:29 +00002067 }
2068
2069 /* RIP version setting. */
2070 if (ri->ri_send != RI_RIP_UNSPEC)
2071 vty_out (vty, " ip rip send version %s%s",
2072 lookup (ri_version_msg, ri->ri_send),
2073 VTY_NEWLINE);
2074
2075 if (ri->ri_receive != RI_RIP_UNSPEC)
2076 vty_out (vty, " ip rip receive version %s%s",
2077 lookup (ri_version_msg, ri->ri_receive),
2078 VTY_NEWLINE);
2079
2080 /* RIP authentication. */
2081#if 0
2082 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
2083 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2084 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
2085#endif /* 0 */
paulca5e5162004-06-06 22:06:33 +00002086
paul718e3742002-12-13 20:15:29 +00002087 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002088 {
2089 vty_out (vty, " ip rip authentication mode md5");
2090 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2091 vty_out (vty, " auth-length old-ripd");
2092 else
2093 vty_out (vty, " auth-length rfc");
2094 vty_out (vty, "%s", VTY_NEWLINE);
2095 }
paul718e3742002-12-13 20:15:29 +00002096
2097 if (ri->auth_str)
2098 vty_out (vty, " ip rip authentication string %s%s",
2099 ri->auth_str, VTY_NEWLINE);
2100
2101 if (ri->key_chain)
2102 vty_out (vty, " ip rip authentication key-chain %s%s",
2103 ri->key_chain, VTY_NEWLINE);
2104
2105 vty_out (vty, "!%s", VTY_NEWLINE);
2106 }
2107 return 0;
2108}
2109
2110int
2111config_write_rip_network (struct vty *vty, int config_mode)
2112{
hasso8a676be2004-10-08 06:36:38 +00002113 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002114 char *ifname;
2115 struct route_node *node;
2116
2117 /* Network type RIP enable interface statement. */
2118 for (node = route_top (rip_enable_network); node; node = route_next (node))
2119 if (node->info)
2120 vty_out (vty, "%s%s/%d%s",
2121 config_mode ? " network " : " ",
2122 inet_ntoa (node->p.u.prefix4),
2123 node->p.prefixlen,
2124 VTY_NEWLINE);
2125
2126 /* Interface name RIP enable statement. */
2127 for (i = 0; i < vector_max (rip_enable_interface); i++)
2128 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2129 vty_out (vty, "%s%s%s",
2130 config_mode ? " network " : " ",
2131 ifname,
2132 VTY_NEWLINE);
2133
2134 /* RIP neighbors listing. */
2135 for (node = route_top (rip->neighbor); node; node = route_next (node))
2136 if (node->info)
2137 vty_out (vty, "%s%s%s",
2138 config_mode ? " neighbor " : " ",
2139 inet_ntoa (node->p.u.prefix4),
2140 VTY_NEWLINE);
2141
2142 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002143 if (config_mode) {
2144 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002145 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul4aaff3f2003-06-07 01:04:45 +00002146 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
2147 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2148 vty_out (vty, " %spassive-interface %s%s",
2149 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2150 }
paul718e3742002-12-13 20:15:29 +00002151
2152 return 0;
2153}
2154
2155struct cmd_node interface_node =
2156{
2157 INTERFACE_NODE,
2158 "%s(config-if)# ",
2159 1,
2160};
2161
2162/* Called when interface structure allocated. */
2163int
2164rip_interface_new_hook (struct interface *ifp)
2165{
2166 ifp->info = rip_interface_new ();
2167 return 0;
2168}
2169
2170/* Called when interface structure deleted. */
2171int
2172rip_interface_delete_hook (struct interface *ifp)
2173{
2174 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002175 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002176 return 0;
2177}
2178
2179/* Allocate and initialize interface vector. */
2180void
2181rip_if_init ()
2182{
2183 /* Default initial size of interface vector. */
2184 if_init();
2185 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2186 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2187
2188 /* RIP network init. */
2189 rip_enable_interface = vector_init (1);
2190 rip_enable_network = route_table_init ();
2191
2192 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002193 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002194
2195 /* Install interface node. */
2196 install_node (&interface_node, rip_interface_config_write);
2197
2198 /* Install commands. */
2199 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002200 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002201 install_default (INTERFACE_NODE);
2202 install_element (INTERFACE_NODE, &interface_desc_cmd);
2203 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2204 install_element (RIP_NODE, &rip_network_cmd);
2205 install_element (RIP_NODE, &no_rip_network_cmd);
2206 install_element (RIP_NODE, &rip_neighbor_cmd);
2207 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2208
2209 install_element (RIP_NODE, &rip_passive_interface_cmd);
2210 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2211
2212 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2213 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2214 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2215 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2216 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2217
2218 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2219 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2220 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2221 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2222 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2223
2224 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002225 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002226 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2227 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002228 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002229
2230 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2231 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2232 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2233
2234 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2235 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2236 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2237
hasso16705132003-05-25 14:49:19 +00002238 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2239 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2240 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2241 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002242}