blob: 0a01d8b5e3c0dd2722872fa1b93f61d6132fa02e [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",
ajs6099b3b2004-11-20 02:06:59 +000089 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +000090
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,
ajs6099b3b2004-11-20 02:06:59 +0000196 safe_strerror (errno));
hasso3fb9cd62004-10-19 19:44:43 +0000197 }
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)
ajs5d6c3772004-12-08 19:24:06 +0000216 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000217
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)
ajs5d6c3772004-12-08 19:24:06 +0000228 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000229
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)
ajs5d6c3772004-12-08 19:24:06 +0000250 zlog_debug ("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)
ajs5d6c3772004-12-08 19:24:06 +0000311 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000312
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)
ajs5d6c3772004-12-08 19:24:06 +0000328 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000329
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)
ajs5d6c3772004-12-08 19:24:06 +0000361 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000362
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)
ajs5d6c3772004-12-08 19:24:06 +0000516 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000517 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)
ajs5d6c3772004-12-08 19:24:06 +0000536 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000537 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)
ajs5d6c3772004-12-08 19:24:06 +0000560 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000561 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)
ajs5d6c3772004-12-08 19:24:06 +0000727 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000728
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)
ajs5d6c3772004-12-08 19:24:06 +0000798 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000799 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)
ajs5d6c3772004-12-08 19:24:06 +0000852 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000853 inet_ntoa (p->u.prefix4), p->prefixlen);
854
855#ifdef HAVE_SNMP
856 rip_ifaddr_delete (ifc->ifp, ifc);
857#endif /* HAVE_SNMP */
858
hasso16705132003-05-25 14:49:19 +0000859 /* Chech wether this prefix needs to be removed */
860 rip_apply_address_del(ifc);
861
paul718e3742002-12-13 20:15:29 +0000862 }
863
864 connected_free (ifc);
865
866 }
867
868 return 0;
869}
870
871/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000872/* Check wether the interface has at least a connected prefix that
873 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000874int
hasso16705132003-05-25 14:49:19 +0000875rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000876{
877 struct listnode *nn;
878 struct connected *connected;
879 struct prefix_ipv4 address;
880
881 for (nn = listhead (ifp->connected); nn; nextnode (nn))
882 if ((connected = getdata (nn)) != NULL)
883 {
884 struct prefix *p;
885 struct route_node *node;
886
887 p = connected->address;
888
889 if (p->family == AF_INET)
890 {
891 address.family = AF_INET;
892 address.prefix = p->u.prefix4;
893 address.prefixlen = IPV4_MAX_BITLEN;
894
895 node = route_node_match (rip_enable_network,
896 (struct prefix *)&address);
897 if (node)
898 {
899 route_unlock_node (node);
900 return 1;
901 }
902 }
903 }
904 return -1;
905}
906
hasso16705132003-05-25 14:49:19 +0000907/* Check wether connected is within the ripng_enable_network table. */
908int
909rip_enable_network_lookup2 (struct connected *connected)
910{
911 struct prefix_ipv4 address;
912 struct prefix *p;
913
914 p = connected->address;
915
916 if (p->family == AF_INET) {
917 struct route_node *node;
918
919 address.family = p->family;
920 address.prefix = p->u.prefix4;
921 address.prefixlen = IPV4_MAX_BITLEN;
922
923 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
924 node = route_node_match (rip_enable_network,
925 (struct prefix *)&address);
926
927 if (node) {
928 route_unlock_node (node);
929 return 1;
930 }
931 }
932
933 return -1;
934}
paul718e3742002-12-13 20:15:29 +0000935/* Add RIP enable network. */
936int
937rip_enable_network_add (struct prefix *p)
938{
939 struct route_node *node;
940
941 node = route_node_get (rip_enable_network, p);
942
943 if (node->info)
944 {
945 route_unlock_node (node);
946 return -1;
947 }
948 else
hasso8a676be2004-10-08 06:36:38 +0000949 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000950
hasso16705132003-05-25 14:49:19 +0000951 /* XXX: One should find a better solution than a generic one */
952 rip_enable_apply_all();
953
paul718e3742002-12-13 20:15:29 +0000954 return 1;
955}
956
957/* Delete RIP enable network. */
958int
959rip_enable_network_delete (struct prefix *p)
960{
961 struct route_node *node;
962
963 node = route_node_lookup (rip_enable_network, p);
964 if (node)
965 {
966 node->info = NULL;
967
968 /* Unlock info lock. */
969 route_unlock_node (node);
970
971 /* Unlock lookup lock. */
972 route_unlock_node (node);
973
hasso16705132003-05-25 14:49:19 +0000974 /* XXX: One should find a better solution than a generic one */
975 rip_enable_apply_all ();
976
paul718e3742002-12-13 20:15:29 +0000977 return 1;
978 }
979 return -1;
980}
981
982/* Check interface is enabled by ifname statement. */
983int
hasso98b718a2004-10-11 12:57:57 +0000984rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000985{
hasso8a676be2004-10-08 06:36:38 +0000986 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000987 char *str;
988
paul55468c82005-03-14 20:19:01 +0000989 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000990 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
991 if (strcmp (str, ifname) == 0)
992 return i;
993 return -1;
994}
995
996/* Add interface to rip_enable_if. */
997int
hasso98b718a2004-10-11 12:57:57 +0000998rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000999{
1000 int ret;
1001
1002 ret = rip_enable_if_lookup (ifname);
1003 if (ret >= 0)
1004 return -1;
1005
1006 vector_set (rip_enable_interface, strdup (ifname));
1007
hasso16705132003-05-25 14:49:19 +00001008 rip_enable_apply_all(); /* TODOVJ */
1009
paul718e3742002-12-13 20:15:29 +00001010 return 1;
1011}
1012
1013/* Delete interface from rip_enable_if. */
1014int
hasso98b718a2004-10-11 12:57:57 +00001015rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001016{
1017 int index;
1018 char *str;
1019
1020 index = rip_enable_if_lookup (ifname);
1021 if (index < 0)
1022 return -1;
1023
1024 str = vector_slot (rip_enable_interface, index);
1025 free (str);
1026 vector_unset (rip_enable_interface, index);
1027
hasso16705132003-05-25 14:49:19 +00001028 rip_enable_apply_all(); /* TODOVJ */
1029
paul718e3742002-12-13 20:15:29 +00001030 return 1;
1031}
1032
1033/* Join to multicast group and send request to the interface. */
1034int
1035rip_interface_wakeup (struct thread *t)
1036{
1037 struct interface *ifp;
1038 struct rip_interface *ri;
1039
1040 /* Get interface. */
1041 ifp = THREAD_ARG (t);
1042
1043 ri = ifp->info;
1044 ri->t_wakeup = NULL;
1045
1046 /* Join to multicast group. */
1047 if (rip_multicast_join (ifp, rip->sock) < 0)
1048 {
1049 zlog_err ("multicast join failed, interface %s not running", ifp->name);
1050 return 0;
1051 }
1052
1053 /* Set running flag. */
1054 ri->running = 1;
1055
1056 /* Send RIP request to the interface. */
1057 rip_request_interface (ifp);
1058
1059 return 0;
1060}
1061
1062int rip_redistribute_check (int);
1063
1064void
1065rip_connect_set (struct interface *ifp, int set)
1066{
1067 struct listnode *nn;
1068 struct connected *connected;
1069 struct prefix_ipv4 address;
1070
1071 for (nn = listhead (ifp->connected); nn; nextnode (nn))
1072 if ((connected = getdata (nn)) != NULL)
1073 {
1074 struct prefix *p;
1075 p = connected->address;
1076
1077 if (p->family != AF_INET)
1078 continue;
1079
1080 address.family = AF_INET;
1081 address.prefix = p->u.prefix4;
1082 address.prefixlen = p->prefixlen;
1083 apply_mask_ipv4 (&address);
1084
hasso16705132003-05-25 14:49:19 +00001085 if (set) {
1086 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1087 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1088 (rip_enable_network_lookup2(connected) >= 0))
1089 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1090 &address, connected->ifp->ifindex, NULL);
1091 } else
paul718e3742002-12-13 20:15:29 +00001092 {
1093 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1094 &address, connected->ifp->ifindex);
1095 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1096 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1097 &address, connected->ifp->ifindex, NULL);
1098 }
1099 }
1100}
1101
1102/* Update interface status. */
1103void
1104rip_enable_apply (struct interface *ifp)
1105{
1106 int ret;
1107 struct rip_interface *ri = NULL;
1108
1109 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001110 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001111 return;
1112
1113 ri = ifp->info;
1114
1115 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001116 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001117
1118 /* If the interface is matched. */
1119 if (ret > 0)
1120 ri->enable_network = 1;
1121 else
1122 ri->enable_network = 0;
1123
1124 /* Check interface name configuration. */
1125 ret = rip_enable_if_lookup (ifp->name);
1126 if (ret >= 0)
1127 ri->enable_interface = 1;
1128 else
1129 ri->enable_interface = 0;
1130
1131 /* any interface MUST have an IPv4 address */
1132 if ( ! rip_if_ipv4_address_check (ifp) )
1133 {
1134 ri->enable_network = 0;
1135 ri->enable_interface = 0;
1136 }
1137
1138 /* Update running status of the interface. */
1139 if (ri->enable_network || ri->enable_interface)
1140 {
paul718e3742002-12-13 20:15:29 +00001141 {
1142 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001143 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001144
1145 /* Add interface wake up thread. */
1146 if (! ri->t_wakeup)
1147 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1148 ifp, 1);
1149 rip_connect_set (ifp, 1);
1150 }
1151 }
1152 else
1153 {
1154 if (ri->running)
1155 {
hasso16705132003-05-25 14:49:19 +00001156 /* Might as well clean up the route table as well
1157 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1158 **/
paul718e3742002-12-13 20:15:29 +00001159 rip_if_down(ifp);
1160
paul718e3742002-12-13 20:15:29 +00001161 rip_connect_set (ifp, 0);
1162 }
1163 }
1164}
1165
1166/* Apply network configuration to all interface. */
1167void
1168rip_enable_apply_all ()
1169{
1170 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +00001171 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001172
1173 /* Check each interface. */
1174 for (node = listhead (iflist); node; nextnode (node))
1175 {
1176 ifp = getdata (node);
1177 rip_enable_apply (ifp);
1178 }
1179}
1180
1181int
1182rip_neighbor_lookup (struct sockaddr_in *from)
1183{
1184 struct prefix_ipv4 p;
1185 struct route_node *node;
1186
1187 memset (&p, 0, sizeof (struct prefix_ipv4));
1188 p.family = AF_INET;
1189 p.prefix = from->sin_addr;
1190 p.prefixlen = IPV4_MAX_BITLEN;
1191
1192 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1193 if (node)
1194 {
1195 route_unlock_node (node);
1196 return 1;
1197 }
1198 return 0;
1199}
1200
1201/* Add new RIP neighbor to the neighbor tree. */
1202int
1203rip_neighbor_add (struct prefix_ipv4 *p)
1204{
1205 struct route_node *node;
1206
1207 node = route_node_get (rip->neighbor, (struct prefix *) p);
1208
1209 if (node->info)
1210 return -1;
1211
1212 node->info = rip->neighbor;
1213
1214 return 0;
1215}
1216
1217/* Delete RIP neighbor from the neighbor tree. */
1218int
1219rip_neighbor_delete (struct prefix_ipv4 *p)
1220{
1221 struct route_node *node;
1222
1223 /* Lock for look up. */
1224 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1225 if (! node)
1226 return -1;
1227
1228 node->info = NULL;
1229
1230 /* Unlock lookup lock. */
1231 route_unlock_node (node);
1232
1233 /* Unlock real neighbor information lock. */
1234 route_unlock_node (node);
1235
1236 return 0;
1237}
1238
1239/* Clear all network and neighbor configuration. */
1240void
1241rip_clean_network ()
1242{
hasso8a676be2004-10-08 06:36:38 +00001243 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001244 char *str;
1245 struct route_node *rn;
1246
1247 /* rip_enable_network. */
1248 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1249 if (rn->info)
1250 {
1251 rn->info = NULL;
1252 route_unlock_node (rn);
1253 }
1254
1255 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001256 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001257 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1258 {
1259 free (str);
1260 vector_slot (rip_enable_interface, i) = NULL;
1261 }
1262}
1263
1264/* Utility function for looking up passive interface settings. */
1265int
hasso98b718a2004-10-11 12:57:57 +00001266rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001267{
hasso8a676be2004-10-08 06:36:38 +00001268 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001269 char *str;
1270
paul55468c82005-03-14 20:19:01 +00001271 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001272 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001273 if (strcmp (str, ifname) == 0)
1274 return i;
1275 return -1;
1276}
1277
1278void
1279rip_passive_interface_apply (struct interface *ifp)
1280{
paul718e3742002-12-13 20:15:29 +00001281 struct rip_interface *ri;
1282
1283 ri = ifp->info;
1284
paul4aaff3f2003-06-07 01:04:45 +00001285 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1286 passive_default : !passive_default);
1287
1288 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001289 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001290}
1291
1292void
1293rip_passive_interface_apply_all ()
1294{
1295 struct interface *ifp;
hasso52dc7ee2004-09-23 19:18:23 +00001296 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001297
1298 for (node = listhead (iflist); node; nextnode (node))
1299 {
1300 ifp = getdata (node);
1301 rip_passive_interface_apply (ifp);
1302 }
1303}
1304
1305/* Passive interface. */
1306int
hasso98b718a2004-10-11 12:57:57 +00001307rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001308{
paul4aaff3f2003-06-07 01:04:45 +00001309 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001310 return CMD_WARNING;
1311
paul4aaff3f2003-06-07 01:04:45 +00001312 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001313
1314 rip_passive_interface_apply_all ();
1315
1316 return CMD_SUCCESS;
1317}
1318
1319int
hasso98b718a2004-10-11 12:57:57 +00001320rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001321{
1322 int i;
1323 char *str;
1324
paul4aaff3f2003-06-07 01:04:45 +00001325 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001326 if (i < 0)
1327 return CMD_WARNING;
1328
paul4aaff3f2003-06-07 01:04:45 +00001329 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001330 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001331 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001332
1333 rip_passive_interface_apply_all ();
1334
1335 return CMD_SUCCESS;
1336}
1337
1338/* Free all configured RIP passive-interface settings. */
1339void
paul4aaff3f2003-06-07 01:04:45 +00001340rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001341{
hasso8a676be2004-10-08 06:36:38 +00001342 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001343 char *str;
1344
paul55468c82005-03-14 20:19:01 +00001345 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001346 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001347 {
1348 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001349 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001350 }
1351 rip_passive_interface_apply_all ();
1352}
1353
1354/* RIP enable network or interface configuration. */
1355DEFUN (rip_network,
1356 rip_network_cmd,
1357 "network (A.B.C.D/M|WORD)",
1358 "Enable routing on an IP network\n"
1359 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1360 "Interface name\n")
1361{
1362 int ret;
1363 struct prefix_ipv4 p;
1364
1365 ret = str2prefix_ipv4 (argv[0], &p);
1366
1367 if (ret)
1368 ret = rip_enable_network_add ((struct prefix *) &p);
1369 else
1370 ret = rip_enable_if_add (argv[0]);
1371
1372 if (ret < 0)
1373 {
1374 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1375 VTY_NEWLINE);
1376 return CMD_WARNING;
1377 }
1378
paul718e3742002-12-13 20:15:29 +00001379 return CMD_SUCCESS;
1380}
1381
1382/* RIP enable network or interface configuration. */
1383DEFUN (no_rip_network,
1384 no_rip_network_cmd,
1385 "no network (A.B.C.D/M|WORD)",
1386 NO_STR
1387 "Enable routing on an IP network\n"
1388 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1389 "Interface name\n")
1390{
1391 int ret;
1392 struct prefix_ipv4 p;
1393
1394 ret = str2prefix_ipv4 (argv[0], &p);
1395
1396 if (ret)
1397 ret = rip_enable_network_delete ((struct prefix *) &p);
1398 else
1399 ret = rip_enable_if_delete (argv[0]);
1400
1401 if (ret < 0)
1402 {
1403 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1404 VTY_NEWLINE);
1405 return CMD_WARNING;
1406 }
1407
paul718e3742002-12-13 20:15:29 +00001408 return CMD_SUCCESS;
1409}
1410
1411/* RIP neighbor configuration set. */
1412DEFUN (rip_neighbor,
1413 rip_neighbor_cmd,
1414 "neighbor A.B.C.D",
1415 "Specify a neighbor router\n"
1416 "Neighbor address\n")
1417{
1418 int ret;
1419 struct prefix_ipv4 p;
1420
1421 ret = str2prefix_ipv4 (argv[0], &p);
1422
1423 if (ret <= 0)
1424 {
1425 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1426 return CMD_WARNING;
1427 }
1428
1429 rip_neighbor_add (&p);
1430
1431 return CMD_SUCCESS;
1432}
1433
1434/* RIP neighbor configuration unset. */
1435DEFUN (no_rip_neighbor,
1436 no_rip_neighbor_cmd,
1437 "no neighbor A.B.C.D",
1438 NO_STR
1439 "Specify a neighbor router\n"
1440 "Neighbor address\n")
1441{
1442 int ret;
1443 struct prefix_ipv4 p;
1444
1445 ret = str2prefix_ipv4 (argv[0], &p);
1446
1447 if (ret <= 0)
1448 {
1449 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1450 return CMD_WARNING;
1451 }
1452
1453 rip_neighbor_delete (&p);
1454
1455 return CMD_SUCCESS;
1456}
1457
1458DEFUN (ip_rip_receive_version,
1459 ip_rip_receive_version_cmd,
1460 "ip rip receive version (1|2)",
1461 IP_STR
1462 "Routing Information Protocol\n"
1463 "Advertisement reception\n"
1464 "Version control\n"
1465 "RIP version 1\n"
1466 "RIP version 2\n")
1467{
1468 struct interface *ifp;
1469 struct rip_interface *ri;
1470
1471 ifp = (struct interface *)vty->index;
1472 ri = ifp->info;
1473
1474 /* Version 1. */
1475 if (atoi (argv[0]) == 1)
1476 {
1477 ri->ri_receive = RI_RIP_VERSION_1;
1478 return CMD_SUCCESS;
1479 }
1480 if (atoi (argv[0]) == 2)
1481 {
1482 ri->ri_receive = RI_RIP_VERSION_2;
1483 return CMD_SUCCESS;
1484 }
1485 return CMD_WARNING;
1486}
1487
1488DEFUN (ip_rip_receive_version_1,
1489 ip_rip_receive_version_1_cmd,
1490 "ip rip receive version 1 2",
1491 IP_STR
1492 "Routing Information Protocol\n"
1493 "Advertisement reception\n"
1494 "Version control\n"
1495 "RIP version 1\n"
1496 "RIP version 2\n")
1497{
1498 struct interface *ifp;
1499 struct rip_interface *ri;
1500
1501 ifp = (struct interface *)vty->index;
1502 ri = ifp->info;
1503
1504 /* Version 1 and 2. */
1505 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1506 return CMD_SUCCESS;
1507}
1508
1509DEFUN (ip_rip_receive_version_2,
1510 ip_rip_receive_version_2_cmd,
1511 "ip rip receive version 2 1",
1512 IP_STR
1513 "Routing Information Protocol\n"
1514 "Advertisement reception\n"
1515 "Version control\n"
1516 "RIP version 2\n"
1517 "RIP version 1\n")
1518{
1519 struct interface *ifp;
1520 struct rip_interface *ri;
1521
1522 ifp = (struct interface *)vty->index;
1523 ri = ifp->info;
1524
1525 /* Version 1 and 2. */
1526 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1527 return CMD_SUCCESS;
1528}
1529
1530DEFUN (no_ip_rip_receive_version,
1531 no_ip_rip_receive_version_cmd,
1532 "no ip rip receive version",
1533 NO_STR
1534 IP_STR
1535 "Routing Information Protocol\n"
1536 "Advertisement reception\n"
1537 "Version control\n")
1538{
1539 struct interface *ifp;
1540 struct rip_interface *ri;
1541
1542 ifp = (struct interface *)vty->index;
1543 ri = ifp->info;
1544
1545 ri->ri_receive = RI_RIP_UNSPEC;
1546 return CMD_SUCCESS;
1547}
1548
1549ALIAS (no_ip_rip_receive_version,
1550 no_ip_rip_receive_version_num_cmd,
1551 "no ip rip receive version (1|2)",
1552 NO_STR
1553 IP_STR
1554 "Routing Information Protocol\n"
1555 "Advertisement reception\n"
1556 "Version control\n"
1557 "Version 1\n"
1558 "Version 2\n")
1559
1560DEFUN (ip_rip_send_version,
1561 ip_rip_send_version_cmd,
1562 "ip rip send version (1|2)",
1563 IP_STR
1564 "Routing Information Protocol\n"
1565 "Advertisement transmission\n"
1566 "Version control\n"
1567 "RIP version 1\n"
1568 "RIP version 2\n")
1569{
1570 struct interface *ifp;
1571 struct rip_interface *ri;
1572
1573 ifp = (struct interface *)vty->index;
1574 ri = ifp->info;
1575
1576 /* Version 1. */
1577 if (atoi (argv[0]) == 1)
1578 {
1579 ri->ri_send = RI_RIP_VERSION_1;
1580 return CMD_SUCCESS;
1581 }
1582 if (atoi (argv[0]) == 2)
1583 {
1584 ri->ri_send = RI_RIP_VERSION_2;
1585 return CMD_SUCCESS;
1586 }
1587 return CMD_WARNING;
1588}
1589
1590DEFUN (ip_rip_send_version_1,
1591 ip_rip_send_version_1_cmd,
1592 "ip rip send version 1 2",
1593 IP_STR
1594 "Routing Information Protocol\n"
1595 "Advertisement transmission\n"
1596 "Version control\n"
1597 "RIP version 1\n"
1598 "RIP version 2\n")
1599{
1600 struct interface *ifp;
1601 struct rip_interface *ri;
1602
1603 ifp = (struct interface *)vty->index;
1604 ri = ifp->info;
1605
1606 /* Version 1 and 2. */
1607 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1608 return CMD_SUCCESS;
1609}
1610
1611DEFUN (ip_rip_send_version_2,
1612 ip_rip_send_version_2_cmd,
1613 "ip rip send version 2 1",
1614 IP_STR
1615 "Routing Information Protocol\n"
1616 "Advertisement transmission\n"
1617 "Version control\n"
1618 "RIP version 2\n"
1619 "RIP version 1\n")
1620{
1621 struct interface *ifp;
1622 struct rip_interface *ri;
1623
1624 ifp = (struct interface *)vty->index;
1625 ri = ifp->info;
1626
1627 /* Version 1 and 2. */
1628 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1629 return CMD_SUCCESS;
1630}
1631
1632DEFUN (no_ip_rip_send_version,
1633 no_ip_rip_send_version_cmd,
1634 "no ip rip send version",
1635 NO_STR
1636 IP_STR
1637 "Routing Information Protocol\n"
1638 "Advertisement transmission\n"
1639 "Version control\n")
1640{
1641 struct interface *ifp;
1642 struct rip_interface *ri;
1643
1644 ifp = (struct interface *)vty->index;
1645 ri = ifp->info;
1646
1647 ri->ri_send = RI_RIP_UNSPEC;
1648 return CMD_SUCCESS;
1649}
1650
1651ALIAS (no_ip_rip_send_version,
1652 no_ip_rip_send_version_num_cmd,
1653 "no ip rip send version (1|2)",
1654 NO_STR
1655 IP_STR
1656 "Routing Information Protocol\n"
1657 "Advertisement transmission\n"
1658 "Version control\n"
1659 "Version 1\n"
1660 "Version 2\n")
1661
1662DEFUN (ip_rip_authentication_mode,
1663 ip_rip_authentication_mode_cmd,
1664 "ip rip authentication mode (md5|text)",
1665 IP_STR
1666 "Routing Information Protocol\n"
1667 "Authentication control\n"
1668 "Authentication mode\n"
1669 "Keyed message digest\n"
1670 "Clear text authentication\n")
1671{
1672 struct interface *ifp;
1673 struct rip_interface *ri;
1674
1675 ifp = (struct interface *)vty->index;
1676 ri = ifp->info;
1677
paulca5e5162004-06-06 22:06:33 +00001678 if ( (argc < 1) || (argc > 2) )
1679 {
1680 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1681 return CMD_WARNING;
1682 }
1683
paul718e3742002-12-13 20:15:29 +00001684 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1685 ri->auth_type = RIP_AUTH_MD5;
1686 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1687 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1688 else
1689 {
1690 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1691 return CMD_WARNING;
1692 }
1693
paulca5e5162004-06-06 22:06:33 +00001694 if (argc == 1)
1695 return CMD_SUCCESS;
1696
1697 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1698 {
1699 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1700 return CMD_WARNING;
1701}
1702
1703 if (strncmp ("r", argv[1], 1) == 0)
1704 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1705 else if (strncmp ("o", argv[1], 1) == 0)
1706 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1707 else
1708 return CMD_WARNING;
1709
paul718e3742002-12-13 20:15:29 +00001710 return CMD_SUCCESS;
1711}
1712
paulca5e5162004-06-06 22:06:33 +00001713ALIAS (ip_rip_authentication_mode,
1714 ip_rip_authentication_mode_authlen_cmd,
1715 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1716 IP_STR
1717 "Routing Information Protocol\n"
1718 "Authentication control\n"
1719 "Authentication mode\n"
1720 "Keyed message digest\n"
1721 "Clear text authentication\n"
1722 "MD5 authentication data length\n"
1723 "RFC compatible\n"
1724 "Old ripd compatible\n")
1725
paul718e3742002-12-13 20:15:29 +00001726DEFUN (no_ip_rip_authentication_mode,
1727 no_ip_rip_authentication_mode_cmd,
1728 "no ip rip authentication mode",
1729 NO_STR
1730 IP_STR
1731 "Routing Information Protocol\n"
1732 "Authentication control\n"
1733 "Authentication mode\n")
1734{
1735 struct interface *ifp;
1736 struct rip_interface *ri;
1737
1738 ifp = (struct interface *)vty->index;
1739 ri = ifp->info;
1740
1741 /* ri->auth_type = RIP_NO_AUTH; */
1742 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paulca5e5162004-06-06 22:06:33 +00001743 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001744
1745 return CMD_SUCCESS;
1746}
1747
1748ALIAS (no_ip_rip_authentication_mode,
1749 no_ip_rip_authentication_mode_type_cmd,
1750 "no ip rip authentication mode (md5|text)",
1751 NO_STR
1752 IP_STR
1753 "Routing Information Protocol\n"
1754 "Authentication control\n"
1755 "Authentication mode\n"
1756 "Keyed message digest\n"
1757 "Clear text authentication\n")
1758
paulca5e5162004-06-06 22:06:33 +00001759ALIAS (no_ip_rip_authentication_mode,
1760 no_ip_rip_authentication_mode_type_authlen_cmd,
1761 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1762 NO_STR
1763 IP_STR
1764 "Routing Information Protocol\n"
1765 "Authentication control\n"
1766 "Authentication mode\n"
1767 "Keyed message digest\n"
1768 "Clear text authentication\n"
1769 "MD5 authentication data length\n"
1770 "RFC compatible\n"
1771 "Old ripd compatible\n")
1772
paul718e3742002-12-13 20:15:29 +00001773DEFUN (ip_rip_authentication_string,
1774 ip_rip_authentication_string_cmd,
1775 "ip rip authentication string LINE",
1776 IP_STR
1777 "Routing Information Protocol\n"
1778 "Authentication control\n"
1779 "Authentication string\n"
1780 "Authentication string\n")
1781{
1782 struct interface *ifp;
1783 struct rip_interface *ri;
1784
1785 ifp = (struct interface *)vty->index;
1786 ri = ifp->info;
1787
1788 if (strlen (argv[0]) > 16)
1789 {
1790 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1791 VTY_NEWLINE);
1792 return CMD_WARNING;
1793 }
1794
1795 if (ri->key_chain)
1796 {
1797 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1798 return CMD_WARNING;
1799 }
1800
1801 if (ri->auth_str)
1802 free (ri->auth_str);
1803
1804 ri->auth_str = strdup (argv[0]);
1805
1806 return CMD_SUCCESS;
1807}
1808
1809DEFUN (no_ip_rip_authentication_string,
1810 no_ip_rip_authentication_string_cmd,
1811 "no ip rip authentication string",
1812 NO_STR
1813 IP_STR
1814 "Routing Information Protocol\n"
1815 "Authentication control\n"
1816 "Authentication string\n")
1817{
1818 struct interface *ifp;
1819 struct rip_interface *ri;
1820
1821 ifp = (struct interface *)vty->index;
1822 ri = ifp->info;
1823
1824 if (ri->auth_str)
1825 free (ri->auth_str);
1826
1827 ri->auth_str = NULL;
1828
1829 return CMD_SUCCESS;
1830}
1831
1832ALIAS (no_ip_rip_authentication_string,
1833 no_ip_rip_authentication_string2_cmd,
1834 "no ip rip authentication string LINE",
1835 NO_STR
1836 IP_STR
1837 "Routing Information Protocol\n"
1838 "Authentication control\n"
1839 "Authentication string\n"
1840 "Authentication string\n")
1841
1842DEFUN (ip_rip_authentication_key_chain,
1843 ip_rip_authentication_key_chain_cmd,
1844 "ip rip authentication key-chain LINE",
1845 IP_STR
1846 "Routing Information Protocol\n"
1847 "Authentication control\n"
1848 "Authentication key-chain\n"
1849 "name of key-chain\n")
1850{
1851 struct interface *ifp;
1852 struct rip_interface *ri;
1853
1854 ifp = (struct interface *) vty->index;
1855 ri = ifp->info;
1856
1857 if (ri->auth_str)
1858 {
1859 vty_out (vty, "%% authentication string configuration exists%s",
1860 VTY_NEWLINE);
1861 return CMD_WARNING;
1862 }
1863
1864 if (ri->key_chain)
1865 free (ri->key_chain);
1866
1867 ri->key_chain = strdup (argv[0]);
1868
1869 return CMD_SUCCESS;
1870}
1871
1872DEFUN (no_ip_rip_authentication_key_chain,
1873 no_ip_rip_authentication_key_chain_cmd,
1874 "no ip rip authentication key-chain",
1875 NO_STR
1876 IP_STR
1877 "Routing Information Protocol\n"
1878 "Authentication control\n"
1879 "Authentication key-chain\n")
1880{
1881 struct interface *ifp;
1882 struct rip_interface *ri;
1883
1884 ifp = (struct interface *) vty->index;
1885 ri = ifp->info;
1886
1887 if (ri->key_chain)
1888 free (ri->key_chain);
1889
1890 ri->key_chain = NULL;
1891
1892 return CMD_SUCCESS;
1893}
1894
1895ALIAS (no_ip_rip_authentication_key_chain,
1896 no_ip_rip_authentication_key_chain2_cmd,
1897 "no ip rip authentication key-chain LINE",
1898 NO_STR
1899 IP_STR
1900 "Routing Information Protocol\n"
1901 "Authentication control\n"
1902 "Authentication key-chain\n"
1903 "name of key-chain\n")
1904
hasso16705132003-05-25 14:49:19 +00001905/* CHANGED: ip rip split-horizon
1906 Cisco and Zebra's command is
1907 ip split-horizon
1908 */
1909DEFUN (ip_rip_split_horizon,
1910 ip_rip_split_horizon_cmd,
1911 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001912 IP_STR
hasso16705132003-05-25 14:49:19 +00001913 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001914 "Perform split horizon\n")
1915{
1916 struct interface *ifp;
1917 struct rip_interface *ri;
1918
1919 ifp = vty->index;
1920 ri = ifp->info;
1921
hasso16705132003-05-25 14:49:19 +00001922 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001923 return CMD_SUCCESS;
1924}
1925
hasso16705132003-05-25 14:49:19 +00001926DEFUN (ip_rip_split_horizon_poisoned_reverse,
1927 ip_rip_split_horizon_poisoned_reverse_cmd,
1928 "ip rip split-horizon poisoned-reverse",
1929 IP_STR
1930 "Routing Information Protocol\n"
1931 "Perform split horizon\n"
1932 "With poisoned-reverse\n")
1933{
1934 struct interface *ifp;
1935 struct rip_interface *ri;
1936
1937 ifp = vty->index;
1938 ri = ifp->info;
1939
1940 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1941 return CMD_SUCCESS;
1942}
1943
1944/* CHANGED: no ip rip split-horizon
1945 Cisco and Zebra's command is
1946 no ip split-horizon
1947 */
1948DEFUN (no_ip_rip_split_horizon,
1949 no_ip_rip_split_horizon_cmd,
1950 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001951 NO_STR
1952 IP_STR
hasso16705132003-05-25 14:49:19 +00001953 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001954 "Perform split horizon\n")
1955{
1956 struct interface *ifp;
1957 struct rip_interface *ri;
1958
1959 ifp = vty->index;
1960 ri = ifp->info;
1961
hasso16705132003-05-25 14:49:19 +00001962 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001963 return CMD_SUCCESS;
1964}
1965
hasso16705132003-05-25 14:49:19 +00001966ALIAS (no_ip_rip_split_horizon,
1967 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1968 "no ip rip split-horizon poisoned-reverse",
1969 NO_STR
1970 IP_STR
1971 "Routing Information Protocol\n"
1972 "Perform split horizon\n"
1973 "With poisoned-reverse\n")
1974
paul718e3742002-12-13 20:15:29 +00001975DEFUN (rip_passive_interface,
1976 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001977 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001978 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001979 "Interface name\n"
1980 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001981{
hasso98b718a2004-10-11 12:57:57 +00001982 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001983
1984 if (!strcmp(ifname,"default")) {
1985 passive_default = 1;
1986 rip_passive_nondefault_clean();
1987 return CMD_SUCCESS;
1988 }
1989 if (passive_default)
1990 return rip_passive_nondefault_unset (vty, ifname);
1991 else
1992 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001993}
1994
1995DEFUN (no_rip_passive_interface,
1996 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001997 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001998 NO_STR
1999 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00002000 "Interface name\n"
2001 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00002002{
hasso98b718a2004-10-11 12:57:57 +00002003 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00002004
2005 if (!strcmp(ifname,"default")) {
2006 passive_default = 0;
2007 rip_passive_nondefault_clean();
2008 return CMD_SUCCESS;
2009 }
2010 if (passive_default)
2011 return rip_passive_nondefault_set (vty, ifname);
2012 else
2013 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00002014}
2015
2016/* Write rip configuration of each interface. */
2017int
2018rip_interface_config_write (struct vty *vty)
2019{
hasso52dc7ee2004-09-23 19:18:23 +00002020 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002021 struct interface *ifp;
2022
2023 for (node = listhead (iflist); node; nextnode (node))
2024 {
2025 struct rip_interface *ri;
2026
2027 ifp = getdata (node);
2028 ri = ifp->info;
2029
hasso16705132003-05-25 14:49:19 +00002030 /* Do not display the interface if there is no
2031 * configuration about it.
2032 **/
2033 if ((!ifp->desc) &&
2034 (ri->split_horizon == ri->split_horizon_default) &&
2035 (ri->ri_send == RI_RIP_UNSPEC) &&
2036 (ri->ri_receive == RI_RIP_UNSPEC) &&
2037 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00002038 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00002039 (!ri->auth_str) &&
2040 (!ri->key_chain) )
2041 continue;
2042
paul718e3742002-12-13 20:15:29 +00002043 vty_out (vty, "interface %s%s", ifp->name,
2044 VTY_NEWLINE);
2045
2046 if (ifp->desc)
2047 vty_out (vty, " description %s%s", ifp->desc,
2048 VTY_NEWLINE);
2049
2050 /* Split horizon. */
2051 if (ri->split_horizon != ri->split_horizon_default)
2052 {
hasso16705132003-05-25 14:49:19 +00002053 switch (ri->split_horizon) {
2054 case RIP_SPLIT_HORIZON:
2055 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
2056 break;
2057 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
2058 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
2059 VTY_NEWLINE);
2060 break;
2061 case RIP_NO_SPLIT_HORIZON:
2062 default:
2063 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2064 break;
2065 }
paul718e3742002-12-13 20:15:29 +00002066 }
2067
2068 /* RIP version setting. */
2069 if (ri->ri_send != RI_RIP_UNSPEC)
2070 vty_out (vty, " ip rip send version %s%s",
2071 lookup (ri_version_msg, ri->ri_send),
2072 VTY_NEWLINE);
2073
2074 if (ri->ri_receive != RI_RIP_UNSPEC)
2075 vty_out (vty, " ip rip receive version %s%s",
2076 lookup (ri_version_msg, ri->ri_receive),
2077 VTY_NEWLINE);
2078
2079 /* RIP authentication. */
2080#if 0
2081 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
2082 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2083 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
2084#endif /* 0 */
paulca5e5162004-06-06 22:06:33 +00002085
paul718e3742002-12-13 20:15:29 +00002086 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002087 {
2088 vty_out (vty, " ip rip authentication mode md5");
2089 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2090 vty_out (vty, " auth-length old-ripd");
2091 else
2092 vty_out (vty, " auth-length rfc");
2093 vty_out (vty, "%s", VTY_NEWLINE);
2094 }
paul718e3742002-12-13 20:15:29 +00002095
2096 if (ri->auth_str)
2097 vty_out (vty, " ip rip authentication string %s%s",
2098 ri->auth_str, VTY_NEWLINE);
2099
2100 if (ri->key_chain)
2101 vty_out (vty, " ip rip authentication key-chain %s%s",
2102 ri->key_chain, VTY_NEWLINE);
2103
2104 vty_out (vty, "!%s", VTY_NEWLINE);
2105 }
2106 return 0;
2107}
2108
2109int
2110config_write_rip_network (struct vty *vty, int config_mode)
2111{
hasso8a676be2004-10-08 06:36:38 +00002112 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002113 char *ifname;
2114 struct route_node *node;
2115
2116 /* Network type RIP enable interface statement. */
2117 for (node = route_top (rip_enable_network); node; node = route_next (node))
2118 if (node->info)
2119 vty_out (vty, "%s%s/%d%s",
2120 config_mode ? " network " : " ",
2121 inet_ntoa (node->p.u.prefix4),
2122 node->p.prefixlen,
2123 VTY_NEWLINE);
2124
2125 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002126 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002127 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2128 vty_out (vty, "%s%s%s",
2129 config_mode ? " network " : " ",
2130 ifname,
2131 VTY_NEWLINE);
2132
2133 /* RIP neighbors listing. */
2134 for (node = route_top (rip->neighbor); node; node = route_next (node))
2135 if (node->info)
2136 vty_out (vty, "%s%s%s",
2137 config_mode ? " neighbor " : " ",
2138 inet_ntoa (node->p.u.prefix4),
2139 VTY_NEWLINE);
2140
2141 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002142 if (config_mode) {
2143 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002144 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002145 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002146 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2147 vty_out (vty, " %spassive-interface %s%s",
2148 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2149 }
paul718e3742002-12-13 20:15:29 +00002150
2151 return 0;
2152}
2153
2154struct cmd_node interface_node =
2155{
2156 INTERFACE_NODE,
2157 "%s(config-if)# ",
2158 1,
2159};
2160
2161/* Called when interface structure allocated. */
2162int
2163rip_interface_new_hook (struct interface *ifp)
2164{
2165 ifp->info = rip_interface_new ();
2166 return 0;
2167}
2168
2169/* Called when interface structure deleted. */
2170int
2171rip_interface_delete_hook (struct interface *ifp)
2172{
2173 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002174 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002175 return 0;
2176}
2177
2178/* Allocate and initialize interface vector. */
2179void
2180rip_if_init ()
2181{
2182 /* Default initial size of interface vector. */
2183 if_init();
2184 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2185 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2186
2187 /* RIP network init. */
2188 rip_enable_interface = vector_init (1);
2189 rip_enable_network = route_table_init ();
2190
2191 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002192 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002193
2194 /* Install interface node. */
2195 install_node (&interface_node, rip_interface_config_write);
2196
2197 /* Install commands. */
2198 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002199 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002200 install_default (INTERFACE_NODE);
2201 install_element (INTERFACE_NODE, &interface_desc_cmd);
2202 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2203 install_element (RIP_NODE, &rip_network_cmd);
2204 install_element (RIP_NODE, &no_rip_network_cmd);
2205 install_element (RIP_NODE, &rip_neighbor_cmd);
2206 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2207
2208 install_element (RIP_NODE, &rip_passive_interface_cmd);
2209 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2210
2211 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2212 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2213 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2214 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2215 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2216
2217 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2218 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2219 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2220 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2221 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2222
2223 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002224 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002225 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2226 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002227 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002228
2229 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2230 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2231 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2232
2233 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2234 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2235 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2236
hasso16705132003-05-25 14:49:19 +00002237 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2238 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2239 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2240 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002241}