blob: 19f6f114cf3b18a70c5ce2d152f5dc4583c2e488 [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;
paul718e3742002-12-13 20:15:29 +0000148
paul931cd542004-01-23 15:31:42 +0000149 if (connected != NULL)
150 {
hasso3fb9cd62004-10-19 19:44:43 +0000151 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 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)
hasso3fb9cd62004-10-19 19:44:43 +0000164 {
165 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
166 "source address %s for interface %s",
167 sock, inet_ntoa(addr),
168 (connected ? connected->ifp->name : "(unknown)"));
169 return;
170 }
paul718e3742002-12-13 20:15:29 +0000171
hasso3fb9cd62004-10-19 19:44:43 +0000172 /* Bind myself. */
173 memset (&from, 0, sizeof (struct sockaddr_in));
paul718e3742002-12-13 20:15:29 +0000174
hasso3fb9cd62004-10-19 19:44:43 +0000175 /* Set RIP port. */
176 sp = getservbyname ("router", "udp");
177 if (sp)
178 from.sin_port = sp->s_port;
179 else
180 from.sin_port = htons (RIP_PORT_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000181
paul931cd542004-01-23 15:31:42 +0000182 /* Address should be any address. */
hasso3fb9cd62004-10-19 19:44:43 +0000183 from.sin_family = AF_INET;
paul931cd542004-01-23 15:31:42 +0000184 if (connected)
hasso3fb9cd62004-10-19 19:44:43 +0000185 addr = ((struct prefix_ipv4 *) connected->address)->prefix;
186 from.sin_addr = addr;
paul718e3742002-12-13 20:15:29 +0000187#ifdef HAVE_SIN_LEN
hasso3fb9cd62004-10-19 19:44:43 +0000188 from.sin_len = sizeof (struct sockaddr_in);
paul718e3742002-12-13 20:15:29 +0000189#endif /* HAVE_SIN_LEN */
190
hasso3fb9cd62004-10-19 19:44:43 +0000191 if (ripd_privs.change (ZPRIVS_RAISE))
192 zlog_err ("rip_interface_multicast_set: could not raise privs");
pauledd7c242003-06-04 13:59:38 +0000193
paulcc1131a2003-10-15 23:20:17 +0000194 ret = bind (sock, (struct sockaddr *) & from, sizeof (struct sockaddr_in));
hasso3fb9cd62004-10-19 19:44:43 +0000195 if (ret < 0)
196 {
197 zlog_warn ("Can't bind socket fd %d to %s port %d for "
198 "interface %s: %s",
199 sock,inet_ntoa(from.sin_addr),
200 (int)ntohs(from.sin_port),
201 (connected ? connected->ifp->name : "(unknown)"),
202 strerror (errno));
203 }
paul718e3742002-12-13 20:15:29 +0000204
hasso3fb9cd62004-10-19 19:44:43 +0000205 if (ripd_privs.change (ZPRIVS_LOWER))
206 zlog_err ("rip_interface_multicast_set: could not lower privs");
pauledd7c242003-06-04 13:59:38 +0000207
hasso3fb9cd62004-10-19 19:44:43 +0000208 return;
209}
paul718e3742002-12-13 20:15:29 +0000210
211/* Send RIP request packet to specified interface. */
212void
213rip_request_interface_send (struct interface *ifp, u_char version)
214{
215 struct sockaddr_in to;
216
217 /* RIPv2 support multicast. */
218 if (version == RIPv2 && if_is_multicast (ifp))
219 {
220
221 if (IS_RIP_DEBUG_EVENT)
222 zlog_info ("multicast request on %s", ifp->name);
223
paul931cd542004-01-23 15:31:42 +0000224 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000225 return;
226 }
227
228 /* RIPv1 and non multicast interface. */
229 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
230 {
hasso52dc7ee2004-09-23 19:18:23 +0000231 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000232
233 if (IS_RIP_DEBUG_EVENT)
234 zlog_info ("broadcast request to %s", ifp->name);
235
236 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
237 {
paul718e3742002-12-13 20:15:29 +0000238 struct connected *connected;
239
240 connected = getdata (cnode);
paul718e3742002-12-13 20:15:29 +0000241
hasso3fb9cd62004-10-19 19:44:43 +0000242 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000243 {
244 memset (&to, 0, sizeof (struct sockaddr_in));
245 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000246 if (connected->destination)
247 /* use specified broadcast or point-to-point destination addr */
248 to.sin_addr = connected->destination->u.prefix4;
249 else
250 /* calculate the appropriate broadcast address */
251 to.sin_addr.s_addr =
252 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
253 connected->address->prefixlen);
paul718e3742002-12-13 20:15:29 +0000254
paul718e3742002-12-13 20:15:29 +0000255 if (IS_RIP_DEBUG_EVENT)
256 zlog_info ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000257
paul931cd542004-01-23 15:31:42 +0000258 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000259 }
260 }
261 }
262}
263
264/* This will be executed when interface goes up. */
265void
266rip_request_interface (struct interface *ifp)
267{
268 struct rip_interface *ri;
269
270 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
271 if (if_is_loopback (ifp))
272 return;
273
274 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000275 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000276 return;
277
278 /* Fetch RIP interface information. */
279 ri = ifp->info;
280
281
282 /* If there is no version configuration in the interface,
283 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000284 {
285 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
286 rip->version_send : ri->ri_send);
287 if (vsend & RIPv1)
288 rip_request_interface_send (ifp, RIPv1);
289 if (vsend & RIPv2)
290 rip_request_interface_send (ifp, RIPv2);
291 }
paul718e3742002-12-13 20:15:29 +0000292}
293
294/* Send RIP request to the neighbor. */
295void
296rip_request_neighbor (struct in_addr addr)
297{
298 struct sockaddr_in to;
299
300 memset (&to, 0, sizeof (struct sockaddr_in));
301 to.sin_port = htons (RIP_PORT_DEFAULT);
302 to.sin_addr = addr;
303
paul931cd542004-01-23 15:31:42 +0000304 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000305}
306
307/* Request routes at all interfaces. */
308void
309rip_request_neighbor_all ()
310{
311 struct route_node *rp;
312
313 if (! rip)
314 return;
315
316 if (IS_RIP_DEBUG_EVENT)
317 zlog_info ("request to the all neighbor");
318
319 /* Send request to all neighbor. */
320 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
321 if (rp->info)
322 rip_request_neighbor (rp->p.u.prefix4);
323}
324
325/* Multicast packet receive socket. */
326int
327rip_multicast_join (struct interface *ifp, int sock)
328{
hasso52dc7ee2004-09-23 19:18:23 +0000329 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000330
paul2e3b2e42002-12-13 21:03:13 +0000331 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000332 {
333 if (IS_RIP_DEBUG_EVENT)
334 zlog_info ("multicast join at %s", ifp->name);
335
336 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
337 {
338 struct prefix_ipv4 *p;
339 struct connected *connected;
340 struct in_addr group;
341
342 connected = getdata (cnode);
343 p = (struct prefix_ipv4 *) connected->address;
344
345 if (p->family != AF_INET)
346 continue;
347
348 group.s_addr = htonl (INADDR_RIP_GROUP);
349 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
350 return -1;
351 else
352 return 0;
353 }
354 }
355 return 0;
356}
357
358/* Leave from multicast group. */
359void
360rip_multicast_leave (struct interface *ifp, int sock)
361{
hasso52dc7ee2004-09-23 19:18:23 +0000362 struct listnode *cnode;
paul718e3742002-12-13 20:15:29 +0000363
364 if (if_is_up (ifp) && if_is_multicast (ifp))
365 {
366 if (IS_RIP_DEBUG_EVENT)
367 zlog_info ("multicast leave from %s", ifp->name);
368
369 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
370 {
371 struct prefix_ipv4 *p;
372 struct connected *connected;
373 struct in_addr group;
374
375 connected = getdata (cnode);
376 p = (struct prefix_ipv4 *) connected->address;
377
378 if (p->family != AF_INET)
379 continue;
380
381 group.s_addr = htonl (INADDR_RIP_GROUP);
382 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
383 return;
384 }
385 }
386}
387
388/* Is there and address on interface that I could use ? */
389int
390rip_if_ipv4_address_check (struct interface *ifp)
391{
392 struct listnode *nn;
393 struct connected *connected;
394 int count = 0;
395
396 for (nn = listhead (ifp->connected); nn; nextnode (nn))
397 if ((connected = getdata (nn)) != NULL)
398 {
399 struct prefix *p;
400
401 p = connected->address;
402
403 if (p->family == AF_INET)
404 {
405 count++;
406 }
407 }
408
409 return count;
410}
paul31a476c2003-09-29 19:54:53 +0000411
412
413
414
415/* Does this address belongs to me ? */
416int
417if_check_address (struct in_addr addr)
418{
hasso52dc7ee2004-09-23 19:18:23 +0000419 struct listnode *node;
paul31a476c2003-09-29 19:54:53 +0000420
421 for (node = listhead (iflist); node; nextnode (node))
422 {
hasso52dc7ee2004-09-23 19:18:23 +0000423 struct listnode *cnode;
paul31a476c2003-09-29 19:54:53 +0000424 struct interface *ifp;
425
426 ifp = getdata (node);
427
428 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
429 {
430 struct connected *connected;
431 struct prefix_ipv4 *p;
432
433 connected = getdata (cnode);
434 p = (struct prefix_ipv4 *) connected->address;
435
436 if (p->family != AF_INET)
437 continue;
438
439 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
440 return 1;
441 }
442 }
443 return 0;
444}
445
446/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
447int
448if_valid_neighbor (struct in_addr addr)
449{
hasso52dc7ee2004-09-23 19:18:23 +0000450 struct listnode *node;
paul31a476c2003-09-29 19:54:53 +0000451 struct connected *connected = NULL;
452 struct prefix_ipv4 *p;
hasso3fb9cd62004-10-19 19:44:43 +0000453 struct prefix_ipv4 pa;
454
455 pa.family = AF_INET;
456 pa.prefix = addr;
457 pa.prefixlen = IPV4_MAX_PREFIXLEN;
paul31a476c2003-09-29 19:54:53 +0000458
459 for (node = listhead (iflist); node; nextnode (node))
460 {
hasso52dc7ee2004-09-23 19:18:23 +0000461 struct listnode *cnode;
paul31a476c2003-09-29 19:54:53 +0000462 struct interface *ifp;
463
464 ifp = getdata (node);
465
466 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
467 {
paul31a476c2003-09-29 19:54:53 +0000468 connected = getdata (cnode);
469
470 if (if_is_pointopoint (ifp))
471 {
472 p = (struct prefix_ipv4 *) connected->address;
473
474 if (p && p->family == AF_INET)
475 {
476 if (IPV4_ADDR_SAME (&p->prefix, &addr))
477 return 1;
478
479 p = (struct prefix_ipv4 *) connected->destination;
hasso3fb9cd62004-10-19 19:44:43 +0000480 if (p)
481 {
482 if (IPV4_ADDR_SAME (&p->prefix, &addr))
483 return 1;
484 }
485 else
486 {
487 if (prefix_match(connected->address,(struct prefix *)&pa))
488 return 1;
489 }
paul31a476c2003-09-29 19:54:53 +0000490 }
491 }
492 else
493 {
hasso3fb9cd62004-10-19 19:44:43 +0000494 if ((connected->address->family == AF_INET) &&
495 prefix_match(connected->address,(struct prefix *)&pa))
496 return 1;
paul31a476c2003-09-29 19:54:53 +0000497 }
498 }
499 }
500 return 0;
501}
paul718e3742002-12-13 20:15:29 +0000502
503/* Inteface link down message processing. */
504int
505rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
506{
507 struct interface *ifp;
508 struct stream *s;
509
510 s = zclient->ibuf;
511
512 /* zebra_interface_state_read() updates interface structure in
513 iflist. */
514 ifp = zebra_interface_state_read(s);
515
516 if (ifp == NULL)
517 return 0;
518
519 rip_if_down(ifp);
520
521 if (IS_RIP_DEBUG_ZEBRA)
522 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is down",
523 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
524
525 return 0;
526}
527
528/* Inteface link up message processing */
529int
530rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
531{
532 struct interface *ifp;
533
534 /* zebra_interface_state_read () updates interface structure in
535 iflist. */
536 ifp = zebra_interface_state_read (zclient->ibuf);
537
538 if (ifp == NULL)
539 return 0;
540
541 if (IS_RIP_DEBUG_ZEBRA)
542 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is up",
543 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
544
545 /* Check if this interface is RIP enabled or not.*/
546 rip_enable_apply (ifp);
547
548 /* Check for a passive interface */
549 rip_passive_interface_apply (ifp);
550
551 /* Apply distribute list to the all interface. */
552 rip_distribute_update_interface (ifp);
553
554 return 0;
555}
556
557/* Inteface addition message from zebra. */
558int
559rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
560{
561 struct interface *ifp;
562
563 ifp = zebra_interface_add_read (zclient->ibuf);
564
565 if (IS_RIP_DEBUG_ZEBRA)
566 zlog_info ("interface add %s index %d flags %ld metric %d mtu %d",
567 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
568
569 /* Check if this interface is RIP enabled or not.*/
570 rip_enable_apply (ifp);
571
572 /* Apply distribute list to the all interface. */
573 rip_distribute_update_interface (ifp);
574
575 /* rip_request_neighbor_all (); */
576
hasso16705132003-05-25 14:49:19 +0000577 /* Check interface routemap. */
578 rip_if_rmap_update_interface (ifp);
579
paul718e3742002-12-13 20:15:29 +0000580 return 0;
581}
582
583int
584rip_interface_delete (int command, struct zclient *zclient,
585 zebra_size_t length)
586{
587 struct interface *ifp;
588 struct stream *s;
589
590
591 s = zclient->ibuf;
592 /* zebra_interface_state_read() updates interface structure in iflist */
593 ifp = zebra_interface_state_read(s);
594
595 if (ifp == NULL)
596 return 0;
597
598 if (if_is_up (ifp)) {
599 rip_if_down(ifp);
600 }
601
602 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
603 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
604
605 /* To support pseudo interface do not free interface structure. */
606 /* if_delete(ifp); */
607
608 return 0;
609}
610
611void
612rip_interface_clean ()
613{
hasso52dc7ee2004-09-23 19:18:23 +0000614 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000615 struct interface *ifp;
616 struct rip_interface *ri;
617
618 for (node = listhead (iflist); node; nextnode (node))
619 {
620 ifp = getdata (node);
621 ri = ifp->info;
622
623 ri->enable_network = 0;
624 ri->enable_interface = 0;
625 ri->running = 0;
626
627 if (ri->t_wakeup)
628 {
629 thread_cancel (ri->t_wakeup);
630 ri->t_wakeup = NULL;
631 }
632 }
633}
634
635void
636rip_interface_reset ()
637{
hasso52dc7ee2004-09-23 19:18:23 +0000638 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000639 struct interface *ifp;
640 struct rip_interface *ri;
641
642 for (node = listhead (iflist); node; nextnode (node))
643 {
644 ifp = getdata (node);
645 ri = ifp->info;
646
647 ri->enable_network = 0;
648 ri->enable_interface = 0;
649 ri->running = 0;
650
651 ri->ri_send = RI_RIP_UNSPEC;
652 ri->ri_receive = RI_RIP_UNSPEC;
653
654 /* ri->auth_type = RIP_NO_AUTH; */
655 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
656
657 if (ri->auth_str)
658 {
659 free (ri->auth_str);
660 ri->auth_str = NULL;
661 }
662 if (ri->key_chain)
663 {
664 free (ri->key_chain);
665 ri->key_chain = NULL;
666 }
667
hasso16705132003-05-25 14:49:19 +0000668 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
669 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000670
671 ri->list[RIP_FILTER_IN] = NULL;
672 ri->list[RIP_FILTER_OUT] = NULL;
673
674 ri->prefix[RIP_FILTER_IN] = NULL;
675 ri->prefix[RIP_FILTER_OUT] = NULL;
676
677 if (ri->t_wakeup)
678 {
679 thread_cancel (ri->t_wakeup);
680 ri->t_wakeup = NULL;
681 }
682
683 ri->recv_badpackets = 0;
684 ri->recv_badroutes = 0;
685 ri->sent_updates = 0;
686
687 ri->passive = 0;
688 }
689}
690
691int
692rip_if_down(struct interface *ifp)
693{
694 struct route_node *rp;
695 struct rip_info *rinfo;
696 struct rip_interface *ri = NULL;
697 if (rip)
698 {
699 for (rp = route_top (rip->table); rp; rp = route_next (rp))
700 if ((rinfo = rp->info) != NULL)
701 {
702 /* Routes got through this interface. */
703 if (rinfo->ifindex == ifp->ifindex &&
704 rinfo->type == ZEBRA_ROUTE_RIP &&
705 rinfo->sub_type == RIP_ROUTE_RTE)
706 {
707 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
708 &rinfo->nexthop,
709 rinfo->ifindex);
710
711 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
712 (struct prefix_ipv4 *)&rp->p,
713 rinfo->ifindex);
714 }
715 else
716 {
717 /* All redistributed routes but static and system */
718 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000719 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000720 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
721 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
722 (struct prefix_ipv4 *)&rp->p,
723 rinfo->ifindex);
724 }
725 }
726 }
727
728 ri = ifp->info;
729
730 if (ri->running)
731 {
732 if (IS_RIP_DEBUG_EVENT)
733 zlog_info ("turn off %s", ifp->name);
734
735 /* Leave from multicast group. */
736 rip_multicast_leave (ifp, rip->sock);
737
738 ri->running = 0;
739 }
740
741 return 0;
742}
743
744/* Needed for stop RIP process. */
745void
746rip_if_down_all ()
747{
748 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +0000749 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000750
751 for (node = listhead (iflist); node; nextnode (node))
752 {
753 ifp = getdata (node);
754 rip_if_down (ifp);
755 }
756}
757
hasso16705132003-05-25 14:49:19 +0000758static void
759rip_apply_address_add (struct connected *ifc) {
760 struct prefix_ipv4 address;
761 struct prefix *p;
762
763 if (!rip)
764 return;
765
766 if (! if_is_up(ifc->ifp))
767 return;
768
769 p = ifc->address;
770
771 memset (&address, 0, sizeof (address));
772 address.family = p->family;
773 address.prefix = p->u.prefix4;
774 address.prefixlen = p->prefixlen;
775 apply_mask_ipv4(&address);
776
777 /* Check if this interface is RIP enabled or not
778 or Check if this address's prefix is RIP enabled */
779 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
780 (rip_enable_network_lookup2(ifc) >= 0))
781 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
782 &address, ifc->ifp->ifindex, NULL);
783
784}
785
paul718e3742002-12-13 20:15:29 +0000786int
787rip_interface_address_add (int command, struct zclient *zclient,
788 zebra_size_t length)
789{
790 struct connected *ifc;
791 struct prefix *p;
792
paul0a589352004-05-08 11:48:26 +0000793 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
794 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000795
796 if (ifc == NULL)
797 return 0;
798
799 p = ifc->address;
800
801 if (p->family == AF_INET)
802 {
803 if (IS_RIP_DEBUG_ZEBRA)
804 zlog_info ("connected address %s/%d is added",
805 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000806
paul878ef2e2003-09-23 23:41:50 +0000807 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000808 /* Check if this prefix needs to be redistributed */
809 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000810
811#ifdef HAVE_SNMP
812 rip_ifaddr_add (ifc->ifp, ifc);
813#endif /* HAVE_SNMP */
814 }
815
816 return 0;
817}
818
hasso16705132003-05-25 14:49:19 +0000819static void
820rip_apply_address_del (struct connected *ifc) {
821 struct prefix_ipv4 address;
822 struct prefix *p;
823
824 if (!rip)
825 return;
826
827 if (! if_is_up(ifc->ifp))
828 return;
829
830 p = ifc->address;
831
832 memset (&address, 0, sizeof (address));
833 address.family = p->family;
834 address.prefix = p->u.prefix4;
835 address.prefixlen = p->prefixlen;
836 apply_mask_ipv4(&address);
837
838 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
839 &address, ifc->ifp->ifindex);
840}
841
paul718e3742002-12-13 20:15:29 +0000842int
843rip_interface_address_delete (int command, struct zclient *zclient,
844 zebra_size_t length)
845{
846 struct connected *ifc;
847 struct prefix *p;
848
paul0a589352004-05-08 11:48:26 +0000849 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
850 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000851
852 if (ifc)
853 {
854 p = ifc->address;
855 if (p->family == AF_INET)
856 {
857 if (IS_RIP_DEBUG_ZEBRA)
858
859 zlog_info ("connected address %s/%d is deleted",
860 inet_ntoa (p->u.prefix4), p->prefixlen);
861
862#ifdef HAVE_SNMP
863 rip_ifaddr_delete (ifc->ifp, ifc);
864#endif /* HAVE_SNMP */
865
hasso16705132003-05-25 14:49:19 +0000866 /* Chech wether this prefix needs to be removed */
867 rip_apply_address_del(ifc);
868
paul718e3742002-12-13 20:15:29 +0000869 }
870
871 connected_free (ifc);
872
873 }
874
875 return 0;
876}
877
878/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000879/* Check wether the interface has at least a connected prefix that
880 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000881int
hasso16705132003-05-25 14:49:19 +0000882rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000883{
884 struct listnode *nn;
885 struct connected *connected;
886 struct prefix_ipv4 address;
887
888 for (nn = listhead (ifp->connected); nn; nextnode (nn))
889 if ((connected = getdata (nn)) != NULL)
890 {
891 struct prefix *p;
892 struct route_node *node;
893
894 p = connected->address;
895
896 if (p->family == AF_INET)
897 {
898 address.family = AF_INET;
899 address.prefix = p->u.prefix4;
900 address.prefixlen = IPV4_MAX_BITLEN;
901
902 node = route_node_match (rip_enable_network,
903 (struct prefix *)&address);
904 if (node)
905 {
906 route_unlock_node (node);
907 return 1;
908 }
909 }
910 }
911 return -1;
912}
913
hasso16705132003-05-25 14:49:19 +0000914/* Check wether connected is within the ripng_enable_network table. */
915int
916rip_enable_network_lookup2 (struct connected *connected)
917{
918 struct prefix_ipv4 address;
919 struct prefix *p;
920
921 p = connected->address;
922
923 if (p->family == AF_INET) {
924 struct route_node *node;
925
926 address.family = p->family;
927 address.prefix = p->u.prefix4;
928 address.prefixlen = IPV4_MAX_BITLEN;
929
930 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
931 node = route_node_match (rip_enable_network,
932 (struct prefix *)&address);
933
934 if (node) {
935 route_unlock_node (node);
936 return 1;
937 }
938 }
939
940 return -1;
941}
paul718e3742002-12-13 20:15:29 +0000942/* Add RIP enable network. */
943int
944rip_enable_network_add (struct prefix *p)
945{
946 struct route_node *node;
947
948 node = route_node_get (rip_enable_network, p);
949
950 if (node->info)
951 {
952 route_unlock_node (node);
953 return -1;
954 }
955 else
hasso8a676be2004-10-08 06:36:38 +0000956 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000957
hasso16705132003-05-25 14:49:19 +0000958 /* XXX: One should find a better solution than a generic one */
959 rip_enable_apply_all();
960
paul718e3742002-12-13 20:15:29 +0000961 return 1;
962}
963
964/* Delete RIP enable network. */
965int
966rip_enable_network_delete (struct prefix *p)
967{
968 struct route_node *node;
969
970 node = route_node_lookup (rip_enable_network, p);
971 if (node)
972 {
973 node->info = NULL;
974
975 /* Unlock info lock. */
976 route_unlock_node (node);
977
978 /* Unlock lookup lock. */
979 route_unlock_node (node);
980
hasso16705132003-05-25 14:49:19 +0000981 /* XXX: One should find a better solution than a generic one */
982 rip_enable_apply_all ();
983
paul718e3742002-12-13 20:15:29 +0000984 return 1;
985 }
986 return -1;
987}
988
989/* Check interface is enabled by ifname statement. */
990int
hasso98b718a2004-10-11 12:57:57 +0000991rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000992{
hasso8a676be2004-10-08 06:36:38 +0000993 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000994 char *str;
995
996 for (i = 0; i < vector_max (rip_enable_interface); i++)
997 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
998 if (strcmp (str, ifname) == 0)
999 return i;
1000 return -1;
1001}
1002
1003/* Add interface to rip_enable_if. */
1004int
hasso98b718a2004-10-11 12:57:57 +00001005rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001006{
1007 int ret;
1008
1009 ret = rip_enable_if_lookup (ifname);
1010 if (ret >= 0)
1011 return -1;
1012
1013 vector_set (rip_enable_interface, strdup (ifname));
1014
hasso16705132003-05-25 14:49:19 +00001015 rip_enable_apply_all(); /* TODOVJ */
1016
paul718e3742002-12-13 20:15:29 +00001017 return 1;
1018}
1019
1020/* Delete interface from rip_enable_if. */
1021int
hasso98b718a2004-10-11 12:57:57 +00001022rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001023{
1024 int index;
1025 char *str;
1026
1027 index = rip_enable_if_lookup (ifname);
1028 if (index < 0)
1029 return -1;
1030
1031 str = vector_slot (rip_enable_interface, index);
1032 free (str);
1033 vector_unset (rip_enable_interface, index);
1034
hasso16705132003-05-25 14:49:19 +00001035 rip_enable_apply_all(); /* TODOVJ */
1036
paul718e3742002-12-13 20:15:29 +00001037 return 1;
1038}
1039
1040/* Join to multicast group and send request to the interface. */
1041int
1042rip_interface_wakeup (struct thread *t)
1043{
1044 struct interface *ifp;
1045 struct rip_interface *ri;
1046
1047 /* Get interface. */
1048 ifp = THREAD_ARG (t);
1049
1050 ri = ifp->info;
1051 ri->t_wakeup = NULL;
1052
1053 /* Join to multicast group. */
1054 if (rip_multicast_join (ifp, rip->sock) < 0)
1055 {
1056 zlog_err ("multicast join failed, interface %s not running", ifp->name);
1057 return 0;
1058 }
1059
1060 /* Set running flag. */
1061 ri->running = 1;
1062
1063 /* Send RIP request to the interface. */
1064 rip_request_interface (ifp);
1065
1066 return 0;
1067}
1068
1069int rip_redistribute_check (int);
1070
1071void
1072rip_connect_set (struct interface *ifp, int set)
1073{
1074 struct listnode *nn;
1075 struct connected *connected;
1076 struct prefix_ipv4 address;
1077
1078 for (nn = listhead (ifp->connected); nn; nextnode (nn))
1079 if ((connected = getdata (nn)) != NULL)
1080 {
1081 struct prefix *p;
1082 p = connected->address;
1083
1084 if (p->family != AF_INET)
1085 continue;
1086
1087 address.family = AF_INET;
1088 address.prefix = p->u.prefix4;
1089 address.prefixlen = p->prefixlen;
1090 apply_mask_ipv4 (&address);
1091
hasso16705132003-05-25 14:49:19 +00001092 if (set) {
1093 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1094 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1095 (rip_enable_network_lookup2(connected) >= 0))
1096 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1097 &address, connected->ifp->ifindex, NULL);
1098 } else
paul718e3742002-12-13 20:15:29 +00001099 {
1100 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1101 &address, connected->ifp->ifindex);
1102 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1103 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1104 &address, connected->ifp->ifindex, NULL);
1105 }
1106 }
1107}
1108
1109/* Update interface status. */
1110void
1111rip_enable_apply (struct interface *ifp)
1112{
1113 int ret;
1114 struct rip_interface *ri = NULL;
1115
1116 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001117 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001118 return;
1119
1120 ri = ifp->info;
1121
1122 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001123 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001124
1125 /* If the interface is matched. */
1126 if (ret > 0)
1127 ri->enable_network = 1;
1128 else
1129 ri->enable_network = 0;
1130
1131 /* Check interface name configuration. */
1132 ret = rip_enable_if_lookup (ifp->name);
1133 if (ret >= 0)
1134 ri->enable_interface = 1;
1135 else
1136 ri->enable_interface = 0;
1137
1138 /* any interface MUST have an IPv4 address */
1139 if ( ! rip_if_ipv4_address_check (ifp) )
1140 {
1141 ri->enable_network = 0;
1142 ri->enable_interface = 0;
1143 }
1144
1145 /* Update running status of the interface. */
1146 if (ri->enable_network || ri->enable_interface)
1147 {
paul718e3742002-12-13 20:15:29 +00001148 {
1149 if (IS_RIP_DEBUG_EVENT)
1150 zlog_info ("turn on %s", ifp->name);
1151
1152 /* Add interface wake up thread. */
1153 if (! ri->t_wakeup)
1154 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1155 ifp, 1);
1156 rip_connect_set (ifp, 1);
1157 }
1158 }
1159 else
1160 {
1161 if (ri->running)
1162 {
hasso16705132003-05-25 14:49:19 +00001163 /* Might as well clean up the route table as well
1164 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1165 **/
paul718e3742002-12-13 20:15:29 +00001166 rip_if_down(ifp);
1167
paul718e3742002-12-13 20:15:29 +00001168 rip_connect_set (ifp, 0);
1169 }
1170 }
1171}
1172
1173/* Apply network configuration to all interface. */
1174void
1175rip_enable_apply_all ()
1176{
1177 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +00001178 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001179
1180 /* Check each interface. */
1181 for (node = listhead (iflist); node; nextnode (node))
1182 {
1183 ifp = getdata (node);
1184 rip_enable_apply (ifp);
1185 }
1186}
1187
1188int
1189rip_neighbor_lookup (struct sockaddr_in *from)
1190{
1191 struct prefix_ipv4 p;
1192 struct route_node *node;
1193
1194 memset (&p, 0, sizeof (struct prefix_ipv4));
1195 p.family = AF_INET;
1196 p.prefix = from->sin_addr;
1197 p.prefixlen = IPV4_MAX_BITLEN;
1198
1199 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1200 if (node)
1201 {
1202 route_unlock_node (node);
1203 return 1;
1204 }
1205 return 0;
1206}
1207
1208/* Add new RIP neighbor to the neighbor tree. */
1209int
1210rip_neighbor_add (struct prefix_ipv4 *p)
1211{
1212 struct route_node *node;
1213
1214 node = route_node_get (rip->neighbor, (struct prefix *) p);
1215
1216 if (node->info)
1217 return -1;
1218
1219 node->info = rip->neighbor;
1220
1221 return 0;
1222}
1223
1224/* Delete RIP neighbor from the neighbor tree. */
1225int
1226rip_neighbor_delete (struct prefix_ipv4 *p)
1227{
1228 struct route_node *node;
1229
1230 /* Lock for look up. */
1231 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1232 if (! node)
1233 return -1;
1234
1235 node->info = NULL;
1236
1237 /* Unlock lookup lock. */
1238 route_unlock_node (node);
1239
1240 /* Unlock real neighbor information lock. */
1241 route_unlock_node (node);
1242
1243 return 0;
1244}
1245
1246/* Clear all network and neighbor configuration. */
1247void
1248rip_clean_network ()
1249{
hasso8a676be2004-10-08 06:36:38 +00001250 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001251 char *str;
1252 struct route_node *rn;
1253
1254 /* rip_enable_network. */
1255 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1256 if (rn->info)
1257 {
1258 rn->info = NULL;
1259 route_unlock_node (rn);
1260 }
1261
1262 /* rip_enable_interface. */
1263 for (i = 0; i < vector_max (rip_enable_interface); i++)
1264 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1265 {
1266 free (str);
1267 vector_slot (rip_enable_interface, i) = NULL;
1268 }
1269}
1270
1271/* Utility function for looking up passive interface settings. */
1272int
hasso98b718a2004-10-11 12:57:57 +00001273rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001274{
hasso8a676be2004-10-08 06:36:38 +00001275 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001276 char *str;
1277
paul4aaff3f2003-06-07 01:04:45 +00001278 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1279 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001280 if (strcmp (str, ifname) == 0)
1281 return i;
1282 return -1;
1283}
1284
1285void
1286rip_passive_interface_apply (struct interface *ifp)
1287{
paul718e3742002-12-13 20:15:29 +00001288 struct rip_interface *ri;
1289
1290 ri = ifp->info;
1291
paul4aaff3f2003-06-07 01:04:45 +00001292 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1293 passive_default : !passive_default);
1294
1295 if (IS_RIP_DEBUG_ZEBRA)
1296 zlog_info ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001297}
1298
1299void
1300rip_passive_interface_apply_all ()
1301{
1302 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +00001303 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001304
1305 for (node = listhead (iflist); node; nextnode (node))
1306 {
1307 ifp = getdata (node);
1308 rip_passive_interface_apply (ifp);
1309 }
1310}
1311
1312/* Passive interface. */
1313int
hasso98b718a2004-10-11 12:57:57 +00001314rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001315{
paul4aaff3f2003-06-07 01:04:45 +00001316 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001317 return CMD_WARNING;
1318
paul4aaff3f2003-06-07 01:04:45 +00001319 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001320
1321 rip_passive_interface_apply_all ();
1322
1323 return CMD_SUCCESS;
1324}
1325
1326int
hasso98b718a2004-10-11 12:57:57 +00001327rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001328{
1329 int i;
1330 char *str;
1331
paul4aaff3f2003-06-07 01:04:45 +00001332 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001333 if (i < 0)
1334 return CMD_WARNING;
1335
paul4aaff3f2003-06-07 01:04:45 +00001336 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001337 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001338 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001339
1340 rip_passive_interface_apply_all ();
1341
1342 return CMD_SUCCESS;
1343}
1344
1345/* Free all configured RIP passive-interface settings. */
1346void
paul4aaff3f2003-06-07 01:04:45 +00001347rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001348{
hasso8a676be2004-10-08 06:36:38 +00001349 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001350 char *str;
1351
paul4aaff3f2003-06-07 01:04:45 +00001352 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1353 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001354 {
1355 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001356 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001357 }
1358 rip_passive_interface_apply_all ();
1359}
1360
1361/* RIP enable network or interface configuration. */
1362DEFUN (rip_network,
1363 rip_network_cmd,
1364 "network (A.B.C.D/M|WORD)",
1365 "Enable routing on an IP network\n"
1366 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1367 "Interface name\n")
1368{
1369 int ret;
1370 struct prefix_ipv4 p;
1371
1372 ret = str2prefix_ipv4 (argv[0], &p);
1373
1374 if (ret)
1375 ret = rip_enable_network_add ((struct prefix *) &p);
1376 else
1377 ret = rip_enable_if_add (argv[0]);
1378
1379 if (ret < 0)
1380 {
1381 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1382 VTY_NEWLINE);
1383 return CMD_WARNING;
1384 }
1385
paul718e3742002-12-13 20:15:29 +00001386 return CMD_SUCCESS;
1387}
1388
1389/* RIP enable network or interface configuration. */
1390DEFUN (no_rip_network,
1391 no_rip_network_cmd,
1392 "no network (A.B.C.D/M|WORD)",
1393 NO_STR
1394 "Enable routing on an IP network\n"
1395 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1396 "Interface name\n")
1397{
1398 int ret;
1399 struct prefix_ipv4 p;
1400
1401 ret = str2prefix_ipv4 (argv[0], &p);
1402
1403 if (ret)
1404 ret = rip_enable_network_delete ((struct prefix *) &p);
1405 else
1406 ret = rip_enable_if_delete (argv[0]);
1407
1408 if (ret < 0)
1409 {
1410 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1411 VTY_NEWLINE);
1412 return CMD_WARNING;
1413 }
1414
paul718e3742002-12-13 20:15:29 +00001415 return CMD_SUCCESS;
1416}
1417
1418/* RIP neighbor configuration set. */
1419DEFUN (rip_neighbor,
1420 rip_neighbor_cmd,
1421 "neighbor A.B.C.D",
1422 "Specify a neighbor router\n"
1423 "Neighbor address\n")
1424{
1425 int ret;
1426 struct prefix_ipv4 p;
1427
1428 ret = str2prefix_ipv4 (argv[0], &p);
1429
1430 if (ret <= 0)
1431 {
1432 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1433 return CMD_WARNING;
1434 }
1435
1436 rip_neighbor_add (&p);
1437
1438 return CMD_SUCCESS;
1439}
1440
1441/* RIP neighbor configuration unset. */
1442DEFUN (no_rip_neighbor,
1443 no_rip_neighbor_cmd,
1444 "no neighbor A.B.C.D",
1445 NO_STR
1446 "Specify a neighbor router\n"
1447 "Neighbor address\n")
1448{
1449 int ret;
1450 struct prefix_ipv4 p;
1451
1452 ret = str2prefix_ipv4 (argv[0], &p);
1453
1454 if (ret <= 0)
1455 {
1456 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1457 return CMD_WARNING;
1458 }
1459
1460 rip_neighbor_delete (&p);
1461
1462 return CMD_SUCCESS;
1463}
1464
1465DEFUN (ip_rip_receive_version,
1466 ip_rip_receive_version_cmd,
1467 "ip rip receive version (1|2)",
1468 IP_STR
1469 "Routing Information Protocol\n"
1470 "Advertisement reception\n"
1471 "Version control\n"
1472 "RIP version 1\n"
1473 "RIP version 2\n")
1474{
1475 struct interface *ifp;
1476 struct rip_interface *ri;
1477
1478 ifp = (struct interface *)vty->index;
1479 ri = ifp->info;
1480
1481 /* Version 1. */
1482 if (atoi (argv[0]) == 1)
1483 {
1484 ri->ri_receive = RI_RIP_VERSION_1;
1485 return CMD_SUCCESS;
1486 }
1487 if (atoi (argv[0]) == 2)
1488 {
1489 ri->ri_receive = RI_RIP_VERSION_2;
1490 return CMD_SUCCESS;
1491 }
1492 return CMD_WARNING;
1493}
1494
1495DEFUN (ip_rip_receive_version_1,
1496 ip_rip_receive_version_1_cmd,
1497 "ip rip receive version 1 2",
1498 IP_STR
1499 "Routing Information Protocol\n"
1500 "Advertisement reception\n"
1501 "Version control\n"
1502 "RIP version 1\n"
1503 "RIP version 2\n")
1504{
1505 struct interface *ifp;
1506 struct rip_interface *ri;
1507
1508 ifp = (struct interface *)vty->index;
1509 ri = ifp->info;
1510
1511 /* Version 1 and 2. */
1512 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1513 return CMD_SUCCESS;
1514}
1515
1516DEFUN (ip_rip_receive_version_2,
1517 ip_rip_receive_version_2_cmd,
1518 "ip rip receive version 2 1",
1519 IP_STR
1520 "Routing Information Protocol\n"
1521 "Advertisement reception\n"
1522 "Version control\n"
1523 "RIP version 2\n"
1524 "RIP version 1\n")
1525{
1526 struct interface *ifp;
1527 struct rip_interface *ri;
1528
1529 ifp = (struct interface *)vty->index;
1530 ri = ifp->info;
1531
1532 /* Version 1 and 2. */
1533 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1534 return CMD_SUCCESS;
1535}
1536
1537DEFUN (no_ip_rip_receive_version,
1538 no_ip_rip_receive_version_cmd,
1539 "no ip rip receive version",
1540 NO_STR
1541 IP_STR
1542 "Routing Information Protocol\n"
1543 "Advertisement reception\n"
1544 "Version control\n")
1545{
1546 struct interface *ifp;
1547 struct rip_interface *ri;
1548
1549 ifp = (struct interface *)vty->index;
1550 ri = ifp->info;
1551
1552 ri->ri_receive = RI_RIP_UNSPEC;
1553 return CMD_SUCCESS;
1554}
1555
1556ALIAS (no_ip_rip_receive_version,
1557 no_ip_rip_receive_version_num_cmd,
1558 "no ip rip receive version (1|2)",
1559 NO_STR
1560 IP_STR
1561 "Routing Information Protocol\n"
1562 "Advertisement reception\n"
1563 "Version control\n"
1564 "Version 1\n"
1565 "Version 2\n")
1566
1567DEFUN (ip_rip_send_version,
1568 ip_rip_send_version_cmd,
1569 "ip rip send version (1|2)",
1570 IP_STR
1571 "Routing Information Protocol\n"
1572 "Advertisement transmission\n"
1573 "Version control\n"
1574 "RIP version 1\n"
1575 "RIP version 2\n")
1576{
1577 struct interface *ifp;
1578 struct rip_interface *ri;
1579
1580 ifp = (struct interface *)vty->index;
1581 ri = ifp->info;
1582
1583 /* Version 1. */
1584 if (atoi (argv[0]) == 1)
1585 {
1586 ri->ri_send = RI_RIP_VERSION_1;
1587 return CMD_SUCCESS;
1588 }
1589 if (atoi (argv[0]) == 2)
1590 {
1591 ri->ri_send = RI_RIP_VERSION_2;
1592 return CMD_SUCCESS;
1593 }
1594 return CMD_WARNING;
1595}
1596
1597DEFUN (ip_rip_send_version_1,
1598 ip_rip_send_version_1_cmd,
1599 "ip rip send version 1 2",
1600 IP_STR
1601 "Routing Information Protocol\n"
1602 "Advertisement transmission\n"
1603 "Version control\n"
1604 "RIP version 1\n"
1605 "RIP version 2\n")
1606{
1607 struct interface *ifp;
1608 struct rip_interface *ri;
1609
1610 ifp = (struct interface *)vty->index;
1611 ri = ifp->info;
1612
1613 /* Version 1 and 2. */
1614 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1615 return CMD_SUCCESS;
1616}
1617
1618DEFUN (ip_rip_send_version_2,
1619 ip_rip_send_version_2_cmd,
1620 "ip rip send version 2 1",
1621 IP_STR
1622 "Routing Information Protocol\n"
1623 "Advertisement transmission\n"
1624 "Version control\n"
1625 "RIP version 2\n"
1626 "RIP version 1\n")
1627{
1628 struct interface *ifp;
1629 struct rip_interface *ri;
1630
1631 ifp = (struct interface *)vty->index;
1632 ri = ifp->info;
1633
1634 /* Version 1 and 2. */
1635 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1636 return CMD_SUCCESS;
1637}
1638
1639DEFUN (no_ip_rip_send_version,
1640 no_ip_rip_send_version_cmd,
1641 "no ip rip send version",
1642 NO_STR
1643 IP_STR
1644 "Routing Information Protocol\n"
1645 "Advertisement transmission\n"
1646 "Version control\n")
1647{
1648 struct interface *ifp;
1649 struct rip_interface *ri;
1650
1651 ifp = (struct interface *)vty->index;
1652 ri = ifp->info;
1653
1654 ri->ri_send = RI_RIP_UNSPEC;
1655 return CMD_SUCCESS;
1656}
1657
1658ALIAS (no_ip_rip_send_version,
1659 no_ip_rip_send_version_num_cmd,
1660 "no ip rip send version (1|2)",
1661 NO_STR
1662 IP_STR
1663 "Routing Information Protocol\n"
1664 "Advertisement transmission\n"
1665 "Version control\n"
1666 "Version 1\n"
1667 "Version 2\n")
1668
1669DEFUN (ip_rip_authentication_mode,
1670 ip_rip_authentication_mode_cmd,
1671 "ip rip authentication mode (md5|text)",
1672 IP_STR
1673 "Routing Information Protocol\n"
1674 "Authentication control\n"
1675 "Authentication mode\n"
1676 "Keyed message digest\n"
1677 "Clear text authentication\n")
1678{
1679 struct interface *ifp;
1680 struct rip_interface *ri;
1681
1682 ifp = (struct interface *)vty->index;
1683 ri = ifp->info;
1684
paulca5e5162004-06-06 22:06:33 +00001685 if ( (argc < 1) || (argc > 2) )
1686 {
1687 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1688 return CMD_WARNING;
1689 }
1690
paul718e3742002-12-13 20:15:29 +00001691 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1692 ri->auth_type = RIP_AUTH_MD5;
1693 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1694 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1695 else
1696 {
1697 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1698 return CMD_WARNING;
1699 }
1700
paulca5e5162004-06-06 22:06:33 +00001701 if (argc == 1)
1702 return CMD_SUCCESS;
1703
1704 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1705 {
1706 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1707 return CMD_WARNING;
1708}
1709
1710 if (strncmp ("r", argv[1], 1) == 0)
1711 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1712 else if (strncmp ("o", argv[1], 1) == 0)
1713 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1714 else
1715 return CMD_WARNING;
1716
paul718e3742002-12-13 20:15:29 +00001717 return CMD_SUCCESS;
1718}
1719
paulca5e5162004-06-06 22:06:33 +00001720ALIAS (ip_rip_authentication_mode,
1721 ip_rip_authentication_mode_authlen_cmd,
1722 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1723 IP_STR
1724 "Routing Information Protocol\n"
1725 "Authentication control\n"
1726 "Authentication mode\n"
1727 "Keyed message digest\n"
1728 "Clear text authentication\n"
1729 "MD5 authentication data length\n"
1730 "RFC compatible\n"
1731 "Old ripd compatible\n")
1732
paul718e3742002-12-13 20:15:29 +00001733DEFUN (no_ip_rip_authentication_mode,
1734 no_ip_rip_authentication_mode_cmd,
1735 "no ip rip authentication mode",
1736 NO_STR
1737 IP_STR
1738 "Routing Information Protocol\n"
1739 "Authentication control\n"
1740 "Authentication mode\n")
1741{
1742 struct interface *ifp;
1743 struct rip_interface *ri;
1744
1745 ifp = (struct interface *)vty->index;
1746 ri = ifp->info;
1747
1748 /* ri->auth_type = RIP_NO_AUTH; */
1749 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paulca5e5162004-06-06 22:06:33 +00001750 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001751
1752 return CMD_SUCCESS;
1753}
1754
1755ALIAS (no_ip_rip_authentication_mode,
1756 no_ip_rip_authentication_mode_type_cmd,
1757 "no ip rip authentication mode (md5|text)",
1758 NO_STR
1759 IP_STR
1760 "Routing Information Protocol\n"
1761 "Authentication control\n"
1762 "Authentication mode\n"
1763 "Keyed message digest\n"
1764 "Clear text authentication\n")
1765
paulca5e5162004-06-06 22:06:33 +00001766ALIAS (no_ip_rip_authentication_mode,
1767 no_ip_rip_authentication_mode_type_authlen_cmd,
1768 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1769 NO_STR
1770 IP_STR
1771 "Routing Information Protocol\n"
1772 "Authentication control\n"
1773 "Authentication mode\n"
1774 "Keyed message digest\n"
1775 "Clear text authentication\n"
1776 "MD5 authentication data length\n"
1777 "RFC compatible\n"
1778 "Old ripd compatible\n")
1779
paul718e3742002-12-13 20:15:29 +00001780DEFUN (ip_rip_authentication_string,
1781 ip_rip_authentication_string_cmd,
1782 "ip rip authentication string LINE",
1783 IP_STR
1784 "Routing Information Protocol\n"
1785 "Authentication control\n"
1786 "Authentication string\n"
1787 "Authentication string\n")
1788{
1789 struct interface *ifp;
1790 struct rip_interface *ri;
1791
1792 ifp = (struct interface *)vty->index;
1793 ri = ifp->info;
1794
1795 if (strlen (argv[0]) > 16)
1796 {
1797 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1798 VTY_NEWLINE);
1799 return CMD_WARNING;
1800 }
1801
1802 if (ri->key_chain)
1803 {
1804 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1805 return CMD_WARNING;
1806 }
1807
1808 if (ri->auth_str)
1809 free (ri->auth_str);
1810
1811 ri->auth_str = strdup (argv[0]);
1812
1813 return CMD_SUCCESS;
1814}
1815
1816DEFUN (no_ip_rip_authentication_string,
1817 no_ip_rip_authentication_string_cmd,
1818 "no ip rip authentication string",
1819 NO_STR
1820 IP_STR
1821 "Routing Information Protocol\n"
1822 "Authentication control\n"
1823 "Authentication string\n")
1824{
1825 struct interface *ifp;
1826 struct rip_interface *ri;
1827
1828 ifp = (struct interface *)vty->index;
1829 ri = ifp->info;
1830
1831 if (ri->auth_str)
1832 free (ri->auth_str);
1833
1834 ri->auth_str = NULL;
1835
1836 return CMD_SUCCESS;
1837}
1838
1839ALIAS (no_ip_rip_authentication_string,
1840 no_ip_rip_authentication_string2_cmd,
1841 "no ip rip authentication string LINE",
1842 NO_STR
1843 IP_STR
1844 "Routing Information Protocol\n"
1845 "Authentication control\n"
1846 "Authentication string\n"
1847 "Authentication string\n")
1848
1849DEFUN (ip_rip_authentication_key_chain,
1850 ip_rip_authentication_key_chain_cmd,
1851 "ip rip authentication key-chain LINE",
1852 IP_STR
1853 "Routing Information Protocol\n"
1854 "Authentication control\n"
1855 "Authentication key-chain\n"
1856 "name of key-chain\n")
1857{
1858 struct interface *ifp;
1859 struct rip_interface *ri;
1860
1861 ifp = (struct interface *) vty->index;
1862 ri = ifp->info;
1863
1864 if (ri->auth_str)
1865 {
1866 vty_out (vty, "%% authentication string configuration exists%s",
1867 VTY_NEWLINE);
1868 return CMD_WARNING;
1869 }
1870
1871 if (ri->key_chain)
1872 free (ri->key_chain);
1873
1874 ri->key_chain = strdup (argv[0]);
1875
1876 return CMD_SUCCESS;
1877}
1878
1879DEFUN (no_ip_rip_authentication_key_chain,
1880 no_ip_rip_authentication_key_chain_cmd,
1881 "no ip rip authentication key-chain",
1882 NO_STR
1883 IP_STR
1884 "Routing Information Protocol\n"
1885 "Authentication control\n"
1886 "Authentication key-chain\n")
1887{
1888 struct interface *ifp;
1889 struct rip_interface *ri;
1890
1891 ifp = (struct interface *) vty->index;
1892 ri = ifp->info;
1893
1894 if (ri->key_chain)
1895 free (ri->key_chain);
1896
1897 ri->key_chain = NULL;
1898
1899 return CMD_SUCCESS;
1900}
1901
1902ALIAS (no_ip_rip_authentication_key_chain,
1903 no_ip_rip_authentication_key_chain2_cmd,
1904 "no ip rip authentication key-chain LINE",
1905 NO_STR
1906 IP_STR
1907 "Routing Information Protocol\n"
1908 "Authentication control\n"
1909 "Authentication key-chain\n"
1910 "name of key-chain\n")
1911
hasso16705132003-05-25 14:49:19 +00001912/* CHANGED: ip rip split-horizon
1913 Cisco and Zebra's command is
1914 ip split-horizon
1915 */
1916DEFUN (ip_rip_split_horizon,
1917 ip_rip_split_horizon_cmd,
1918 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001919 IP_STR
hasso16705132003-05-25 14:49:19 +00001920 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001921 "Perform split horizon\n")
1922{
1923 struct interface *ifp;
1924 struct rip_interface *ri;
1925
1926 ifp = vty->index;
1927 ri = ifp->info;
1928
hasso16705132003-05-25 14:49:19 +00001929 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001930 return CMD_SUCCESS;
1931}
1932
hasso16705132003-05-25 14:49:19 +00001933DEFUN (ip_rip_split_horizon_poisoned_reverse,
1934 ip_rip_split_horizon_poisoned_reverse_cmd,
1935 "ip rip split-horizon poisoned-reverse",
1936 IP_STR
1937 "Routing Information Protocol\n"
1938 "Perform split horizon\n"
1939 "With poisoned-reverse\n")
1940{
1941 struct interface *ifp;
1942 struct rip_interface *ri;
1943
1944 ifp = vty->index;
1945 ri = ifp->info;
1946
1947 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1948 return CMD_SUCCESS;
1949}
1950
1951/* CHANGED: no ip rip split-horizon
1952 Cisco and Zebra's command is
1953 no ip split-horizon
1954 */
1955DEFUN (no_ip_rip_split_horizon,
1956 no_ip_rip_split_horizon_cmd,
1957 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001958 NO_STR
1959 IP_STR
hasso16705132003-05-25 14:49:19 +00001960 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001961 "Perform split horizon\n")
1962{
1963 struct interface *ifp;
1964 struct rip_interface *ri;
1965
1966 ifp = vty->index;
1967 ri = ifp->info;
1968
hasso16705132003-05-25 14:49:19 +00001969 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001970 return CMD_SUCCESS;
1971}
1972
hasso16705132003-05-25 14:49:19 +00001973ALIAS (no_ip_rip_split_horizon,
1974 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1975 "no ip rip split-horizon poisoned-reverse",
1976 NO_STR
1977 IP_STR
1978 "Routing Information Protocol\n"
1979 "Perform split horizon\n"
1980 "With poisoned-reverse\n")
1981
paul718e3742002-12-13 20:15:29 +00001982DEFUN (rip_passive_interface,
1983 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001984 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001985 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001986 "Interface name\n"
1987 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001988{
hasso98b718a2004-10-11 12:57:57 +00001989 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001990
1991 if (!strcmp(ifname,"default")) {
1992 passive_default = 1;
1993 rip_passive_nondefault_clean();
1994 return CMD_SUCCESS;
1995 }
1996 if (passive_default)
1997 return rip_passive_nondefault_unset (vty, ifname);
1998 else
1999 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00002000}
2001
2002DEFUN (no_rip_passive_interface,
2003 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00002004 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00002005 NO_STR
2006 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00002007 "Interface name\n"
2008 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00002009{
hasso98b718a2004-10-11 12:57:57 +00002010 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00002011
2012 if (!strcmp(ifname,"default")) {
2013 passive_default = 0;
2014 rip_passive_nondefault_clean();
2015 return CMD_SUCCESS;
2016 }
2017 if (passive_default)
2018 return rip_passive_nondefault_set (vty, ifname);
2019 else
2020 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00002021}
2022
2023/* Write rip configuration of each interface. */
2024int
2025rip_interface_config_write (struct vty *vty)
2026{
hasso52dc7ee2004-09-23 19:18:23 +00002027 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002028 struct interface *ifp;
2029
2030 for (node = listhead (iflist); node; nextnode (node))
2031 {
2032 struct rip_interface *ri;
2033
2034 ifp = getdata (node);
2035 ri = ifp->info;
2036
hasso16705132003-05-25 14:49:19 +00002037 /* Do not display the interface if there is no
2038 * configuration about it.
2039 **/
2040 if ((!ifp->desc) &&
2041 (ri->split_horizon == ri->split_horizon_default) &&
2042 (ri->ri_send == RI_RIP_UNSPEC) &&
2043 (ri->ri_receive == RI_RIP_UNSPEC) &&
2044 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00002045 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00002046 (!ri->auth_str) &&
2047 (!ri->key_chain) )
2048 continue;
2049
paul718e3742002-12-13 20:15:29 +00002050 vty_out (vty, "interface %s%s", ifp->name,
2051 VTY_NEWLINE);
2052
2053 if (ifp->desc)
2054 vty_out (vty, " description %s%s", ifp->desc,
2055 VTY_NEWLINE);
2056
2057 /* Split horizon. */
2058 if (ri->split_horizon != ri->split_horizon_default)
2059 {
hasso16705132003-05-25 14:49:19 +00002060 switch (ri->split_horizon) {
2061 case RIP_SPLIT_HORIZON:
2062 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
2063 break;
2064 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
2065 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
2066 VTY_NEWLINE);
2067 break;
2068 case RIP_NO_SPLIT_HORIZON:
2069 default:
2070 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2071 break;
2072 }
paul718e3742002-12-13 20:15:29 +00002073 }
2074
2075 /* RIP version setting. */
2076 if (ri->ri_send != RI_RIP_UNSPEC)
2077 vty_out (vty, " ip rip send version %s%s",
2078 lookup (ri_version_msg, ri->ri_send),
2079 VTY_NEWLINE);
2080
2081 if (ri->ri_receive != RI_RIP_UNSPEC)
2082 vty_out (vty, " ip rip receive version %s%s",
2083 lookup (ri_version_msg, ri->ri_receive),
2084 VTY_NEWLINE);
2085
2086 /* RIP authentication. */
2087#if 0
2088 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
2089 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2090 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
2091#endif /* 0 */
paulca5e5162004-06-06 22:06:33 +00002092
paul718e3742002-12-13 20:15:29 +00002093 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002094 {
2095 vty_out (vty, " ip rip authentication mode md5");
2096 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2097 vty_out (vty, " auth-length old-ripd");
2098 else
2099 vty_out (vty, " auth-length rfc");
2100 vty_out (vty, "%s", VTY_NEWLINE);
2101 }
paul718e3742002-12-13 20:15:29 +00002102
2103 if (ri->auth_str)
2104 vty_out (vty, " ip rip authentication string %s%s",
2105 ri->auth_str, VTY_NEWLINE);
2106
2107 if (ri->key_chain)
2108 vty_out (vty, " ip rip authentication key-chain %s%s",
2109 ri->key_chain, VTY_NEWLINE);
2110
2111 vty_out (vty, "!%s", VTY_NEWLINE);
2112 }
2113 return 0;
2114}
2115
2116int
2117config_write_rip_network (struct vty *vty, int config_mode)
2118{
hasso8a676be2004-10-08 06:36:38 +00002119 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002120 char *ifname;
2121 struct route_node *node;
2122
2123 /* Network type RIP enable interface statement. */
2124 for (node = route_top (rip_enable_network); node; node = route_next (node))
2125 if (node->info)
2126 vty_out (vty, "%s%s/%d%s",
2127 config_mode ? " network " : " ",
2128 inet_ntoa (node->p.u.prefix4),
2129 node->p.prefixlen,
2130 VTY_NEWLINE);
2131
2132 /* Interface name RIP enable statement. */
2133 for (i = 0; i < vector_max (rip_enable_interface); i++)
2134 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2135 vty_out (vty, "%s%s%s",
2136 config_mode ? " network " : " ",
2137 ifname,
2138 VTY_NEWLINE);
2139
2140 /* RIP neighbors listing. */
2141 for (node = route_top (rip->neighbor); node; node = route_next (node))
2142 if (node->info)
2143 vty_out (vty, "%s%s%s",
2144 config_mode ? " neighbor " : " ",
2145 inet_ntoa (node->p.u.prefix4),
2146 VTY_NEWLINE);
2147
2148 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002149 if (config_mode) {
2150 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002151 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul4aaff3f2003-06-07 01:04:45 +00002152 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
2153 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2154 vty_out (vty, " %spassive-interface %s%s",
2155 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2156 }
paul718e3742002-12-13 20:15:29 +00002157
2158 return 0;
2159}
2160
2161struct cmd_node interface_node =
2162{
2163 INTERFACE_NODE,
2164 "%s(config-if)# ",
2165 1,
2166};
2167
2168/* Called when interface structure allocated. */
2169int
2170rip_interface_new_hook (struct interface *ifp)
2171{
2172 ifp->info = rip_interface_new ();
2173 return 0;
2174}
2175
2176/* Called when interface structure deleted. */
2177int
2178rip_interface_delete_hook (struct interface *ifp)
2179{
2180 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002181 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002182 return 0;
2183}
2184
2185/* Allocate and initialize interface vector. */
2186void
2187rip_if_init ()
2188{
2189 /* Default initial size of interface vector. */
2190 if_init();
2191 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2192 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2193
2194 /* RIP network init. */
2195 rip_enable_interface = vector_init (1);
2196 rip_enable_network = route_table_init ();
2197
2198 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002199 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002200
2201 /* Install interface node. */
2202 install_node (&interface_node, rip_interface_config_write);
2203
2204 /* Install commands. */
2205 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002206 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002207 install_default (INTERFACE_NODE);
2208 install_element (INTERFACE_NODE, &interface_desc_cmd);
2209 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2210 install_element (RIP_NODE, &rip_network_cmd);
2211 install_element (RIP_NODE, &no_rip_network_cmd);
2212 install_element (RIP_NODE, &rip_neighbor_cmd);
2213 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2214
2215 install_element (RIP_NODE, &rip_passive_interface_cmd);
2216 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2217
2218 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2219 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2220 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2221 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2222 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2223
2224 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2225 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2226 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2227 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2228 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2229
2230 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002231 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002232 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2233 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002234 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002235
2236 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2237 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2238 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2239
2240 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2241 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2242 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2243
hasso16705132003-05-25 14:49:19 +00002244 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2245 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2246 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2247 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002248}