blob: 0bc5a311076b990a88fcc00bd973b61f097f7569 [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"
pauldc63bfd2005-10-25 23:31:05 +000043#include "ripd/rip_interface.h"
44
45/* static prototypes */
46static void rip_enable_apply (struct interface *);
47static void rip_passive_interface_apply (struct interface *);
48static int rip_if_down(struct interface *ifp);
49static int rip_enable_if_lookup (const char *ifname);
50static int rip_enable_network_lookup2 (struct connected *connected);
51static void rip_enable_apply_all (void);
52
paul718e3742002-12-13 20:15:29 +000053struct message ri_version_msg[] =
54{
55 {RI_RIP_VERSION_1, "1"},
56 {RI_RIP_VERSION_2, "2"},
57 {RI_RIP_VERSION_1_AND_2, "1 2"},
58 {0, NULL}
59};
60
pauledd7c242003-06-04 13:59:38 +000061extern struct zebra_privs_t ripd_privs;
62
paul718e3742002-12-13 20:15:29 +000063/* RIP enabled network vector. */
64vector rip_enable_interface;
65
66/* RIP enabled interface table. */
67struct route_table *rip_enable_network;
68
69/* Vector to store passive-interface name. */
paul4aaff3f2003-06-07 01:04:45 +000070static int passive_default; /* are we in passive-interface default mode? */
71vector Vrip_passive_nondefault;
paul718e3742002-12-13 20:15:29 +000072
73/* Join to the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000074static int
paul718e3742002-12-13 20:15:29 +000075ipv4_multicast_join (int sock,
76 struct in_addr group,
77 struct in_addr ifa,
78 unsigned int ifindex)
79{
80 int ret;
81
82 ret = setsockopt_multicast_ipv4 (sock,
83 IP_ADD_MEMBERSHIP,
84 ifa,
85 group.s_addr,
86 ifindex);
87
88 if (ret < 0)
89 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
ajs6099b3b2004-11-20 02:06:59 +000090 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +000091
92 return ret;
93}
94
95/* Leave from the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000096static int
paul718e3742002-12-13 20:15:29 +000097ipv4_multicast_leave (int sock,
98 struct in_addr group,
99 struct in_addr ifa,
100 unsigned int ifindex)
101{
102 int ret;
103
104 ret = setsockopt_multicast_ipv4 (sock,
105 IP_DROP_MEMBERSHIP,
106 ifa,
107 group.s_addr,
108 ifindex);
109
110 if (ret < 0)
111 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
112
113 return ret;
114}
115
116/* Allocate new RIP's interface configuration. */
pauldc63bfd2005-10-25 23:31:05 +0000117static struct rip_interface *
118rip_interface_new (void)
paul718e3742002-12-13 20:15:29 +0000119{
120 struct rip_interface *ri;
121
122 ri = XMALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
123 memset (ri, 0, sizeof (struct rip_interface));
124
125 /* Default authentication type is simple password for Cisco
126 compatibility. */
paul7755a8c2005-06-02 08:20:53 +0000127 ri->auth_type = RIP_NO_AUTH;
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{
hasso3fb9cd62004-10-19 19:44:43 +0000143 struct in_addr addr;
paulcc1131a2003-10-15 23:20:17 +0000144 struct prefix_ipv4 *p;
paulc49ad8f2004-10-22 10:27:28 +0000145
146 assert (connected != NULL);
147
148 if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected))
149 p = (struct prefix_ipv4 *) connected->destination;
150 else
151 p = (struct prefix_ipv4 *) connected->address;
152
153 addr = p->prefix;
paul718e3742002-12-13 20:15:29 +0000154
paul1a517862004-08-19 04:03:08 +0000155 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
156 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000157 {
158 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
159 "source address %s for interface %s",
160 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000161 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000162 }
paul2c61ae32005-08-16 15:22:14 +0000163
hasso3fb9cd62004-10-19 19:44:43 +0000164 return;
165}
paul718e3742002-12-13 20:15:29 +0000166
167/* Send RIP request packet to specified interface. */
pauldc63bfd2005-10-25 23:31:05 +0000168static void
paul718e3742002-12-13 20:15:29 +0000169rip_request_interface_send (struct interface *ifp, u_char version)
170{
171 struct sockaddr_in to;
172
173 /* RIPv2 support multicast. */
174 if (version == RIPv2 && if_is_multicast (ifp))
175 {
176
177 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000178 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000179
paul931cd542004-01-23 15:31:42 +0000180 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000181 return;
182 }
183
184 /* RIPv1 and non multicast interface. */
185 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
186 {
paul1eb8ef22005-04-07 07:30:20 +0000187 struct listnode *cnode, *cnnode;
188 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000189
190 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000191 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000192
paul1eb8ef22005-04-07 07:30:20 +0000193 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000194 {
hasso3fb9cd62004-10-19 19:44:43 +0000195 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000196 {
197 memset (&to, 0, sizeof (struct sockaddr_in));
198 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000199 if (connected->destination)
200 /* use specified broadcast or point-to-point destination addr */
201 to.sin_addr = connected->destination->u.prefix4;
202 else
203 /* calculate the appropriate broadcast address */
204 to.sin_addr.s_addr =
205 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
206 connected->address->prefixlen);
paul718e3742002-12-13 20:15:29 +0000207
paul718e3742002-12-13 20:15:29 +0000208 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000209 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000210
paul931cd542004-01-23 15:31:42 +0000211 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000212 }
213 }
214 }
215}
216
217/* This will be executed when interface goes up. */
pauldc63bfd2005-10-25 23:31:05 +0000218static void
paul718e3742002-12-13 20:15:29 +0000219rip_request_interface (struct interface *ifp)
220{
221 struct rip_interface *ri;
222
223 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
224 if (if_is_loopback (ifp))
225 return;
226
227 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000228 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000229 return;
230
231 /* Fetch RIP interface information. */
232 ri = ifp->info;
233
234
235 /* If there is no version configuration in the interface,
236 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000237 {
238 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
239 rip->version_send : ri->ri_send);
240 if (vsend & RIPv1)
241 rip_request_interface_send (ifp, RIPv1);
242 if (vsend & RIPv2)
243 rip_request_interface_send (ifp, RIPv2);
244 }
paul718e3742002-12-13 20:15:29 +0000245}
246
247/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000248static void
paul718e3742002-12-13 20:15:29 +0000249rip_request_neighbor (struct in_addr addr)
250{
251 struct sockaddr_in to;
252
253 memset (&to, 0, sizeof (struct sockaddr_in));
254 to.sin_port = htons (RIP_PORT_DEFAULT);
255 to.sin_addr = addr;
256
paul931cd542004-01-23 15:31:42 +0000257 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000258}
259
260/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000261static void
262rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000263{
264 struct route_node *rp;
265
266 if (! rip)
267 return;
268
269 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000270 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000271
272 /* Send request to all neighbor. */
273 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
274 if (rp->info)
275 rip_request_neighbor (rp->p.u.prefix4);
276}
277
278/* Multicast packet receive socket. */
pauldc63bfd2005-10-25 23:31:05 +0000279static int
paul718e3742002-12-13 20:15:29 +0000280rip_multicast_join (struct interface *ifp, int sock)
281{
hasso52dc7ee2004-09-23 19:18:23 +0000282 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000283 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000284
paul2e3b2e42002-12-13 21:03:13 +0000285 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000286 {
287 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000288 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000289
paul1eb8ef22005-04-07 07:30:20 +0000290 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000291 {
292 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000293 struct in_addr group;
294
paul1eb8ef22005-04-07 07:30:20 +0000295 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000296
297 if (p->family != AF_INET)
298 continue;
299
300 group.s_addr = htonl (INADDR_RIP_GROUP);
301 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
302 return -1;
303 else
304 return 0;
305 }
306 }
307 return 0;
308}
309
310/* Leave from multicast group. */
pauldc63bfd2005-10-25 23:31:05 +0000311static void
paul718e3742002-12-13 20:15:29 +0000312rip_multicast_leave (struct interface *ifp, int sock)
313{
hasso52dc7ee2004-09-23 19:18:23 +0000314 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000315 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000316
317 if (if_is_up (ifp) && if_is_multicast (ifp))
318 {
319 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000320 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000321
paul1eb8ef22005-04-07 07:30:20 +0000322 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000323 {
324 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000325 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000326
paul718e3742002-12-13 20:15:29 +0000327 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000328
paul718e3742002-12-13 20:15:29 +0000329 if (p->family != AF_INET)
330 continue;
331
332 group.s_addr = htonl (INADDR_RIP_GROUP);
333 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
334 return;
335 }
336 }
337}
338
339/* Is there and address on interface that I could use ? */
pauldc63bfd2005-10-25 23:31:05 +0000340static int
paul718e3742002-12-13 20:15:29 +0000341rip_if_ipv4_address_check (struct interface *ifp)
342{
343 struct listnode *nn;
344 struct connected *connected;
345 int count = 0;
346
paul1eb8ef22005-04-07 07:30:20 +0000347 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
348 {
349 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000350
paul1eb8ef22005-04-07 07:30:20 +0000351 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000352
paul1eb8ef22005-04-07 07:30:20 +0000353 if (p->family == AF_INET)
354 count++;
355 }
paul718e3742002-12-13 20:15:29 +0000356
357 return count;
358}
paul31a476c2003-09-29 19:54:53 +0000359
360
361
362
363/* Does this address belongs to me ? */
364int
365if_check_address (struct in_addr addr)
366{
hasso52dc7ee2004-09-23 19:18:23 +0000367 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000368 struct interface *ifp;
369
370 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000371 {
hasso52dc7ee2004-09-23 19:18:23 +0000372 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000373 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000374
paul1eb8ef22005-04-07 07:30:20 +0000375 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000376 {
paul31a476c2003-09-29 19:54:53 +0000377 struct prefix_ipv4 *p;
378
paul31a476c2003-09-29 19:54:53 +0000379 p = (struct prefix_ipv4 *) connected->address;
380
381 if (p->family != AF_INET)
382 continue;
383
384 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
385 return 1;
386 }
387 }
388 return 0;
389}
390
paul718e3742002-12-13 20:15:29 +0000391/* Inteface link down message processing. */
392int
393rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
394{
395 struct interface *ifp;
396 struct stream *s;
397
398 s = zclient->ibuf;
399
400 /* zebra_interface_state_read() updates interface structure in
401 iflist. */
402 ifp = zebra_interface_state_read(s);
403
404 if (ifp == NULL)
405 return 0;
406
407 rip_if_down(ifp);
408
409 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000410 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000411 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
412
413 return 0;
414}
415
416/* Inteface link up message processing */
417int
418rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
419{
420 struct interface *ifp;
421
422 /* zebra_interface_state_read () updates interface structure in
423 iflist. */
424 ifp = zebra_interface_state_read (zclient->ibuf);
425
426 if (ifp == NULL)
427 return 0;
428
429 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000430 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000431 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
432
433 /* Check if this interface is RIP enabled or not.*/
434 rip_enable_apply (ifp);
435
436 /* Check for a passive interface */
437 rip_passive_interface_apply (ifp);
438
439 /* Apply distribute list to the all interface. */
440 rip_distribute_update_interface (ifp);
441
442 return 0;
443}
444
445/* Inteface addition message from zebra. */
446int
447rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
448{
449 struct interface *ifp;
450
451 ifp = zebra_interface_add_read (zclient->ibuf);
452
453 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000454 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000455 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
456
457 /* Check if this interface is RIP enabled or not.*/
458 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000459
460 /* Check for a passive interface */
461 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000462
463 /* Apply distribute list to the all interface. */
464 rip_distribute_update_interface (ifp);
465
466 /* rip_request_neighbor_all (); */
467
hasso16705132003-05-25 14:49:19 +0000468 /* Check interface routemap. */
469 rip_if_rmap_update_interface (ifp);
470
paul718e3742002-12-13 20:15:29 +0000471 return 0;
472}
473
474int
475rip_interface_delete (int command, struct zclient *zclient,
476 zebra_size_t length)
477{
478 struct interface *ifp;
479 struct stream *s;
480
481
482 s = zclient->ibuf;
483 /* zebra_interface_state_read() updates interface structure in iflist */
484 ifp = zebra_interface_state_read(s);
485
486 if (ifp == NULL)
487 return 0;
488
489 if (if_is_up (ifp)) {
490 rip_if_down(ifp);
491 }
492
493 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
494 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
495
496 /* To support pseudo interface do not free interface structure. */
497 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000498 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000499
500 return 0;
501}
502
503void
pauldc63bfd2005-10-25 23:31:05 +0000504rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000505{
hasso52dc7ee2004-09-23 19:18:23 +0000506 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000507 struct interface *ifp;
508 struct rip_interface *ri;
509
paul1eb8ef22005-04-07 07:30:20 +0000510 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000511 {
paul718e3742002-12-13 20:15:29 +0000512 ri = ifp->info;
513
514 ri->enable_network = 0;
515 ri->enable_interface = 0;
516 ri->running = 0;
517
518 if (ri->t_wakeup)
519 {
520 thread_cancel (ri->t_wakeup);
521 ri->t_wakeup = NULL;
522 }
523 }
524}
525
526void
pauldc63bfd2005-10-25 23:31:05 +0000527rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000528{
hasso52dc7ee2004-09-23 19:18:23 +0000529 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000530 struct interface *ifp;
531 struct rip_interface *ri;
532
paul1eb8ef22005-04-07 07:30:20 +0000533 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000534 {
paul718e3742002-12-13 20:15:29 +0000535 ri = ifp->info;
536
537 ri->enable_network = 0;
538 ri->enable_interface = 0;
539 ri->running = 0;
540
541 ri->ri_send = RI_RIP_UNSPEC;
542 ri->ri_receive = RI_RIP_UNSPEC;
543
paul7755a8c2005-06-02 08:20:53 +0000544 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000545
546 if (ri->auth_str)
547 {
548 free (ri->auth_str);
549 ri->auth_str = NULL;
550 }
551 if (ri->key_chain)
552 {
553 free (ri->key_chain);
554 ri->key_chain = NULL;
555 }
556
hasso16705132003-05-25 14:49:19 +0000557 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
558 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000559
560 ri->list[RIP_FILTER_IN] = NULL;
561 ri->list[RIP_FILTER_OUT] = NULL;
562
563 ri->prefix[RIP_FILTER_IN] = NULL;
564 ri->prefix[RIP_FILTER_OUT] = NULL;
565
566 if (ri->t_wakeup)
567 {
568 thread_cancel (ri->t_wakeup);
569 ri->t_wakeup = NULL;
570 }
571
572 ri->recv_badpackets = 0;
573 ri->recv_badroutes = 0;
574 ri->sent_updates = 0;
575
576 ri->passive = 0;
577 }
578}
579
580int
581rip_if_down(struct interface *ifp)
582{
583 struct route_node *rp;
584 struct rip_info *rinfo;
585 struct rip_interface *ri = NULL;
586 if (rip)
587 {
588 for (rp = route_top (rip->table); rp; rp = route_next (rp))
589 if ((rinfo = rp->info) != NULL)
590 {
591 /* Routes got through this interface. */
592 if (rinfo->ifindex == ifp->ifindex &&
593 rinfo->type == ZEBRA_ROUTE_RIP &&
594 rinfo->sub_type == RIP_ROUTE_RTE)
595 {
596 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
597 &rinfo->nexthop,
598 rinfo->ifindex);
599
600 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
601 (struct prefix_ipv4 *)&rp->p,
602 rinfo->ifindex);
603 }
604 else
605 {
606 /* All redistributed routes but static and system */
607 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000608 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000609 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
610 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
611 (struct prefix_ipv4 *)&rp->p,
612 rinfo->ifindex);
613 }
614 }
615 }
616
617 ri = ifp->info;
618
619 if (ri->running)
620 {
621 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000622 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000623
624 /* Leave from multicast group. */
625 rip_multicast_leave (ifp, rip->sock);
626
627 ri->running = 0;
628 }
629
630 return 0;
631}
632
633/* Needed for stop RIP process. */
634void
635rip_if_down_all ()
636{
637 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000638 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000639
paul1eb8ef22005-04-07 07:30:20 +0000640 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
641 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000642}
643
hasso16705132003-05-25 14:49:19 +0000644static void
pauldc63bfd2005-10-25 23:31:05 +0000645rip_apply_address_add (struct connected *ifc)
646{
hasso16705132003-05-25 14:49:19 +0000647 struct prefix_ipv4 address;
648 struct prefix *p;
649
650 if (!rip)
651 return;
652
653 if (! if_is_up(ifc->ifp))
654 return;
655
656 p = ifc->address;
657
658 memset (&address, 0, sizeof (address));
659 address.family = p->family;
660 address.prefix = p->u.prefix4;
661 address.prefixlen = p->prefixlen;
662 apply_mask_ipv4(&address);
663
664 /* Check if this interface is RIP enabled or not
665 or Check if this address's prefix is RIP enabled */
666 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
667 (rip_enable_network_lookup2(ifc) >= 0))
668 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000669 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000670
671}
672
paul718e3742002-12-13 20:15:29 +0000673int
674rip_interface_address_add (int command, struct zclient *zclient,
675 zebra_size_t length)
676{
677 struct connected *ifc;
678 struct prefix *p;
679
paul0a589352004-05-08 11:48:26 +0000680 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
681 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000682
683 if (ifc == NULL)
684 return 0;
685
686 p = ifc->address;
687
688 if (p->family == AF_INET)
689 {
690 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000691 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000692 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000693
paul878ef2e2003-09-23 23:41:50 +0000694 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000695 /* Check if this prefix needs to be redistributed */
696 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000697
698#ifdef HAVE_SNMP
699 rip_ifaddr_add (ifc->ifp, ifc);
700#endif /* HAVE_SNMP */
701 }
702
703 return 0;
704}
705
hasso16705132003-05-25 14:49:19 +0000706static void
707rip_apply_address_del (struct connected *ifc) {
708 struct prefix_ipv4 address;
709 struct prefix *p;
710
711 if (!rip)
712 return;
713
714 if (! if_is_up(ifc->ifp))
715 return;
716
717 p = ifc->address;
718
719 memset (&address, 0, sizeof (address));
720 address.family = p->family;
721 address.prefix = p->u.prefix4;
722 address.prefixlen = p->prefixlen;
723 apply_mask_ipv4(&address);
724
725 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
726 &address, ifc->ifp->ifindex);
727}
728
paul718e3742002-12-13 20:15:29 +0000729int
730rip_interface_address_delete (int command, struct zclient *zclient,
731 zebra_size_t length)
732{
733 struct connected *ifc;
734 struct prefix *p;
735
paul0a589352004-05-08 11:48:26 +0000736 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
737 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000738
739 if (ifc)
740 {
741 p = ifc->address;
742 if (p->family == AF_INET)
743 {
744 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000745 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000746 inet_ntoa (p->u.prefix4), p->prefixlen);
747
748#ifdef HAVE_SNMP
749 rip_ifaddr_delete (ifc->ifp, ifc);
750#endif /* HAVE_SNMP */
751
hasso16705132003-05-25 14:49:19 +0000752 /* Chech wether this prefix needs to be removed */
753 rip_apply_address_del(ifc);
754
paul718e3742002-12-13 20:15:29 +0000755 }
756
757 connected_free (ifc);
758
759 }
760
761 return 0;
762}
763
764/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000765/* Check wether the interface has at least a connected prefix that
766 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000767static int
hasso16705132003-05-25 14:49:19 +0000768rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000769{
paul1eb8ef22005-04-07 07:30:20 +0000770 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000771 struct connected *connected;
772 struct prefix_ipv4 address;
773
paul1eb8ef22005-04-07 07:30:20 +0000774 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
775 {
776 struct prefix *p;
777 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000778
paul1eb8ef22005-04-07 07:30:20 +0000779 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000780
paul1eb8ef22005-04-07 07:30:20 +0000781 if (p->family == AF_INET)
782 {
783 address.family = AF_INET;
784 address.prefix = p->u.prefix4;
785 address.prefixlen = IPV4_MAX_BITLEN;
786
787 node = route_node_match (rip_enable_network,
788 (struct prefix *)&address);
789 if (node)
790 {
791 route_unlock_node (node);
792 return 1;
793 }
794 }
795 }
paul718e3742002-12-13 20:15:29 +0000796 return -1;
797}
798
hasso16705132003-05-25 14:49:19 +0000799/* Check wether connected is within the ripng_enable_network table. */
800int
801rip_enable_network_lookup2 (struct connected *connected)
802{
803 struct prefix_ipv4 address;
804 struct prefix *p;
805
806 p = connected->address;
807
808 if (p->family == AF_INET) {
809 struct route_node *node;
810
811 address.family = p->family;
812 address.prefix = p->u.prefix4;
813 address.prefixlen = IPV4_MAX_BITLEN;
814
815 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
816 node = route_node_match (rip_enable_network,
817 (struct prefix *)&address);
818
819 if (node) {
820 route_unlock_node (node);
821 return 1;
822 }
823 }
824
825 return -1;
826}
paul718e3742002-12-13 20:15:29 +0000827/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000828static int
paul718e3742002-12-13 20:15:29 +0000829rip_enable_network_add (struct prefix *p)
830{
831 struct route_node *node;
832
833 node = route_node_get (rip_enable_network, p);
834
835 if (node->info)
836 {
837 route_unlock_node (node);
838 return -1;
839 }
840 else
hasso8a676be2004-10-08 06:36:38 +0000841 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000842
hasso16705132003-05-25 14:49:19 +0000843 /* XXX: One should find a better solution than a generic one */
844 rip_enable_apply_all();
845
paul718e3742002-12-13 20:15:29 +0000846 return 1;
847}
848
849/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000850static int
paul718e3742002-12-13 20:15:29 +0000851rip_enable_network_delete (struct prefix *p)
852{
853 struct route_node *node;
854
855 node = route_node_lookup (rip_enable_network, p);
856 if (node)
857 {
858 node->info = NULL;
859
860 /* Unlock info lock. */
861 route_unlock_node (node);
862
863 /* Unlock lookup lock. */
864 route_unlock_node (node);
865
hasso16705132003-05-25 14:49:19 +0000866 /* XXX: One should find a better solution than a generic one */
867 rip_enable_apply_all ();
868
paul718e3742002-12-13 20:15:29 +0000869 return 1;
870 }
871 return -1;
872}
873
874/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000875static int
hasso98b718a2004-10-11 12:57:57 +0000876rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000877{
hasso8a676be2004-10-08 06:36:38 +0000878 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000879 char *str;
880
paul55468c82005-03-14 20:19:01 +0000881 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000882 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
883 if (strcmp (str, ifname) == 0)
884 return i;
885 return -1;
886}
887
888/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000889static int
hasso98b718a2004-10-11 12:57:57 +0000890rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000891{
892 int ret;
893
894 ret = rip_enable_if_lookup (ifname);
895 if (ret >= 0)
896 return -1;
897
898 vector_set (rip_enable_interface, strdup (ifname));
899
hasso16705132003-05-25 14:49:19 +0000900 rip_enable_apply_all(); /* TODOVJ */
901
paul718e3742002-12-13 20:15:29 +0000902 return 1;
903}
904
905/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000906static int
hasso98b718a2004-10-11 12:57:57 +0000907rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000908{
909 int index;
910 char *str;
911
912 index = rip_enable_if_lookup (ifname);
913 if (index < 0)
914 return -1;
915
916 str = vector_slot (rip_enable_interface, index);
917 free (str);
918 vector_unset (rip_enable_interface, index);
919
hasso16705132003-05-25 14:49:19 +0000920 rip_enable_apply_all(); /* TODOVJ */
921
paul718e3742002-12-13 20:15:29 +0000922 return 1;
923}
924
925/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000926static int
paul718e3742002-12-13 20:15:29 +0000927rip_interface_wakeup (struct thread *t)
928{
929 struct interface *ifp;
930 struct rip_interface *ri;
931
932 /* Get interface. */
933 ifp = THREAD_ARG (t);
934
935 ri = ifp->info;
936 ri->t_wakeup = NULL;
937
938 /* Join to multicast group. */
939 if (rip_multicast_join (ifp, rip->sock) < 0)
940 {
941 zlog_err ("multicast join failed, interface %s not running", ifp->name);
942 return 0;
943 }
944
945 /* Set running flag. */
946 ri->running = 1;
947
948 /* Send RIP request to the interface. */
949 rip_request_interface (ifp);
950
951 return 0;
952}
953
954int rip_redistribute_check (int);
955
pauldc63bfd2005-10-25 23:31:05 +0000956static void
paul718e3742002-12-13 20:15:29 +0000957rip_connect_set (struct interface *ifp, int set)
958{
paul1eb8ef22005-04-07 07:30:20 +0000959 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000960 struct connected *connected;
961 struct prefix_ipv4 address;
962
paul1eb8ef22005-04-07 07:30:20 +0000963 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
964 {
965 struct prefix *p;
966 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000967
paul1eb8ef22005-04-07 07:30:20 +0000968 if (p->family != AF_INET)
969 continue;
paul718e3742002-12-13 20:15:29 +0000970
paul1eb8ef22005-04-07 07:30:20 +0000971 address.family = AF_INET;
972 address.prefix = p->u.prefix4;
973 address.prefixlen = p->prefixlen;
974 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000975
paul1eb8ef22005-04-07 07:30:20 +0000976 if (set) {
977 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
978 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
979 (rip_enable_network_lookup2(connected) >= 0))
980 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000981 &address, connected->ifp->ifindex,
982 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000983 } else
984 {
985 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
986 &address, connected->ifp->ifindex);
987 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
988 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000989 &address, connected->ifp->ifindex,
990 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000991 }
992 }
paul718e3742002-12-13 20:15:29 +0000993}
994
995/* Update interface status. */
996void
997rip_enable_apply (struct interface *ifp)
998{
999 int ret;
1000 struct rip_interface *ri = NULL;
1001
1002 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001003 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001004 return;
1005
1006 ri = ifp->info;
1007
1008 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001009 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001010
1011 /* If the interface is matched. */
1012 if (ret > 0)
1013 ri->enable_network = 1;
1014 else
1015 ri->enable_network = 0;
1016
1017 /* Check interface name configuration. */
1018 ret = rip_enable_if_lookup (ifp->name);
1019 if (ret >= 0)
1020 ri->enable_interface = 1;
1021 else
1022 ri->enable_interface = 0;
1023
1024 /* any interface MUST have an IPv4 address */
1025 if ( ! rip_if_ipv4_address_check (ifp) )
1026 {
1027 ri->enable_network = 0;
1028 ri->enable_interface = 0;
1029 }
1030
1031 /* Update running status of the interface. */
1032 if (ri->enable_network || ri->enable_interface)
1033 {
paul718e3742002-12-13 20:15:29 +00001034 {
1035 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001036 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001037
1038 /* Add interface wake up thread. */
1039 if (! ri->t_wakeup)
1040 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1041 ifp, 1);
1042 rip_connect_set (ifp, 1);
1043 }
1044 }
1045 else
1046 {
1047 if (ri->running)
1048 {
hasso16705132003-05-25 14:49:19 +00001049 /* Might as well clean up the route table as well
1050 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1051 **/
paul718e3742002-12-13 20:15:29 +00001052 rip_if_down(ifp);
1053
paul718e3742002-12-13 20:15:29 +00001054 rip_connect_set (ifp, 0);
1055 }
1056 }
1057}
1058
1059/* Apply network configuration to all interface. */
1060void
1061rip_enable_apply_all ()
1062{
1063 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001064 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001065
1066 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001067 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1068 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001069}
1070
1071int
1072rip_neighbor_lookup (struct sockaddr_in *from)
1073{
1074 struct prefix_ipv4 p;
1075 struct route_node *node;
1076
1077 memset (&p, 0, sizeof (struct prefix_ipv4));
1078 p.family = AF_INET;
1079 p.prefix = from->sin_addr;
1080 p.prefixlen = IPV4_MAX_BITLEN;
1081
1082 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1083 if (node)
1084 {
1085 route_unlock_node (node);
1086 return 1;
1087 }
1088 return 0;
1089}
1090
1091/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001092static int
paul718e3742002-12-13 20:15:29 +00001093rip_neighbor_add (struct prefix_ipv4 *p)
1094{
1095 struct route_node *node;
1096
1097 node = route_node_get (rip->neighbor, (struct prefix *) p);
1098
1099 if (node->info)
1100 return -1;
1101
1102 node->info = rip->neighbor;
1103
1104 return 0;
1105}
1106
1107/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001108static int
paul718e3742002-12-13 20:15:29 +00001109rip_neighbor_delete (struct prefix_ipv4 *p)
1110{
1111 struct route_node *node;
1112
1113 /* Lock for look up. */
1114 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1115 if (! node)
1116 return -1;
1117
1118 node->info = NULL;
1119
1120 /* Unlock lookup lock. */
1121 route_unlock_node (node);
1122
1123 /* Unlock real neighbor information lock. */
1124 route_unlock_node (node);
1125
1126 return 0;
1127}
1128
1129/* Clear all network and neighbor configuration. */
1130void
1131rip_clean_network ()
1132{
hasso8a676be2004-10-08 06:36:38 +00001133 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001134 char *str;
1135 struct route_node *rn;
1136
1137 /* rip_enable_network. */
1138 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1139 if (rn->info)
1140 {
1141 rn->info = NULL;
1142 route_unlock_node (rn);
1143 }
1144
1145 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001146 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001147 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1148 {
1149 free (str);
1150 vector_slot (rip_enable_interface, i) = NULL;
1151 }
1152}
1153
1154/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001155static int
hasso98b718a2004-10-11 12:57:57 +00001156rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001157{
hasso8a676be2004-10-08 06:36:38 +00001158 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001159 char *str;
1160
paul55468c82005-03-14 20:19:01 +00001161 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001162 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001163 if (strcmp (str, ifname) == 0)
1164 return i;
1165 return -1;
1166}
1167
1168void
1169rip_passive_interface_apply (struct interface *ifp)
1170{
paul718e3742002-12-13 20:15:29 +00001171 struct rip_interface *ri;
1172
1173 ri = ifp->info;
1174
paul4aaff3f2003-06-07 01:04:45 +00001175 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1176 passive_default : !passive_default);
1177
1178 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001179 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001180}
1181
pauldc63bfd2005-10-25 23:31:05 +00001182static void
1183rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001184{
1185 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001186 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001187
paul1eb8ef22005-04-07 07:30:20 +00001188 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1189 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001190}
1191
1192/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001193static int
hasso98b718a2004-10-11 12:57:57 +00001194rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001195{
paul4aaff3f2003-06-07 01:04:45 +00001196 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001197 return CMD_WARNING;
1198
paul4aaff3f2003-06-07 01:04:45 +00001199 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001200
1201 rip_passive_interface_apply_all ();
1202
1203 return CMD_SUCCESS;
1204}
1205
pauldc63bfd2005-10-25 23:31:05 +00001206static int
hasso98b718a2004-10-11 12:57:57 +00001207rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001208{
1209 int i;
1210 char *str;
1211
paul4aaff3f2003-06-07 01:04:45 +00001212 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001213 if (i < 0)
1214 return CMD_WARNING;
1215
paul4aaff3f2003-06-07 01:04:45 +00001216 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001217 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001218 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001219
1220 rip_passive_interface_apply_all ();
1221
1222 return CMD_SUCCESS;
1223}
1224
1225/* Free all configured RIP passive-interface settings. */
1226void
pauldc63bfd2005-10-25 23:31:05 +00001227rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001228{
hasso8a676be2004-10-08 06:36:38 +00001229 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001230 char *str;
1231
paul55468c82005-03-14 20:19:01 +00001232 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001233 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001234 {
1235 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001236 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001237 }
1238 rip_passive_interface_apply_all ();
1239}
1240
1241/* RIP enable network or interface configuration. */
1242DEFUN (rip_network,
1243 rip_network_cmd,
1244 "network (A.B.C.D/M|WORD)",
1245 "Enable routing on an IP network\n"
1246 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1247 "Interface name\n")
1248{
1249 int ret;
1250 struct prefix_ipv4 p;
1251
1252 ret = str2prefix_ipv4 (argv[0], &p);
1253
1254 if (ret)
1255 ret = rip_enable_network_add ((struct prefix *) &p);
1256 else
1257 ret = rip_enable_if_add (argv[0]);
1258
1259 if (ret < 0)
1260 {
1261 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1262 VTY_NEWLINE);
1263 return CMD_WARNING;
1264 }
1265
paul718e3742002-12-13 20:15:29 +00001266 return CMD_SUCCESS;
1267}
1268
1269/* RIP enable network or interface configuration. */
1270DEFUN (no_rip_network,
1271 no_rip_network_cmd,
1272 "no network (A.B.C.D/M|WORD)",
1273 NO_STR
1274 "Enable routing on an IP network\n"
1275 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1276 "Interface name\n")
1277{
1278 int ret;
1279 struct prefix_ipv4 p;
1280
1281 ret = str2prefix_ipv4 (argv[0], &p);
1282
1283 if (ret)
1284 ret = rip_enable_network_delete ((struct prefix *) &p);
1285 else
1286 ret = rip_enable_if_delete (argv[0]);
1287
1288 if (ret < 0)
1289 {
1290 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1291 VTY_NEWLINE);
1292 return CMD_WARNING;
1293 }
1294
paul718e3742002-12-13 20:15:29 +00001295 return CMD_SUCCESS;
1296}
1297
1298/* RIP neighbor configuration set. */
1299DEFUN (rip_neighbor,
1300 rip_neighbor_cmd,
1301 "neighbor A.B.C.D",
1302 "Specify a neighbor router\n"
1303 "Neighbor address\n")
1304{
1305 int ret;
1306 struct prefix_ipv4 p;
1307
1308 ret = str2prefix_ipv4 (argv[0], &p);
1309
1310 if (ret <= 0)
1311 {
1312 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1313 return CMD_WARNING;
1314 }
1315
1316 rip_neighbor_add (&p);
1317
1318 return CMD_SUCCESS;
1319}
1320
1321/* RIP neighbor configuration unset. */
1322DEFUN (no_rip_neighbor,
1323 no_rip_neighbor_cmd,
1324 "no neighbor A.B.C.D",
1325 NO_STR
1326 "Specify a neighbor router\n"
1327 "Neighbor address\n")
1328{
1329 int ret;
1330 struct prefix_ipv4 p;
1331
1332 ret = str2prefix_ipv4 (argv[0], &p);
1333
1334 if (ret <= 0)
1335 {
1336 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1337 return CMD_WARNING;
1338 }
1339
1340 rip_neighbor_delete (&p);
1341
1342 return CMD_SUCCESS;
1343}
1344
1345DEFUN (ip_rip_receive_version,
1346 ip_rip_receive_version_cmd,
1347 "ip rip receive version (1|2)",
1348 IP_STR
1349 "Routing Information Protocol\n"
1350 "Advertisement reception\n"
1351 "Version control\n"
1352 "RIP version 1\n"
1353 "RIP version 2\n")
1354{
1355 struct interface *ifp;
1356 struct rip_interface *ri;
1357
1358 ifp = (struct interface *)vty->index;
1359 ri = ifp->info;
1360
1361 /* Version 1. */
1362 if (atoi (argv[0]) == 1)
1363 {
1364 ri->ri_receive = RI_RIP_VERSION_1;
1365 return CMD_SUCCESS;
1366 }
1367 if (atoi (argv[0]) == 2)
1368 {
1369 ri->ri_receive = RI_RIP_VERSION_2;
1370 return CMD_SUCCESS;
1371 }
1372 return CMD_WARNING;
1373}
1374
1375DEFUN (ip_rip_receive_version_1,
1376 ip_rip_receive_version_1_cmd,
1377 "ip rip receive version 1 2",
1378 IP_STR
1379 "Routing Information Protocol\n"
1380 "Advertisement reception\n"
1381 "Version control\n"
1382 "RIP version 1\n"
1383 "RIP version 2\n")
1384{
1385 struct interface *ifp;
1386 struct rip_interface *ri;
1387
1388 ifp = (struct interface *)vty->index;
1389 ri = ifp->info;
1390
1391 /* Version 1 and 2. */
1392 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1393 return CMD_SUCCESS;
1394}
1395
1396DEFUN (ip_rip_receive_version_2,
1397 ip_rip_receive_version_2_cmd,
1398 "ip rip receive version 2 1",
1399 IP_STR
1400 "Routing Information Protocol\n"
1401 "Advertisement reception\n"
1402 "Version control\n"
1403 "RIP version 2\n"
1404 "RIP version 1\n")
1405{
1406 struct interface *ifp;
1407 struct rip_interface *ri;
1408
1409 ifp = (struct interface *)vty->index;
1410 ri = ifp->info;
1411
1412 /* Version 1 and 2. */
1413 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1414 return CMD_SUCCESS;
1415}
1416
1417DEFUN (no_ip_rip_receive_version,
1418 no_ip_rip_receive_version_cmd,
1419 "no ip rip receive version",
1420 NO_STR
1421 IP_STR
1422 "Routing Information Protocol\n"
1423 "Advertisement reception\n"
1424 "Version control\n")
1425{
1426 struct interface *ifp;
1427 struct rip_interface *ri;
1428
1429 ifp = (struct interface *)vty->index;
1430 ri = ifp->info;
1431
1432 ri->ri_receive = RI_RIP_UNSPEC;
1433 return CMD_SUCCESS;
1434}
1435
1436ALIAS (no_ip_rip_receive_version,
1437 no_ip_rip_receive_version_num_cmd,
1438 "no ip rip receive version (1|2)",
1439 NO_STR
1440 IP_STR
1441 "Routing Information Protocol\n"
1442 "Advertisement reception\n"
1443 "Version control\n"
1444 "Version 1\n"
1445 "Version 2\n")
1446
1447DEFUN (ip_rip_send_version,
1448 ip_rip_send_version_cmd,
1449 "ip rip send version (1|2)",
1450 IP_STR
1451 "Routing Information Protocol\n"
1452 "Advertisement transmission\n"
1453 "Version control\n"
1454 "RIP version 1\n"
1455 "RIP version 2\n")
1456{
1457 struct interface *ifp;
1458 struct rip_interface *ri;
1459
1460 ifp = (struct interface *)vty->index;
1461 ri = ifp->info;
1462
1463 /* Version 1. */
1464 if (atoi (argv[0]) == 1)
1465 {
1466 ri->ri_send = RI_RIP_VERSION_1;
1467 return CMD_SUCCESS;
1468 }
1469 if (atoi (argv[0]) == 2)
1470 {
1471 ri->ri_send = RI_RIP_VERSION_2;
1472 return CMD_SUCCESS;
1473 }
1474 return CMD_WARNING;
1475}
1476
1477DEFUN (ip_rip_send_version_1,
1478 ip_rip_send_version_1_cmd,
1479 "ip rip send version 1 2",
1480 IP_STR
1481 "Routing Information Protocol\n"
1482 "Advertisement transmission\n"
1483 "Version control\n"
1484 "RIP version 1\n"
1485 "RIP version 2\n")
1486{
1487 struct interface *ifp;
1488 struct rip_interface *ri;
1489
1490 ifp = (struct interface *)vty->index;
1491 ri = ifp->info;
1492
1493 /* Version 1 and 2. */
1494 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1495 return CMD_SUCCESS;
1496}
1497
1498DEFUN (ip_rip_send_version_2,
1499 ip_rip_send_version_2_cmd,
1500 "ip rip send version 2 1",
1501 IP_STR
1502 "Routing Information Protocol\n"
1503 "Advertisement transmission\n"
1504 "Version control\n"
1505 "RIP version 2\n"
1506 "RIP version 1\n")
1507{
1508 struct interface *ifp;
1509 struct rip_interface *ri;
1510
1511 ifp = (struct interface *)vty->index;
1512 ri = ifp->info;
1513
1514 /* Version 1 and 2. */
1515 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1516 return CMD_SUCCESS;
1517}
1518
1519DEFUN (no_ip_rip_send_version,
1520 no_ip_rip_send_version_cmd,
1521 "no ip rip send version",
1522 NO_STR
1523 IP_STR
1524 "Routing Information Protocol\n"
1525 "Advertisement transmission\n"
1526 "Version control\n")
1527{
1528 struct interface *ifp;
1529 struct rip_interface *ri;
1530
1531 ifp = (struct interface *)vty->index;
1532 ri = ifp->info;
1533
1534 ri->ri_send = RI_RIP_UNSPEC;
1535 return CMD_SUCCESS;
1536}
1537
1538ALIAS (no_ip_rip_send_version,
1539 no_ip_rip_send_version_num_cmd,
1540 "no ip rip send version (1|2)",
1541 NO_STR
1542 IP_STR
1543 "Routing Information Protocol\n"
1544 "Advertisement transmission\n"
1545 "Version control\n"
1546 "Version 1\n"
1547 "Version 2\n")
1548
1549DEFUN (ip_rip_authentication_mode,
1550 ip_rip_authentication_mode_cmd,
1551 "ip rip authentication mode (md5|text)",
1552 IP_STR
1553 "Routing Information Protocol\n"
1554 "Authentication control\n"
1555 "Authentication mode\n"
1556 "Keyed message digest\n"
1557 "Clear text authentication\n")
1558{
1559 struct interface *ifp;
1560 struct rip_interface *ri;
1561
1562 ifp = (struct interface *)vty->index;
1563 ri = ifp->info;
1564
paulca5e5162004-06-06 22:06:33 +00001565 if ( (argc < 1) || (argc > 2) )
1566 {
1567 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1568 return CMD_WARNING;
1569 }
1570
paul718e3742002-12-13 20:15:29 +00001571 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1572 ri->auth_type = RIP_AUTH_MD5;
1573 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1574 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1575 else
1576 {
1577 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1578 return CMD_WARNING;
1579 }
1580
paulca5e5162004-06-06 22:06:33 +00001581 if (argc == 1)
1582 return CMD_SUCCESS;
1583
1584 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1585 {
1586 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1587 return CMD_WARNING;
1588}
1589
1590 if (strncmp ("r", argv[1], 1) == 0)
1591 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1592 else if (strncmp ("o", argv[1], 1) == 0)
1593 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1594 else
1595 return CMD_WARNING;
1596
paul718e3742002-12-13 20:15:29 +00001597 return CMD_SUCCESS;
1598}
1599
paulca5e5162004-06-06 22:06:33 +00001600ALIAS (ip_rip_authentication_mode,
1601 ip_rip_authentication_mode_authlen_cmd,
1602 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1603 IP_STR
1604 "Routing Information Protocol\n"
1605 "Authentication control\n"
1606 "Authentication mode\n"
1607 "Keyed message digest\n"
1608 "Clear text authentication\n"
1609 "MD5 authentication data length\n"
1610 "RFC compatible\n"
1611 "Old ripd compatible\n")
1612
paul718e3742002-12-13 20:15:29 +00001613DEFUN (no_ip_rip_authentication_mode,
1614 no_ip_rip_authentication_mode_cmd,
1615 "no ip rip authentication mode",
1616 NO_STR
1617 IP_STR
1618 "Routing Information Protocol\n"
1619 "Authentication control\n"
1620 "Authentication mode\n")
1621{
1622 struct interface *ifp;
1623 struct rip_interface *ri;
1624
1625 ifp = (struct interface *)vty->index;
1626 ri = ifp->info;
1627
paul7755a8c2005-06-02 08:20:53 +00001628 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001629 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001630
1631 return CMD_SUCCESS;
1632}
1633
1634ALIAS (no_ip_rip_authentication_mode,
1635 no_ip_rip_authentication_mode_type_cmd,
1636 "no ip rip authentication mode (md5|text)",
1637 NO_STR
1638 IP_STR
1639 "Routing Information Protocol\n"
1640 "Authentication control\n"
1641 "Authentication mode\n"
1642 "Keyed message digest\n"
1643 "Clear text authentication\n")
1644
paulca5e5162004-06-06 22:06:33 +00001645ALIAS (no_ip_rip_authentication_mode,
1646 no_ip_rip_authentication_mode_type_authlen_cmd,
1647 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1648 NO_STR
1649 IP_STR
1650 "Routing Information Protocol\n"
1651 "Authentication control\n"
1652 "Authentication mode\n"
1653 "Keyed message digest\n"
1654 "Clear text authentication\n"
1655 "MD5 authentication data length\n"
1656 "RFC compatible\n"
1657 "Old ripd compatible\n")
1658
paul718e3742002-12-13 20:15:29 +00001659DEFUN (ip_rip_authentication_string,
1660 ip_rip_authentication_string_cmd,
1661 "ip rip authentication string LINE",
1662 IP_STR
1663 "Routing Information Protocol\n"
1664 "Authentication control\n"
1665 "Authentication string\n"
1666 "Authentication string\n")
1667{
1668 struct interface *ifp;
1669 struct rip_interface *ri;
1670
1671 ifp = (struct interface *)vty->index;
1672 ri = ifp->info;
1673
1674 if (strlen (argv[0]) > 16)
1675 {
1676 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1677 VTY_NEWLINE);
1678 return CMD_WARNING;
1679 }
1680
1681 if (ri->key_chain)
1682 {
1683 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1684 return CMD_WARNING;
1685 }
1686
1687 if (ri->auth_str)
1688 free (ri->auth_str);
1689
1690 ri->auth_str = strdup (argv[0]);
1691
1692 return CMD_SUCCESS;
1693}
1694
1695DEFUN (no_ip_rip_authentication_string,
1696 no_ip_rip_authentication_string_cmd,
1697 "no ip rip authentication string",
1698 NO_STR
1699 IP_STR
1700 "Routing Information Protocol\n"
1701 "Authentication control\n"
1702 "Authentication string\n")
1703{
1704 struct interface *ifp;
1705 struct rip_interface *ri;
1706
1707 ifp = (struct interface *)vty->index;
1708 ri = ifp->info;
1709
1710 if (ri->auth_str)
1711 free (ri->auth_str);
1712
1713 ri->auth_str = NULL;
1714
1715 return CMD_SUCCESS;
1716}
1717
1718ALIAS (no_ip_rip_authentication_string,
1719 no_ip_rip_authentication_string2_cmd,
1720 "no ip rip authentication string LINE",
1721 NO_STR
1722 IP_STR
1723 "Routing Information Protocol\n"
1724 "Authentication control\n"
1725 "Authentication string\n"
1726 "Authentication string\n")
1727
1728DEFUN (ip_rip_authentication_key_chain,
1729 ip_rip_authentication_key_chain_cmd,
1730 "ip rip authentication key-chain LINE",
1731 IP_STR
1732 "Routing Information Protocol\n"
1733 "Authentication control\n"
1734 "Authentication key-chain\n"
1735 "name of key-chain\n")
1736{
1737 struct interface *ifp;
1738 struct rip_interface *ri;
1739
1740 ifp = (struct interface *) vty->index;
1741 ri = ifp->info;
1742
1743 if (ri->auth_str)
1744 {
1745 vty_out (vty, "%% authentication string configuration exists%s",
1746 VTY_NEWLINE);
1747 return CMD_WARNING;
1748 }
1749
1750 if (ri->key_chain)
1751 free (ri->key_chain);
1752
1753 ri->key_chain = strdup (argv[0]);
1754
1755 return CMD_SUCCESS;
1756}
1757
1758DEFUN (no_ip_rip_authentication_key_chain,
1759 no_ip_rip_authentication_key_chain_cmd,
1760 "no ip rip authentication key-chain",
1761 NO_STR
1762 IP_STR
1763 "Routing Information Protocol\n"
1764 "Authentication control\n"
1765 "Authentication key-chain\n")
1766{
1767 struct interface *ifp;
1768 struct rip_interface *ri;
1769
1770 ifp = (struct interface *) vty->index;
1771 ri = ifp->info;
1772
1773 if (ri->key_chain)
1774 free (ri->key_chain);
1775
1776 ri->key_chain = NULL;
1777
1778 return CMD_SUCCESS;
1779}
1780
1781ALIAS (no_ip_rip_authentication_key_chain,
1782 no_ip_rip_authentication_key_chain2_cmd,
1783 "no ip rip authentication key-chain LINE",
1784 NO_STR
1785 IP_STR
1786 "Routing Information Protocol\n"
1787 "Authentication control\n"
1788 "Authentication key-chain\n"
1789 "name of key-chain\n")
1790
hasso16705132003-05-25 14:49:19 +00001791/* CHANGED: ip rip split-horizon
1792 Cisco and Zebra's command is
1793 ip split-horizon
1794 */
1795DEFUN (ip_rip_split_horizon,
1796 ip_rip_split_horizon_cmd,
1797 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001798 IP_STR
hasso16705132003-05-25 14:49:19 +00001799 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001800 "Perform split horizon\n")
1801{
1802 struct interface *ifp;
1803 struct rip_interface *ri;
1804
1805 ifp = vty->index;
1806 ri = ifp->info;
1807
hasso16705132003-05-25 14:49:19 +00001808 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001809 return CMD_SUCCESS;
1810}
1811
hasso16705132003-05-25 14:49:19 +00001812DEFUN (ip_rip_split_horizon_poisoned_reverse,
1813 ip_rip_split_horizon_poisoned_reverse_cmd,
1814 "ip rip split-horizon poisoned-reverse",
1815 IP_STR
1816 "Routing Information Protocol\n"
1817 "Perform split horizon\n"
1818 "With poisoned-reverse\n")
1819{
1820 struct interface *ifp;
1821 struct rip_interface *ri;
1822
1823 ifp = vty->index;
1824 ri = ifp->info;
1825
1826 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1827 return CMD_SUCCESS;
1828}
1829
1830/* CHANGED: no ip rip split-horizon
1831 Cisco and Zebra's command is
1832 no ip split-horizon
1833 */
1834DEFUN (no_ip_rip_split_horizon,
1835 no_ip_rip_split_horizon_cmd,
1836 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001837 NO_STR
1838 IP_STR
hasso16705132003-05-25 14:49:19 +00001839 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001840 "Perform split horizon\n")
1841{
1842 struct interface *ifp;
1843 struct rip_interface *ri;
1844
1845 ifp = vty->index;
1846 ri = ifp->info;
1847
hasso16705132003-05-25 14:49:19 +00001848 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001849 return CMD_SUCCESS;
1850}
1851
vincentfac3e842005-10-06 07:45:43 +00001852DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001853 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1854 "no ip rip split-horizon poisoned-reverse",
1855 NO_STR
1856 IP_STR
1857 "Routing Information Protocol\n"
1858 "Perform split horizon\n"
1859 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001860{
1861 struct interface *ifp;
1862 struct rip_interface *ri;
1863
1864 ifp = vty->index;
1865 ri = ifp->info;
1866
1867 switch( ri->split_horizon )
1868 {
1869 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1870 ri->split_horizon = RIP_SPLIT_HORIZON;
1871 default:
1872 break;
1873 }
1874
1875 return CMD_SUCCESS;
1876}
hasso16705132003-05-25 14:49:19 +00001877
paul718e3742002-12-13 20:15:29 +00001878DEFUN (rip_passive_interface,
1879 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001880 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001881 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001882 "Interface name\n"
1883 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001884{
hasso98b718a2004-10-11 12:57:57 +00001885 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001886
1887 if (!strcmp(ifname,"default")) {
1888 passive_default = 1;
1889 rip_passive_nondefault_clean();
1890 return CMD_SUCCESS;
1891 }
1892 if (passive_default)
1893 return rip_passive_nondefault_unset (vty, ifname);
1894 else
1895 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001896}
1897
1898DEFUN (no_rip_passive_interface,
1899 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001900 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001901 NO_STR
1902 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001903 "Interface name\n"
1904 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001905{
hasso98b718a2004-10-11 12:57:57 +00001906 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001907
1908 if (!strcmp(ifname,"default")) {
1909 passive_default = 0;
1910 rip_passive_nondefault_clean();
1911 return CMD_SUCCESS;
1912 }
1913 if (passive_default)
1914 return rip_passive_nondefault_set (vty, ifname);
1915 else
1916 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001917}
1918
1919/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001920static int
paul718e3742002-12-13 20:15:29 +00001921rip_interface_config_write (struct vty *vty)
1922{
hasso52dc7ee2004-09-23 19:18:23 +00001923 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001924 struct interface *ifp;
1925
paul1eb8ef22005-04-07 07:30:20 +00001926 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001927 {
1928 struct rip_interface *ri;
1929
paul718e3742002-12-13 20:15:29 +00001930 ri = ifp->info;
1931
hasso16705132003-05-25 14:49:19 +00001932 /* Do not display the interface if there is no
1933 * configuration about it.
1934 **/
1935 if ((!ifp->desc) &&
1936 (ri->split_horizon == ri->split_horizon_default) &&
1937 (ri->ri_send == RI_RIP_UNSPEC) &&
1938 (ri->ri_receive == RI_RIP_UNSPEC) &&
1939 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001940 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001941 (!ri->auth_str) &&
1942 (!ri->key_chain) )
1943 continue;
1944
paul718e3742002-12-13 20:15:29 +00001945 vty_out (vty, "interface %s%s", ifp->name,
1946 VTY_NEWLINE);
1947
1948 if (ifp->desc)
1949 vty_out (vty, " description %s%s", ifp->desc,
1950 VTY_NEWLINE);
1951
1952 /* Split horizon. */
1953 if (ri->split_horizon != ri->split_horizon_default)
1954 {
hasso16705132003-05-25 14:49:19 +00001955 switch (ri->split_horizon) {
1956 case RIP_SPLIT_HORIZON:
1957 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1958 break;
1959 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1960 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1961 VTY_NEWLINE);
1962 break;
1963 case RIP_NO_SPLIT_HORIZON:
1964 default:
1965 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1966 break;
1967 }
paul718e3742002-12-13 20:15:29 +00001968 }
1969
1970 /* RIP version setting. */
1971 if (ri->ri_send != RI_RIP_UNSPEC)
1972 vty_out (vty, " ip rip send version %s%s",
1973 lookup (ri_version_msg, ri->ri_send),
1974 VTY_NEWLINE);
1975
1976 if (ri->ri_receive != RI_RIP_UNSPEC)
1977 vty_out (vty, " ip rip receive version %s%s",
1978 lookup (ri_version_msg, ri->ri_receive),
1979 VTY_NEWLINE);
1980
1981 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001982 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1983 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001984
paul718e3742002-12-13 20:15:29 +00001985 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001986 {
1987 vty_out (vty, " ip rip authentication mode md5");
1988 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1989 vty_out (vty, " auth-length old-ripd");
1990 else
1991 vty_out (vty, " auth-length rfc");
1992 vty_out (vty, "%s", VTY_NEWLINE);
1993 }
paul718e3742002-12-13 20:15:29 +00001994
1995 if (ri->auth_str)
1996 vty_out (vty, " ip rip authentication string %s%s",
1997 ri->auth_str, VTY_NEWLINE);
1998
1999 if (ri->key_chain)
2000 vty_out (vty, " ip rip authentication key-chain %s%s",
2001 ri->key_chain, VTY_NEWLINE);
2002
2003 vty_out (vty, "!%s", VTY_NEWLINE);
2004 }
2005 return 0;
2006}
2007
2008int
2009config_write_rip_network (struct vty *vty, int config_mode)
2010{
hasso8a676be2004-10-08 06:36:38 +00002011 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002012 char *ifname;
2013 struct route_node *node;
2014
2015 /* Network type RIP enable interface statement. */
2016 for (node = route_top (rip_enable_network); node; node = route_next (node))
2017 if (node->info)
2018 vty_out (vty, "%s%s/%d%s",
2019 config_mode ? " network " : " ",
2020 inet_ntoa (node->p.u.prefix4),
2021 node->p.prefixlen,
2022 VTY_NEWLINE);
2023
2024 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002025 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002026 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2027 vty_out (vty, "%s%s%s",
2028 config_mode ? " network " : " ",
2029 ifname,
2030 VTY_NEWLINE);
2031
2032 /* RIP neighbors listing. */
2033 for (node = route_top (rip->neighbor); node; node = route_next (node))
2034 if (node->info)
2035 vty_out (vty, "%s%s%s",
2036 config_mode ? " neighbor " : " ",
2037 inet_ntoa (node->p.u.prefix4),
2038 VTY_NEWLINE);
2039
2040 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002041 if (config_mode) {
2042 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002043 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002044 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002045 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2046 vty_out (vty, " %spassive-interface %s%s",
2047 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2048 }
paul718e3742002-12-13 20:15:29 +00002049
2050 return 0;
2051}
2052
2053struct cmd_node interface_node =
2054{
2055 INTERFACE_NODE,
2056 "%s(config-if)# ",
2057 1,
2058};
2059
2060/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002061static int
paul718e3742002-12-13 20:15:29 +00002062rip_interface_new_hook (struct interface *ifp)
2063{
2064 ifp->info = rip_interface_new ();
2065 return 0;
2066}
2067
2068/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002069static int
paul718e3742002-12-13 20:15:29 +00002070rip_interface_delete_hook (struct interface *ifp)
2071{
2072 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002073 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002074 return 0;
2075}
2076
2077/* Allocate and initialize interface vector. */
2078void
pauldc63bfd2005-10-25 23:31:05 +00002079rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002080{
2081 /* Default initial size of interface vector. */
2082 if_init();
2083 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2084 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2085
2086 /* RIP network init. */
2087 rip_enable_interface = vector_init (1);
2088 rip_enable_network = route_table_init ();
2089
2090 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002091 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002092
2093 /* Install interface node. */
2094 install_node (&interface_node, rip_interface_config_write);
2095
2096 /* Install commands. */
2097 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002098 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002099 install_default (INTERFACE_NODE);
2100 install_element (INTERFACE_NODE, &interface_desc_cmd);
2101 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2102 install_element (RIP_NODE, &rip_network_cmd);
2103 install_element (RIP_NODE, &no_rip_network_cmd);
2104 install_element (RIP_NODE, &rip_neighbor_cmd);
2105 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2106
2107 install_element (RIP_NODE, &rip_passive_interface_cmd);
2108 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2109
2110 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2111 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2112 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2113 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2114 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2115
2116 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2117 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2118 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2119 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2120 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2121
2122 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002123 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002124 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2125 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002126 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002127
2128 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2129 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2130 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2131
2132 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2133 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2134 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2135
hasso16705132003-05-25 14:49:19 +00002136 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2137 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2138 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2139 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002140}