blob: a5b12db6efb1c8bb825fb3a2ec0ded2c9d2b981d [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;
Paul Jakma15a2b082006-05-04 07:36:34 +00001561 int auth_type;
paul718e3742002-12-13 20:15:29 +00001562
1563 ifp = (struct interface *)vty->index;
1564 ri = ifp->info;
1565
paulca5e5162004-06-06 22:06:33 +00001566 if ( (argc < 1) || (argc > 2) )
1567 {
1568 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1569 return CMD_WARNING;
1570 }
1571
paul718e3742002-12-13 20:15:29 +00001572 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001573 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001574 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001575 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001576 else
1577 {
1578 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1579 return CMD_WARNING;
1580 }
1581
paulca5e5162004-06-06 22:06:33 +00001582 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001583 {
1584 ri->auth_type = auth_type;
1585 return CMD_SUCCESS;
1586 }
paulca5e5162004-06-06 22:06:33 +00001587
Paul Jakma15a2b082006-05-04 07:36:34 +00001588 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001589 {
1590 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1591 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001592 }
paulca5e5162004-06-06 22:06:33 +00001593
1594 if (strncmp ("r", argv[1], 1) == 0)
1595 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1596 else if (strncmp ("o", argv[1], 1) == 0)
1597 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1598 else
1599 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001600
1601 ri->auth_type = auth_type;
1602
paul718e3742002-12-13 20:15:29 +00001603 return CMD_SUCCESS;
1604}
1605
paulca5e5162004-06-06 22:06:33 +00001606ALIAS (ip_rip_authentication_mode,
1607 ip_rip_authentication_mode_authlen_cmd,
1608 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1609 IP_STR
1610 "Routing Information Protocol\n"
1611 "Authentication control\n"
1612 "Authentication mode\n"
1613 "Keyed message digest\n"
1614 "Clear text authentication\n"
1615 "MD5 authentication data length\n"
1616 "RFC compatible\n"
1617 "Old ripd compatible\n")
1618
paul718e3742002-12-13 20:15:29 +00001619DEFUN (no_ip_rip_authentication_mode,
1620 no_ip_rip_authentication_mode_cmd,
1621 "no ip rip authentication mode",
1622 NO_STR
1623 IP_STR
1624 "Routing Information Protocol\n"
1625 "Authentication control\n"
1626 "Authentication mode\n")
1627{
1628 struct interface *ifp;
1629 struct rip_interface *ri;
1630
1631 ifp = (struct interface *)vty->index;
1632 ri = ifp->info;
1633
paul7755a8c2005-06-02 08:20:53 +00001634 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001635 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001636
1637 return CMD_SUCCESS;
1638}
1639
1640ALIAS (no_ip_rip_authentication_mode,
1641 no_ip_rip_authentication_mode_type_cmd,
1642 "no ip rip authentication mode (md5|text)",
1643 NO_STR
1644 IP_STR
1645 "Routing Information Protocol\n"
1646 "Authentication control\n"
1647 "Authentication mode\n"
1648 "Keyed message digest\n"
1649 "Clear text authentication\n")
1650
paulca5e5162004-06-06 22:06:33 +00001651ALIAS (no_ip_rip_authentication_mode,
1652 no_ip_rip_authentication_mode_type_authlen_cmd,
1653 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1654 NO_STR
1655 IP_STR
1656 "Routing Information Protocol\n"
1657 "Authentication control\n"
1658 "Authentication mode\n"
1659 "Keyed message digest\n"
1660 "Clear text authentication\n"
1661 "MD5 authentication data length\n"
1662 "RFC compatible\n"
1663 "Old ripd compatible\n")
1664
paul718e3742002-12-13 20:15:29 +00001665DEFUN (ip_rip_authentication_string,
1666 ip_rip_authentication_string_cmd,
1667 "ip rip authentication string LINE",
1668 IP_STR
1669 "Routing Information Protocol\n"
1670 "Authentication control\n"
1671 "Authentication string\n"
1672 "Authentication string\n")
1673{
1674 struct interface *ifp;
1675 struct rip_interface *ri;
1676
1677 ifp = (struct interface *)vty->index;
1678 ri = ifp->info;
1679
1680 if (strlen (argv[0]) > 16)
1681 {
1682 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1683 VTY_NEWLINE);
1684 return CMD_WARNING;
1685 }
1686
1687 if (ri->key_chain)
1688 {
1689 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1690 return CMD_WARNING;
1691 }
1692
1693 if (ri->auth_str)
1694 free (ri->auth_str);
1695
1696 ri->auth_str = strdup (argv[0]);
1697
1698 return CMD_SUCCESS;
1699}
1700
1701DEFUN (no_ip_rip_authentication_string,
1702 no_ip_rip_authentication_string_cmd,
1703 "no ip rip authentication string",
1704 NO_STR
1705 IP_STR
1706 "Routing Information Protocol\n"
1707 "Authentication control\n"
1708 "Authentication string\n")
1709{
1710 struct interface *ifp;
1711 struct rip_interface *ri;
1712
1713 ifp = (struct interface *)vty->index;
1714 ri = ifp->info;
1715
1716 if (ri->auth_str)
1717 free (ri->auth_str);
1718
1719 ri->auth_str = NULL;
1720
1721 return CMD_SUCCESS;
1722}
1723
1724ALIAS (no_ip_rip_authentication_string,
1725 no_ip_rip_authentication_string2_cmd,
1726 "no ip rip authentication string LINE",
1727 NO_STR
1728 IP_STR
1729 "Routing Information Protocol\n"
1730 "Authentication control\n"
1731 "Authentication string\n"
1732 "Authentication string\n")
1733
1734DEFUN (ip_rip_authentication_key_chain,
1735 ip_rip_authentication_key_chain_cmd,
1736 "ip rip authentication key-chain LINE",
1737 IP_STR
1738 "Routing Information Protocol\n"
1739 "Authentication control\n"
1740 "Authentication key-chain\n"
1741 "name of key-chain\n")
1742{
1743 struct interface *ifp;
1744 struct rip_interface *ri;
1745
1746 ifp = (struct interface *) vty->index;
1747 ri = ifp->info;
1748
1749 if (ri->auth_str)
1750 {
1751 vty_out (vty, "%% authentication string configuration exists%s",
1752 VTY_NEWLINE);
1753 return CMD_WARNING;
1754 }
1755
1756 if (ri->key_chain)
1757 free (ri->key_chain);
1758
1759 ri->key_chain = strdup (argv[0]);
1760
1761 return CMD_SUCCESS;
1762}
1763
1764DEFUN (no_ip_rip_authentication_key_chain,
1765 no_ip_rip_authentication_key_chain_cmd,
1766 "no ip rip authentication key-chain",
1767 NO_STR
1768 IP_STR
1769 "Routing Information Protocol\n"
1770 "Authentication control\n"
1771 "Authentication key-chain\n")
1772{
1773 struct interface *ifp;
1774 struct rip_interface *ri;
1775
1776 ifp = (struct interface *) vty->index;
1777 ri = ifp->info;
1778
1779 if (ri->key_chain)
1780 free (ri->key_chain);
1781
1782 ri->key_chain = NULL;
1783
1784 return CMD_SUCCESS;
1785}
1786
1787ALIAS (no_ip_rip_authentication_key_chain,
1788 no_ip_rip_authentication_key_chain2_cmd,
1789 "no ip rip authentication key-chain LINE",
1790 NO_STR
1791 IP_STR
1792 "Routing Information Protocol\n"
1793 "Authentication control\n"
1794 "Authentication key-chain\n"
1795 "name of key-chain\n")
1796
hasso16705132003-05-25 14:49:19 +00001797/* CHANGED: ip rip split-horizon
1798 Cisco and Zebra's command is
1799 ip split-horizon
1800 */
1801DEFUN (ip_rip_split_horizon,
1802 ip_rip_split_horizon_cmd,
1803 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001804 IP_STR
hasso16705132003-05-25 14:49:19 +00001805 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001806 "Perform split horizon\n")
1807{
1808 struct interface *ifp;
1809 struct rip_interface *ri;
1810
1811 ifp = vty->index;
1812 ri = ifp->info;
1813
hasso16705132003-05-25 14:49:19 +00001814 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001815 return CMD_SUCCESS;
1816}
1817
hasso16705132003-05-25 14:49:19 +00001818DEFUN (ip_rip_split_horizon_poisoned_reverse,
1819 ip_rip_split_horizon_poisoned_reverse_cmd,
1820 "ip rip split-horizon poisoned-reverse",
1821 IP_STR
1822 "Routing Information Protocol\n"
1823 "Perform split horizon\n"
1824 "With poisoned-reverse\n")
1825{
1826 struct interface *ifp;
1827 struct rip_interface *ri;
1828
1829 ifp = vty->index;
1830 ri = ifp->info;
1831
1832 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1833 return CMD_SUCCESS;
1834}
1835
1836/* CHANGED: no ip rip split-horizon
1837 Cisco and Zebra's command is
1838 no ip split-horizon
1839 */
1840DEFUN (no_ip_rip_split_horizon,
1841 no_ip_rip_split_horizon_cmd,
1842 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001843 NO_STR
1844 IP_STR
hasso16705132003-05-25 14:49:19 +00001845 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001846 "Perform split horizon\n")
1847{
1848 struct interface *ifp;
1849 struct rip_interface *ri;
1850
1851 ifp = vty->index;
1852 ri = ifp->info;
1853
hasso16705132003-05-25 14:49:19 +00001854 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001855 return CMD_SUCCESS;
1856}
1857
vincentfac3e842005-10-06 07:45:43 +00001858DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001859 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1860 "no ip rip split-horizon poisoned-reverse",
1861 NO_STR
1862 IP_STR
1863 "Routing Information Protocol\n"
1864 "Perform split horizon\n"
1865 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001866{
1867 struct interface *ifp;
1868 struct rip_interface *ri;
1869
1870 ifp = vty->index;
1871 ri = ifp->info;
1872
1873 switch( ri->split_horizon )
1874 {
1875 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1876 ri->split_horizon = RIP_SPLIT_HORIZON;
1877 default:
1878 break;
1879 }
1880
1881 return CMD_SUCCESS;
1882}
hasso16705132003-05-25 14:49:19 +00001883
paul718e3742002-12-13 20:15:29 +00001884DEFUN (rip_passive_interface,
1885 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001886 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001887 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001888 "Interface name\n"
1889 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001890{
hasso98b718a2004-10-11 12:57:57 +00001891 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001892
1893 if (!strcmp(ifname,"default")) {
1894 passive_default = 1;
1895 rip_passive_nondefault_clean();
1896 return CMD_SUCCESS;
1897 }
1898 if (passive_default)
1899 return rip_passive_nondefault_unset (vty, ifname);
1900 else
1901 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001902}
1903
1904DEFUN (no_rip_passive_interface,
1905 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001906 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001907 NO_STR
1908 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001909 "Interface name\n"
1910 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001911{
hasso98b718a2004-10-11 12:57:57 +00001912 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001913
1914 if (!strcmp(ifname,"default")) {
1915 passive_default = 0;
1916 rip_passive_nondefault_clean();
1917 return CMD_SUCCESS;
1918 }
1919 if (passive_default)
1920 return rip_passive_nondefault_set (vty, ifname);
1921 else
1922 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001923}
1924
1925/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001926static int
paul718e3742002-12-13 20:15:29 +00001927rip_interface_config_write (struct vty *vty)
1928{
hasso52dc7ee2004-09-23 19:18:23 +00001929 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001930 struct interface *ifp;
1931
paul1eb8ef22005-04-07 07:30:20 +00001932 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001933 {
1934 struct rip_interface *ri;
1935
paul718e3742002-12-13 20:15:29 +00001936 ri = ifp->info;
1937
hasso16705132003-05-25 14:49:19 +00001938 /* Do not display the interface if there is no
1939 * configuration about it.
1940 **/
1941 if ((!ifp->desc) &&
1942 (ri->split_horizon == ri->split_horizon_default) &&
1943 (ri->ri_send == RI_RIP_UNSPEC) &&
1944 (ri->ri_receive == RI_RIP_UNSPEC) &&
1945 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001946 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001947 (!ri->auth_str) &&
1948 (!ri->key_chain) )
1949 continue;
1950
paul718e3742002-12-13 20:15:29 +00001951 vty_out (vty, "interface %s%s", ifp->name,
1952 VTY_NEWLINE);
1953
1954 if (ifp->desc)
1955 vty_out (vty, " description %s%s", ifp->desc,
1956 VTY_NEWLINE);
1957
1958 /* Split horizon. */
1959 if (ri->split_horizon != ri->split_horizon_default)
1960 {
hasso16705132003-05-25 14:49:19 +00001961 switch (ri->split_horizon) {
1962 case RIP_SPLIT_HORIZON:
1963 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1964 break;
1965 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1966 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1967 VTY_NEWLINE);
1968 break;
1969 case RIP_NO_SPLIT_HORIZON:
1970 default:
1971 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1972 break;
1973 }
paul718e3742002-12-13 20:15:29 +00001974 }
1975
1976 /* RIP version setting. */
1977 if (ri->ri_send != RI_RIP_UNSPEC)
1978 vty_out (vty, " ip rip send version %s%s",
1979 lookup (ri_version_msg, ri->ri_send),
1980 VTY_NEWLINE);
1981
1982 if (ri->ri_receive != RI_RIP_UNSPEC)
1983 vty_out (vty, " ip rip receive version %s%s",
1984 lookup (ri_version_msg, ri->ri_receive),
1985 VTY_NEWLINE);
1986
1987 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001988 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1989 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001990
paul718e3742002-12-13 20:15:29 +00001991 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001992 {
1993 vty_out (vty, " ip rip authentication mode md5");
1994 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1995 vty_out (vty, " auth-length old-ripd");
1996 else
1997 vty_out (vty, " auth-length rfc");
1998 vty_out (vty, "%s", VTY_NEWLINE);
1999 }
paul718e3742002-12-13 20:15:29 +00002000
2001 if (ri->auth_str)
2002 vty_out (vty, " ip rip authentication string %s%s",
2003 ri->auth_str, VTY_NEWLINE);
2004
2005 if (ri->key_chain)
2006 vty_out (vty, " ip rip authentication key-chain %s%s",
2007 ri->key_chain, VTY_NEWLINE);
2008
2009 vty_out (vty, "!%s", VTY_NEWLINE);
2010 }
2011 return 0;
2012}
2013
2014int
2015config_write_rip_network (struct vty *vty, int config_mode)
2016{
hasso8a676be2004-10-08 06:36:38 +00002017 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002018 char *ifname;
2019 struct route_node *node;
2020
2021 /* Network type RIP enable interface statement. */
2022 for (node = route_top (rip_enable_network); node; node = route_next (node))
2023 if (node->info)
2024 vty_out (vty, "%s%s/%d%s",
2025 config_mode ? " network " : " ",
2026 inet_ntoa (node->p.u.prefix4),
2027 node->p.prefixlen,
2028 VTY_NEWLINE);
2029
2030 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002031 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002032 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2033 vty_out (vty, "%s%s%s",
2034 config_mode ? " network " : " ",
2035 ifname,
2036 VTY_NEWLINE);
2037
2038 /* RIP neighbors listing. */
2039 for (node = route_top (rip->neighbor); node; node = route_next (node))
2040 if (node->info)
2041 vty_out (vty, "%s%s%s",
2042 config_mode ? " neighbor " : " ",
2043 inet_ntoa (node->p.u.prefix4),
2044 VTY_NEWLINE);
2045
2046 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002047 if (config_mode) {
2048 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002049 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002050 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002051 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2052 vty_out (vty, " %spassive-interface %s%s",
2053 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2054 }
paul718e3742002-12-13 20:15:29 +00002055
2056 return 0;
2057}
2058
2059struct cmd_node interface_node =
2060{
2061 INTERFACE_NODE,
2062 "%s(config-if)# ",
2063 1,
2064};
2065
2066/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002067static int
paul718e3742002-12-13 20:15:29 +00002068rip_interface_new_hook (struct interface *ifp)
2069{
2070 ifp->info = rip_interface_new ();
2071 return 0;
2072}
2073
2074/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002075static int
paul718e3742002-12-13 20:15:29 +00002076rip_interface_delete_hook (struct interface *ifp)
2077{
2078 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002079 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002080 return 0;
2081}
2082
2083/* Allocate and initialize interface vector. */
2084void
pauldc63bfd2005-10-25 23:31:05 +00002085rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002086{
2087 /* Default initial size of interface vector. */
2088 if_init();
2089 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2090 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2091
2092 /* RIP network init. */
2093 rip_enable_interface = vector_init (1);
2094 rip_enable_network = route_table_init ();
2095
2096 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002097 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002098
2099 /* Install interface node. */
2100 install_node (&interface_node, rip_interface_config_write);
2101
2102 /* Install commands. */
2103 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002104 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002105 install_default (INTERFACE_NODE);
2106 install_element (INTERFACE_NODE, &interface_desc_cmd);
2107 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2108 install_element (RIP_NODE, &rip_network_cmd);
2109 install_element (RIP_NODE, &no_rip_network_cmd);
2110 install_element (RIP_NODE, &rip_neighbor_cmd);
2111 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2112
2113 install_element (RIP_NODE, &rip_passive_interface_cmd);
2114 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2115
2116 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2117 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2118 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2119 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2120 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2121
2122 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2123 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2124 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2125 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2126 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2127
2128 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002129 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002130 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2131 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002132 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002133
2134 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2135 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2136 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2137
2138 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2139 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2140 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2141
hasso16705132003-05-25 14:49:19 +00002142 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2143 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2144 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2145 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002146}