blob: 827663ac7bebd8932675d1ec7e6d5d1e82838b2f [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"},
paul718e3742002-12-13 20:15:29 +000058};
59
pauledd7c242003-06-04 13:59:38 +000060extern struct zebra_privs_t ripd_privs;
61
paul718e3742002-12-13 20:15:29 +000062/* RIP enabled network vector. */
63vector rip_enable_interface;
64
65/* RIP enabled interface table. */
66struct route_table *rip_enable_network;
67
68/* Vector to store passive-interface name. */
paul4aaff3f2003-06-07 01:04:45 +000069static int passive_default; /* are we in passive-interface default mode? */
70vector Vrip_passive_nondefault;
paul718e3742002-12-13 20:15:29 +000071
72/* Join to the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000073static int
paul718e3742002-12-13 20:15:29 +000074ipv4_multicast_join (int sock,
75 struct in_addr group,
76 struct in_addr ifa,
77 unsigned int ifindex)
78{
79 int ret;
80
81 ret = setsockopt_multicast_ipv4 (sock,
82 IP_ADD_MEMBERSHIP,
83 ifa,
84 group.s_addr,
85 ifindex);
86
87 if (ret < 0)
88 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
ajs6099b3b2004-11-20 02:06:59 +000089 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +000090
91 return ret;
92}
93
94/* Leave from the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000095static int
paul718e3742002-12-13 20:15:29 +000096ipv4_multicast_leave (int sock,
97 struct in_addr group,
98 struct in_addr ifa,
99 unsigned int ifindex)
100{
101 int ret;
102
103 ret = setsockopt_multicast_ipv4 (sock,
104 IP_DROP_MEMBERSHIP,
105 ifa,
106 group.s_addr,
107 ifindex);
108
109 if (ret < 0)
110 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
111
112 return ret;
113}
114
115/* Allocate new RIP's interface configuration. */
pauldc63bfd2005-10-25 23:31:05 +0000116static struct rip_interface *
117rip_interface_new (void)
paul718e3742002-12-13 20:15:29 +0000118{
119 struct rip_interface *ri;
120
Stephen Hemminger393deb92008-08-18 14:13:29 -0700121 ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
paul718e3742002-12-13 20:15:29 +0000122
123 /* Default authentication type is simple password for Cisco
124 compatibility. */
paul7755a8c2005-06-02 08:20:53 +0000125 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +0000126 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +0000127
128 /* Set default split-horizon behavior. If the interface is Frame
129 Relay or SMDS is enabled, the default value for split-horizon is
130 off. But currently Zebra does detect Frame Relay or SMDS
131 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000132 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000133 ri->split_horizon = ri->split_horizon_default;
134
135 return ri;
136}
137
138void
paul1a517862004-08-19 04:03:08 +0000139rip_interface_multicast_set (int sock, struct connected *connected)
paul718e3742002-12-13 20:15:29 +0000140{
hasso3fb9cd62004-10-19 19:44:43 +0000141 struct in_addr addr;
paulc49ad8f2004-10-22 10:27:28 +0000142
143 assert (connected != NULL);
144
Andrew J. Schorre4529632006-12-12 19:18:21 +0000145 addr = CONNECTED_ID(connected)->u.prefix4;
paul718e3742002-12-13 20:15:29 +0000146
paul1a517862004-08-19 04:03:08 +0000147 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
148 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000149 {
150 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
151 "source address %s for interface %s",
152 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000153 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000154 }
paul2c61ae32005-08-16 15:22:14 +0000155
hasso3fb9cd62004-10-19 19:44:43 +0000156 return;
157}
paul718e3742002-12-13 20:15:29 +0000158
159/* Send RIP request packet to specified interface. */
pauldc63bfd2005-10-25 23:31:05 +0000160static void
paul718e3742002-12-13 20:15:29 +0000161rip_request_interface_send (struct interface *ifp, u_char version)
162{
163 struct sockaddr_in to;
164
165 /* RIPv2 support multicast. */
166 if (version == RIPv2 && if_is_multicast (ifp))
167 {
168
169 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000170 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000171
paul931cd542004-01-23 15:31:42 +0000172 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000173 return;
174 }
175
176 /* RIPv1 and non multicast interface. */
177 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
178 {
paul1eb8ef22005-04-07 07:30:20 +0000179 struct listnode *cnode, *cnnode;
180 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000181
182 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000183 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000184
paul1eb8ef22005-04-07 07:30:20 +0000185 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000186 {
hasso3fb9cd62004-10-19 19:44:43 +0000187 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000188 {
189 memset (&to, 0, sizeof (struct sockaddr_in));
190 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000191 if (connected->destination)
Andrew J. Schorre4529632006-12-12 19:18:21 +0000192 /* use specified broadcast or peer destination addr */
hasso3fb9cd62004-10-19 19:44:43 +0000193 to.sin_addr = connected->destination->u.prefix4;
Andrew J. Schorre4529632006-12-12 19:18:21 +0000194 else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
hasso3fb9cd62004-10-19 19:44:43 +0000195 /* calculate the appropriate broadcast address */
196 to.sin_addr.s_addr =
197 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
198 connected->address->prefixlen);
Andrew J. Schorre4529632006-12-12 19:18:21 +0000199 else
200 /* do not know where to send the packet */
201 continue;
paul718e3742002-12-13 20:15:29 +0000202
paul718e3742002-12-13 20:15:29 +0000203 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000204 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000205
paul931cd542004-01-23 15:31:42 +0000206 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000207 }
208 }
209 }
210}
211
212/* This will be executed when interface goes up. */
pauldc63bfd2005-10-25 23:31:05 +0000213static void
paul718e3742002-12-13 20:15:29 +0000214rip_request_interface (struct interface *ifp)
215{
216 struct rip_interface *ri;
217
218 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
219 if (if_is_loopback (ifp))
220 return;
221
222 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000223 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000224 return;
225
226 /* Fetch RIP interface information. */
227 ri = ifp->info;
228
229
230 /* If there is no version configuration in the interface,
231 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000232 {
233 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
234 rip->version_send : ri->ri_send);
235 if (vsend & RIPv1)
236 rip_request_interface_send (ifp, RIPv1);
237 if (vsend & RIPv2)
238 rip_request_interface_send (ifp, RIPv2);
239 }
paul718e3742002-12-13 20:15:29 +0000240}
241
242/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000243static void
paul718e3742002-12-13 20:15:29 +0000244rip_request_neighbor (struct in_addr addr)
245{
246 struct sockaddr_in to;
247
248 memset (&to, 0, sizeof (struct sockaddr_in));
249 to.sin_port = htons (RIP_PORT_DEFAULT);
250 to.sin_addr = addr;
251
paul931cd542004-01-23 15:31:42 +0000252 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000253}
254
255/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000256static void
257rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000258{
259 struct route_node *rp;
260
261 if (! rip)
262 return;
263
264 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000265 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000266
267 /* Send request to all neighbor. */
268 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
269 if (rp->info)
270 rip_request_neighbor (rp->p.u.prefix4);
271}
272
273/* Multicast packet receive socket. */
pauldc63bfd2005-10-25 23:31:05 +0000274static int
paul718e3742002-12-13 20:15:29 +0000275rip_multicast_join (struct interface *ifp, int sock)
276{
hasso52dc7ee2004-09-23 19:18:23 +0000277 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000278 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000279
paul2e3b2e42002-12-13 21:03:13 +0000280 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000281 {
282 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000283 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000284
paul1eb8ef22005-04-07 07:30:20 +0000285 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000286 {
287 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000288 struct in_addr group;
289
paul1eb8ef22005-04-07 07:30:20 +0000290 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000291
292 if (p->family != AF_INET)
293 continue;
294
295 group.s_addr = htonl (INADDR_RIP_GROUP);
296 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
297 return -1;
298 else
299 return 0;
300 }
301 }
302 return 0;
303}
304
305/* Leave from multicast group. */
pauldc63bfd2005-10-25 23:31:05 +0000306static void
paul718e3742002-12-13 20:15:29 +0000307rip_multicast_leave (struct interface *ifp, int sock)
308{
hasso52dc7ee2004-09-23 19:18:23 +0000309 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000310 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000311
312 if (if_is_up (ifp) && if_is_multicast (ifp))
313 {
314 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000315 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000316
paul1eb8ef22005-04-07 07:30:20 +0000317 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000318 {
319 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000320 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000321
paul718e3742002-12-13 20:15:29 +0000322 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000323
paul718e3742002-12-13 20:15:29 +0000324 if (p->family != AF_INET)
325 continue;
326
327 group.s_addr = htonl (INADDR_RIP_GROUP);
328 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
329 return;
330 }
331 }
332}
333
334/* Is there and address on interface that I could use ? */
pauldc63bfd2005-10-25 23:31:05 +0000335static int
paul718e3742002-12-13 20:15:29 +0000336rip_if_ipv4_address_check (struct interface *ifp)
337{
338 struct listnode *nn;
339 struct connected *connected;
340 int count = 0;
341
paul1eb8ef22005-04-07 07:30:20 +0000342 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
343 {
344 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000345
paul1eb8ef22005-04-07 07:30:20 +0000346 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000347
paul1eb8ef22005-04-07 07:30:20 +0000348 if (p->family == AF_INET)
349 count++;
350 }
paul718e3742002-12-13 20:15:29 +0000351
352 return count;
353}
paul31a476c2003-09-29 19:54:53 +0000354
355
356
357
358/* Does this address belongs to me ? */
359int
360if_check_address (struct in_addr addr)
361{
hasso52dc7ee2004-09-23 19:18:23 +0000362 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000363 struct interface *ifp;
364
365 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000366 {
hasso52dc7ee2004-09-23 19:18:23 +0000367 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000368 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000369
paul1eb8ef22005-04-07 07:30:20 +0000370 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000371 {
paul31a476c2003-09-29 19:54:53 +0000372 struct prefix_ipv4 *p;
373
paul31a476c2003-09-29 19:54:53 +0000374 p = (struct prefix_ipv4 *) connected->address;
375
376 if (p->family != AF_INET)
377 continue;
378
379 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
380 return 1;
381 }
382 }
383 return 0;
384}
385
paul718e3742002-12-13 20:15:29 +0000386/* Inteface link down message processing. */
387int
388rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
389{
390 struct interface *ifp;
391 struct stream *s;
392
393 s = zclient->ibuf;
394
395 /* zebra_interface_state_read() updates interface structure in
396 iflist. */
397 ifp = zebra_interface_state_read(s);
398
399 if (ifp == NULL)
400 return 0;
401
402 rip_if_down(ifp);
403
404 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000405 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000406 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
407
408 return 0;
409}
410
411/* Inteface link up message processing */
412int
413rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
414{
415 struct interface *ifp;
416
417 /* zebra_interface_state_read () updates interface structure in
418 iflist. */
419 ifp = zebra_interface_state_read (zclient->ibuf);
420
421 if (ifp == NULL)
422 return 0;
423
424 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000425 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000426 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
427
428 /* Check if this interface is RIP enabled or not.*/
429 rip_enable_apply (ifp);
430
431 /* Check for a passive interface */
432 rip_passive_interface_apply (ifp);
433
434 /* Apply distribute list to the all interface. */
435 rip_distribute_update_interface (ifp);
436
437 return 0;
438}
439
440/* Inteface addition message from zebra. */
441int
442rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
443{
444 struct interface *ifp;
445
446 ifp = zebra_interface_add_read (zclient->ibuf);
447
448 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000449 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000450 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
451
452 /* Check if this interface is RIP enabled or not.*/
453 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000454
455 /* Check for a passive interface */
456 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000457
458 /* Apply distribute list to the all interface. */
459 rip_distribute_update_interface (ifp);
460
461 /* rip_request_neighbor_all (); */
462
hasso16705132003-05-25 14:49:19 +0000463 /* Check interface routemap. */
464 rip_if_rmap_update_interface (ifp);
465
paul718e3742002-12-13 20:15:29 +0000466 return 0;
467}
468
469int
470rip_interface_delete (int command, struct zclient *zclient,
471 zebra_size_t length)
472{
473 struct interface *ifp;
474 struct stream *s;
475
476
477 s = zclient->ibuf;
478 /* zebra_interface_state_read() updates interface structure in iflist */
479 ifp = zebra_interface_state_read(s);
480
481 if (ifp == NULL)
482 return 0;
483
484 if (if_is_up (ifp)) {
485 rip_if_down(ifp);
486 }
487
488 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
489 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
490
491 /* To support pseudo interface do not free interface structure. */
492 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000493 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000494
495 return 0;
496}
497
498void
pauldc63bfd2005-10-25 23:31:05 +0000499rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000500{
hasso52dc7ee2004-09-23 19:18:23 +0000501 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000502 struct interface *ifp;
503 struct rip_interface *ri;
504
paul1eb8ef22005-04-07 07:30:20 +0000505 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000506 {
paul718e3742002-12-13 20:15:29 +0000507 ri = ifp->info;
508
509 ri->enable_network = 0;
510 ri->enable_interface = 0;
511 ri->running = 0;
512
513 if (ri->t_wakeup)
514 {
515 thread_cancel (ri->t_wakeup);
516 ri->t_wakeup = NULL;
517 }
518 }
519}
520
521void
pauldc63bfd2005-10-25 23:31:05 +0000522rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000523{
hasso52dc7ee2004-09-23 19:18:23 +0000524 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000525 struct interface *ifp;
526 struct rip_interface *ri;
527
paul1eb8ef22005-04-07 07:30:20 +0000528 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000529 {
paul718e3742002-12-13 20:15:29 +0000530 ri = ifp->info;
531
532 ri->enable_network = 0;
533 ri->enable_interface = 0;
534 ri->running = 0;
535
536 ri->ri_send = RI_RIP_UNSPEC;
537 ri->ri_receive = RI_RIP_UNSPEC;
538
paul7755a8c2005-06-02 08:20:53 +0000539 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000540
541 if (ri->auth_str)
542 {
543 free (ri->auth_str);
544 ri->auth_str = NULL;
545 }
546 if (ri->key_chain)
547 {
548 free (ri->key_chain);
549 ri->key_chain = NULL;
550 }
551
hasso16705132003-05-25 14:49:19 +0000552 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
553 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000554
555 ri->list[RIP_FILTER_IN] = NULL;
556 ri->list[RIP_FILTER_OUT] = NULL;
557
558 ri->prefix[RIP_FILTER_IN] = NULL;
559 ri->prefix[RIP_FILTER_OUT] = NULL;
560
561 if (ri->t_wakeup)
562 {
563 thread_cancel (ri->t_wakeup);
564 ri->t_wakeup = NULL;
565 }
566
567 ri->recv_badpackets = 0;
568 ri->recv_badroutes = 0;
569 ri->sent_updates = 0;
570
571 ri->passive = 0;
572 }
573}
574
575int
576rip_if_down(struct interface *ifp)
577{
578 struct route_node *rp;
579 struct rip_info *rinfo;
580 struct rip_interface *ri = NULL;
581 if (rip)
582 {
583 for (rp = route_top (rip->table); rp; rp = route_next (rp))
584 if ((rinfo = rp->info) != NULL)
585 {
586 /* Routes got through this interface. */
587 if (rinfo->ifindex == ifp->ifindex &&
588 rinfo->type == ZEBRA_ROUTE_RIP &&
589 rinfo->sub_type == RIP_ROUTE_RTE)
590 {
591 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
592 &rinfo->nexthop,
Krisztian Kovacsc5a89ff2009-06-02 18:09:48 +0100593 rinfo->metric);
paul718e3742002-12-13 20:15:29 +0000594
595 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
596 (struct prefix_ipv4 *)&rp->p,
597 rinfo->ifindex);
598 }
599 else
600 {
601 /* All redistributed routes but static and system */
602 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000603 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000604 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
605 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
606 (struct prefix_ipv4 *)&rp->p,
607 rinfo->ifindex);
608 }
609 }
610 }
611
612 ri = ifp->info;
613
614 if (ri->running)
615 {
616 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000617 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000618
619 /* Leave from multicast group. */
620 rip_multicast_leave (ifp, rip->sock);
621
622 ri->running = 0;
623 }
624
625 return 0;
626}
627
628/* Needed for stop RIP process. */
629void
630rip_if_down_all ()
631{
632 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000633 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000634
paul1eb8ef22005-04-07 07:30:20 +0000635 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
636 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000637}
638
hasso16705132003-05-25 14:49:19 +0000639static void
pauldc63bfd2005-10-25 23:31:05 +0000640rip_apply_address_add (struct connected *ifc)
641{
hasso16705132003-05-25 14:49:19 +0000642 struct prefix_ipv4 address;
643 struct prefix *p;
644
645 if (!rip)
646 return;
647
648 if (! if_is_up(ifc->ifp))
649 return;
650
651 p = ifc->address;
652
653 memset (&address, 0, sizeof (address));
654 address.family = p->family;
655 address.prefix = p->u.prefix4;
656 address.prefixlen = p->prefixlen;
657 apply_mask_ipv4(&address);
658
659 /* Check if this interface is RIP enabled or not
660 or Check if this address's prefix is RIP enabled */
661 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
662 (rip_enable_network_lookup2(ifc) >= 0))
663 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000664 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000665
666}
667
paul718e3742002-12-13 20:15:29 +0000668int
669rip_interface_address_add (int command, struct zclient *zclient,
670 zebra_size_t length)
671{
672 struct connected *ifc;
673 struct prefix *p;
674
paul0a589352004-05-08 11:48:26 +0000675 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
676 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000677
678 if (ifc == NULL)
679 return 0;
680
681 p = ifc->address;
682
683 if (p->family == AF_INET)
684 {
685 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000686 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000687 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000688
paul878ef2e2003-09-23 23:41:50 +0000689 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000690 /* Check if this prefix needs to be redistributed */
691 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000692
693#ifdef HAVE_SNMP
694 rip_ifaddr_add (ifc->ifp, ifc);
695#endif /* HAVE_SNMP */
696 }
697
698 return 0;
699}
700
hasso16705132003-05-25 14:49:19 +0000701static void
702rip_apply_address_del (struct connected *ifc) {
703 struct prefix_ipv4 address;
704 struct prefix *p;
705
706 if (!rip)
707 return;
708
709 if (! if_is_up(ifc->ifp))
710 return;
711
712 p = ifc->address;
713
714 memset (&address, 0, sizeof (address));
715 address.family = p->family;
716 address.prefix = p->u.prefix4;
717 address.prefixlen = p->prefixlen;
718 apply_mask_ipv4(&address);
719
720 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
721 &address, ifc->ifp->ifindex);
722}
723
paul718e3742002-12-13 20:15:29 +0000724int
725rip_interface_address_delete (int command, struct zclient *zclient,
726 zebra_size_t length)
727{
728 struct connected *ifc;
729 struct prefix *p;
730
paul0a589352004-05-08 11:48:26 +0000731 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
732 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000733
734 if (ifc)
735 {
736 p = ifc->address;
737 if (p->family == AF_INET)
738 {
739 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000740 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000741 inet_ntoa (p->u.prefix4), p->prefixlen);
742
743#ifdef HAVE_SNMP
744 rip_ifaddr_delete (ifc->ifp, ifc);
745#endif /* HAVE_SNMP */
746
hasso16705132003-05-25 14:49:19 +0000747 /* Chech wether this prefix needs to be removed */
748 rip_apply_address_del(ifc);
749
paul718e3742002-12-13 20:15:29 +0000750 }
751
752 connected_free (ifc);
753
754 }
755
756 return 0;
757}
758
759/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000760/* Check wether the interface has at least a connected prefix that
761 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000762static int
hasso16705132003-05-25 14:49:19 +0000763rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000764{
paul1eb8ef22005-04-07 07:30:20 +0000765 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000766 struct connected *connected;
767 struct prefix_ipv4 address;
768
paul1eb8ef22005-04-07 07:30:20 +0000769 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
770 {
771 struct prefix *p;
772 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000773
paul1eb8ef22005-04-07 07:30:20 +0000774 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000775
paul1eb8ef22005-04-07 07:30:20 +0000776 if (p->family == AF_INET)
777 {
778 address.family = AF_INET;
779 address.prefix = p->u.prefix4;
780 address.prefixlen = IPV4_MAX_BITLEN;
781
782 node = route_node_match (rip_enable_network,
783 (struct prefix *)&address);
784 if (node)
785 {
786 route_unlock_node (node);
787 return 1;
788 }
789 }
790 }
paul718e3742002-12-13 20:15:29 +0000791 return -1;
792}
793
hasso16705132003-05-25 14:49:19 +0000794/* Check wether connected is within the ripng_enable_network table. */
795int
796rip_enable_network_lookup2 (struct connected *connected)
797{
798 struct prefix_ipv4 address;
799 struct prefix *p;
800
801 p = connected->address;
802
803 if (p->family == AF_INET) {
804 struct route_node *node;
805
806 address.family = p->family;
807 address.prefix = p->u.prefix4;
808 address.prefixlen = IPV4_MAX_BITLEN;
809
810 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
811 node = route_node_match (rip_enable_network,
812 (struct prefix *)&address);
813
814 if (node) {
815 route_unlock_node (node);
816 return 1;
817 }
818 }
819
820 return -1;
821}
paul718e3742002-12-13 20:15:29 +0000822/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000823static int
paul718e3742002-12-13 20:15:29 +0000824rip_enable_network_add (struct prefix *p)
825{
826 struct route_node *node;
827
828 node = route_node_get (rip_enable_network, p);
829
830 if (node->info)
831 {
832 route_unlock_node (node);
833 return -1;
834 }
835 else
hasso8a676be2004-10-08 06:36:38 +0000836 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000837
hasso16705132003-05-25 14:49:19 +0000838 /* XXX: One should find a better solution than a generic one */
839 rip_enable_apply_all();
840
paul718e3742002-12-13 20:15:29 +0000841 return 1;
842}
843
844/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000845static int
paul718e3742002-12-13 20:15:29 +0000846rip_enable_network_delete (struct prefix *p)
847{
848 struct route_node *node;
849
850 node = route_node_lookup (rip_enable_network, p);
851 if (node)
852 {
853 node->info = NULL;
854
855 /* Unlock info lock. */
856 route_unlock_node (node);
857
858 /* Unlock lookup lock. */
859 route_unlock_node (node);
860
hasso16705132003-05-25 14:49:19 +0000861 /* XXX: One should find a better solution than a generic one */
862 rip_enable_apply_all ();
863
paul718e3742002-12-13 20:15:29 +0000864 return 1;
865 }
866 return -1;
867}
868
869/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000870static int
hasso98b718a2004-10-11 12:57:57 +0000871rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000872{
hasso8a676be2004-10-08 06:36:38 +0000873 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000874 char *str;
875
paul55468c82005-03-14 20:19:01 +0000876 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000877 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
878 if (strcmp (str, ifname) == 0)
879 return i;
880 return -1;
881}
882
883/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000884static int
hasso98b718a2004-10-11 12:57:57 +0000885rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000886{
887 int ret;
888
889 ret = rip_enable_if_lookup (ifname);
890 if (ret >= 0)
891 return -1;
892
893 vector_set (rip_enable_interface, strdup (ifname));
894
hasso16705132003-05-25 14:49:19 +0000895 rip_enable_apply_all(); /* TODOVJ */
896
paul718e3742002-12-13 20:15:29 +0000897 return 1;
898}
899
900/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000901static int
hasso98b718a2004-10-11 12:57:57 +0000902rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000903{
904 int index;
905 char *str;
906
907 index = rip_enable_if_lookup (ifname);
908 if (index < 0)
909 return -1;
910
911 str = vector_slot (rip_enable_interface, index);
912 free (str);
913 vector_unset (rip_enable_interface, index);
914
hasso16705132003-05-25 14:49:19 +0000915 rip_enable_apply_all(); /* TODOVJ */
916
paul718e3742002-12-13 20:15:29 +0000917 return 1;
918}
919
920/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000921static int
paul718e3742002-12-13 20:15:29 +0000922rip_interface_wakeup (struct thread *t)
923{
924 struct interface *ifp;
925 struct rip_interface *ri;
926
927 /* Get interface. */
928 ifp = THREAD_ARG (t);
929
930 ri = ifp->info;
931 ri->t_wakeup = NULL;
932
933 /* Join to multicast group. */
934 if (rip_multicast_join (ifp, rip->sock) < 0)
935 {
936 zlog_err ("multicast join failed, interface %s not running", ifp->name);
937 return 0;
938 }
939
940 /* Set running flag. */
941 ri->running = 1;
942
943 /* Send RIP request to the interface. */
944 rip_request_interface (ifp);
945
946 return 0;
947}
948
949int rip_redistribute_check (int);
950
pauldc63bfd2005-10-25 23:31:05 +0000951static void
paul718e3742002-12-13 20:15:29 +0000952rip_connect_set (struct interface *ifp, int set)
953{
paul1eb8ef22005-04-07 07:30:20 +0000954 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000955 struct connected *connected;
956 struct prefix_ipv4 address;
957
paul1eb8ef22005-04-07 07:30:20 +0000958 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
959 {
960 struct prefix *p;
961 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000962
paul1eb8ef22005-04-07 07:30:20 +0000963 if (p->family != AF_INET)
964 continue;
paul718e3742002-12-13 20:15:29 +0000965
paul1eb8ef22005-04-07 07:30:20 +0000966 address.family = AF_INET;
967 address.prefix = p->u.prefix4;
968 address.prefixlen = p->prefixlen;
969 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000970
paul1eb8ef22005-04-07 07:30:20 +0000971 if (set) {
972 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
973 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
974 (rip_enable_network_lookup2(connected) >= 0))
975 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000976 &address, connected->ifp->ifindex,
977 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000978 } else
979 {
980 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
981 &address, connected->ifp->ifindex);
982 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
983 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000984 &address, connected->ifp->ifindex,
985 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000986 }
987 }
paul718e3742002-12-13 20:15:29 +0000988}
989
990/* Update interface status. */
991void
992rip_enable_apply (struct interface *ifp)
993{
994 int ret;
995 struct rip_interface *ri = NULL;
996
997 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +0000998 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000999 return;
1000
1001 ri = ifp->info;
1002
1003 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001004 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001005
1006 /* If the interface is matched. */
1007 if (ret > 0)
1008 ri->enable_network = 1;
1009 else
1010 ri->enable_network = 0;
1011
1012 /* Check interface name configuration. */
1013 ret = rip_enable_if_lookup (ifp->name);
1014 if (ret >= 0)
1015 ri->enable_interface = 1;
1016 else
1017 ri->enable_interface = 0;
1018
1019 /* any interface MUST have an IPv4 address */
1020 if ( ! rip_if_ipv4_address_check (ifp) )
1021 {
1022 ri->enable_network = 0;
1023 ri->enable_interface = 0;
1024 }
1025
1026 /* Update running status of the interface. */
1027 if (ri->enable_network || ri->enable_interface)
1028 {
paul718e3742002-12-13 20:15:29 +00001029 {
1030 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001031 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001032
1033 /* Add interface wake up thread. */
1034 if (! ri->t_wakeup)
1035 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1036 ifp, 1);
1037 rip_connect_set (ifp, 1);
1038 }
1039 }
1040 else
1041 {
1042 if (ri->running)
1043 {
hasso16705132003-05-25 14:49:19 +00001044 /* Might as well clean up the route table as well
1045 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1046 **/
paul718e3742002-12-13 20:15:29 +00001047 rip_if_down(ifp);
1048
paul718e3742002-12-13 20:15:29 +00001049 rip_connect_set (ifp, 0);
1050 }
1051 }
1052}
1053
1054/* Apply network configuration to all interface. */
1055void
1056rip_enable_apply_all ()
1057{
1058 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001059 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001060
1061 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001062 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1063 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001064}
1065
1066int
1067rip_neighbor_lookup (struct sockaddr_in *from)
1068{
1069 struct prefix_ipv4 p;
1070 struct route_node *node;
1071
1072 memset (&p, 0, sizeof (struct prefix_ipv4));
1073 p.family = AF_INET;
1074 p.prefix = from->sin_addr;
1075 p.prefixlen = IPV4_MAX_BITLEN;
1076
1077 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1078 if (node)
1079 {
1080 route_unlock_node (node);
1081 return 1;
1082 }
1083 return 0;
1084}
1085
1086/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001087static int
paul718e3742002-12-13 20:15:29 +00001088rip_neighbor_add (struct prefix_ipv4 *p)
1089{
1090 struct route_node *node;
1091
1092 node = route_node_get (rip->neighbor, (struct prefix *) p);
1093
1094 if (node->info)
1095 return -1;
1096
1097 node->info = rip->neighbor;
1098
1099 return 0;
1100}
1101
1102/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001103static int
paul718e3742002-12-13 20:15:29 +00001104rip_neighbor_delete (struct prefix_ipv4 *p)
1105{
1106 struct route_node *node;
1107
1108 /* Lock for look up. */
1109 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1110 if (! node)
1111 return -1;
1112
1113 node->info = NULL;
1114
1115 /* Unlock lookup lock. */
1116 route_unlock_node (node);
1117
1118 /* Unlock real neighbor information lock. */
1119 route_unlock_node (node);
1120
1121 return 0;
1122}
1123
1124/* Clear all network and neighbor configuration. */
1125void
1126rip_clean_network ()
1127{
hasso8a676be2004-10-08 06:36:38 +00001128 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001129 char *str;
1130 struct route_node *rn;
1131
1132 /* rip_enable_network. */
1133 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1134 if (rn->info)
1135 {
1136 rn->info = NULL;
1137 route_unlock_node (rn);
1138 }
1139
1140 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001141 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001142 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1143 {
1144 free (str);
1145 vector_slot (rip_enable_interface, i) = NULL;
1146 }
1147}
1148
1149/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001150static int
hasso98b718a2004-10-11 12:57:57 +00001151rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001152{
hasso8a676be2004-10-08 06:36:38 +00001153 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001154 char *str;
1155
paul55468c82005-03-14 20:19:01 +00001156 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001157 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001158 if (strcmp (str, ifname) == 0)
1159 return i;
1160 return -1;
1161}
1162
1163void
1164rip_passive_interface_apply (struct interface *ifp)
1165{
paul718e3742002-12-13 20:15:29 +00001166 struct rip_interface *ri;
1167
1168 ri = ifp->info;
1169
paul4aaff3f2003-06-07 01:04:45 +00001170 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1171 passive_default : !passive_default);
1172
1173 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001174 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001175}
1176
pauldc63bfd2005-10-25 23:31:05 +00001177static void
1178rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001179{
1180 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001181 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001182
paul1eb8ef22005-04-07 07:30:20 +00001183 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1184 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001185}
1186
1187/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001188static int
hasso98b718a2004-10-11 12:57:57 +00001189rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001190{
paul4aaff3f2003-06-07 01:04:45 +00001191 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001192 return CMD_WARNING;
1193
paul4aaff3f2003-06-07 01:04:45 +00001194 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001195
1196 rip_passive_interface_apply_all ();
1197
1198 return CMD_SUCCESS;
1199}
1200
pauldc63bfd2005-10-25 23:31:05 +00001201static int
hasso98b718a2004-10-11 12:57:57 +00001202rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001203{
1204 int i;
1205 char *str;
1206
paul4aaff3f2003-06-07 01:04:45 +00001207 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001208 if (i < 0)
1209 return CMD_WARNING;
1210
paul4aaff3f2003-06-07 01:04:45 +00001211 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001212 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001213 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001214
1215 rip_passive_interface_apply_all ();
1216
1217 return CMD_SUCCESS;
1218}
1219
1220/* Free all configured RIP passive-interface settings. */
1221void
pauldc63bfd2005-10-25 23:31:05 +00001222rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001223{
hasso8a676be2004-10-08 06:36:38 +00001224 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001225 char *str;
1226
paul55468c82005-03-14 20:19:01 +00001227 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001228 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001229 {
1230 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001231 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001232 }
1233 rip_passive_interface_apply_all ();
1234}
1235
1236/* RIP enable network or interface configuration. */
1237DEFUN (rip_network,
1238 rip_network_cmd,
1239 "network (A.B.C.D/M|WORD)",
1240 "Enable routing on an IP network\n"
1241 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1242 "Interface name\n")
1243{
1244 int ret;
1245 struct prefix_ipv4 p;
1246
1247 ret = str2prefix_ipv4 (argv[0], &p);
1248
1249 if (ret)
1250 ret = rip_enable_network_add ((struct prefix *) &p);
1251 else
1252 ret = rip_enable_if_add (argv[0]);
1253
1254 if (ret < 0)
1255 {
1256 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1257 VTY_NEWLINE);
1258 return CMD_WARNING;
1259 }
1260
paul718e3742002-12-13 20:15:29 +00001261 return CMD_SUCCESS;
1262}
1263
1264/* RIP enable network or interface configuration. */
1265DEFUN (no_rip_network,
1266 no_rip_network_cmd,
1267 "no network (A.B.C.D/M|WORD)",
1268 NO_STR
1269 "Enable routing on an IP network\n"
1270 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1271 "Interface name\n")
1272{
1273 int ret;
1274 struct prefix_ipv4 p;
1275
1276 ret = str2prefix_ipv4 (argv[0], &p);
1277
1278 if (ret)
1279 ret = rip_enable_network_delete ((struct prefix *) &p);
1280 else
1281 ret = rip_enable_if_delete (argv[0]);
1282
1283 if (ret < 0)
1284 {
1285 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1286 VTY_NEWLINE);
1287 return CMD_WARNING;
1288 }
1289
paul718e3742002-12-13 20:15:29 +00001290 return CMD_SUCCESS;
1291}
1292
1293/* RIP neighbor configuration set. */
1294DEFUN (rip_neighbor,
1295 rip_neighbor_cmd,
1296 "neighbor A.B.C.D",
1297 "Specify a neighbor router\n"
1298 "Neighbor address\n")
1299{
1300 int ret;
1301 struct prefix_ipv4 p;
1302
1303 ret = str2prefix_ipv4 (argv[0], &p);
1304
1305 if (ret <= 0)
1306 {
1307 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1308 return CMD_WARNING;
1309 }
1310
1311 rip_neighbor_add (&p);
1312
1313 return CMD_SUCCESS;
1314}
1315
1316/* RIP neighbor configuration unset. */
1317DEFUN (no_rip_neighbor,
1318 no_rip_neighbor_cmd,
1319 "no neighbor A.B.C.D",
1320 NO_STR
1321 "Specify a neighbor router\n"
1322 "Neighbor address\n")
1323{
1324 int ret;
1325 struct prefix_ipv4 p;
1326
1327 ret = str2prefix_ipv4 (argv[0], &p);
1328
1329 if (ret <= 0)
1330 {
1331 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1332 return CMD_WARNING;
1333 }
1334
1335 rip_neighbor_delete (&p);
1336
1337 return CMD_SUCCESS;
1338}
1339
1340DEFUN (ip_rip_receive_version,
1341 ip_rip_receive_version_cmd,
1342 "ip rip receive version (1|2)",
1343 IP_STR
1344 "Routing Information Protocol\n"
1345 "Advertisement reception\n"
1346 "Version control\n"
1347 "RIP version 1\n"
1348 "RIP version 2\n")
1349{
1350 struct interface *ifp;
1351 struct rip_interface *ri;
1352
1353 ifp = (struct interface *)vty->index;
1354 ri = ifp->info;
1355
1356 /* Version 1. */
1357 if (atoi (argv[0]) == 1)
1358 {
1359 ri->ri_receive = RI_RIP_VERSION_1;
1360 return CMD_SUCCESS;
1361 }
1362 if (atoi (argv[0]) == 2)
1363 {
1364 ri->ri_receive = RI_RIP_VERSION_2;
1365 return CMD_SUCCESS;
1366 }
1367 return CMD_WARNING;
1368}
1369
1370DEFUN (ip_rip_receive_version_1,
1371 ip_rip_receive_version_1_cmd,
1372 "ip rip receive version 1 2",
1373 IP_STR
1374 "Routing Information Protocol\n"
1375 "Advertisement reception\n"
1376 "Version control\n"
1377 "RIP version 1\n"
1378 "RIP version 2\n")
1379{
1380 struct interface *ifp;
1381 struct rip_interface *ri;
1382
1383 ifp = (struct interface *)vty->index;
1384 ri = ifp->info;
1385
1386 /* Version 1 and 2. */
1387 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1388 return CMD_SUCCESS;
1389}
1390
1391DEFUN (ip_rip_receive_version_2,
1392 ip_rip_receive_version_2_cmd,
1393 "ip rip receive version 2 1",
1394 IP_STR
1395 "Routing Information Protocol\n"
1396 "Advertisement reception\n"
1397 "Version control\n"
1398 "RIP version 2\n"
1399 "RIP version 1\n")
1400{
1401 struct interface *ifp;
1402 struct rip_interface *ri;
1403
1404 ifp = (struct interface *)vty->index;
1405 ri = ifp->info;
1406
1407 /* Version 1 and 2. */
1408 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1409 return CMD_SUCCESS;
1410}
1411
1412DEFUN (no_ip_rip_receive_version,
1413 no_ip_rip_receive_version_cmd,
1414 "no ip rip receive version",
1415 NO_STR
1416 IP_STR
1417 "Routing Information Protocol\n"
1418 "Advertisement reception\n"
1419 "Version control\n")
1420{
1421 struct interface *ifp;
1422 struct rip_interface *ri;
1423
1424 ifp = (struct interface *)vty->index;
1425 ri = ifp->info;
1426
1427 ri->ri_receive = RI_RIP_UNSPEC;
1428 return CMD_SUCCESS;
1429}
1430
1431ALIAS (no_ip_rip_receive_version,
1432 no_ip_rip_receive_version_num_cmd,
1433 "no ip rip receive version (1|2)",
1434 NO_STR
1435 IP_STR
1436 "Routing Information Protocol\n"
1437 "Advertisement reception\n"
1438 "Version control\n"
1439 "Version 1\n"
1440 "Version 2\n")
1441
1442DEFUN (ip_rip_send_version,
1443 ip_rip_send_version_cmd,
1444 "ip rip send version (1|2)",
1445 IP_STR
1446 "Routing Information Protocol\n"
1447 "Advertisement transmission\n"
1448 "Version control\n"
1449 "RIP version 1\n"
1450 "RIP version 2\n")
1451{
1452 struct interface *ifp;
1453 struct rip_interface *ri;
1454
1455 ifp = (struct interface *)vty->index;
1456 ri = ifp->info;
1457
1458 /* Version 1. */
1459 if (atoi (argv[0]) == 1)
1460 {
1461 ri->ri_send = RI_RIP_VERSION_1;
1462 return CMD_SUCCESS;
1463 }
1464 if (atoi (argv[0]) == 2)
1465 {
1466 ri->ri_send = RI_RIP_VERSION_2;
1467 return CMD_SUCCESS;
1468 }
1469 return CMD_WARNING;
1470}
1471
1472DEFUN (ip_rip_send_version_1,
1473 ip_rip_send_version_1_cmd,
1474 "ip rip send version 1 2",
1475 IP_STR
1476 "Routing Information Protocol\n"
1477 "Advertisement transmission\n"
1478 "Version control\n"
1479 "RIP version 1\n"
1480 "RIP version 2\n")
1481{
1482 struct interface *ifp;
1483 struct rip_interface *ri;
1484
1485 ifp = (struct interface *)vty->index;
1486 ri = ifp->info;
1487
1488 /* Version 1 and 2. */
1489 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1490 return CMD_SUCCESS;
1491}
1492
1493DEFUN (ip_rip_send_version_2,
1494 ip_rip_send_version_2_cmd,
1495 "ip rip send version 2 1",
1496 IP_STR
1497 "Routing Information Protocol\n"
1498 "Advertisement transmission\n"
1499 "Version control\n"
1500 "RIP version 2\n"
1501 "RIP version 1\n")
1502{
1503 struct interface *ifp;
1504 struct rip_interface *ri;
1505
1506 ifp = (struct interface *)vty->index;
1507 ri = ifp->info;
1508
1509 /* Version 1 and 2. */
1510 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1511 return CMD_SUCCESS;
1512}
1513
1514DEFUN (no_ip_rip_send_version,
1515 no_ip_rip_send_version_cmd,
1516 "no ip rip send version",
1517 NO_STR
1518 IP_STR
1519 "Routing Information Protocol\n"
1520 "Advertisement transmission\n"
1521 "Version control\n")
1522{
1523 struct interface *ifp;
1524 struct rip_interface *ri;
1525
1526 ifp = (struct interface *)vty->index;
1527 ri = ifp->info;
1528
1529 ri->ri_send = RI_RIP_UNSPEC;
1530 return CMD_SUCCESS;
1531}
1532
1533ALIAS (no_ip_rip_send_version,
1534 no_ip_rip_send_version_num_cmd,
1535 "no ip rip send version (1|2)",
1536 NO_STR
1537 IP_STR
1538 "Routing Information Protocol\n"
1539 "Advertisement transmission\n"
1540 "Version control\n"
1541 "Version 1\n"
1542 "Version 2\n")
1543
1544DEFUN (ip_rip_authentication_mode,
1545 ip_rip_authentication_mode_cmd,
1546 "ip rip authentication mode (md5|text)",
1547 IP_STR
1548 "Routing Information Protocol\n"
1549 "Authentication control\n"
1550 "Authentication mode\n"
1551 "Keyed message digest\n"
1552 "Clear text authentication\n")
1553{
1554 struct interface *ifp;
1555 struct rip_interface *ri;
Paul Jakma15a2b082006-05-04 07:36:34 +00001556 int auth_type;
paul718e3742002-12-13 20:15:29 +00001557
1558 ifp = (struct interface *)vty->index;
1559 ri = ifp->info;
1560
paulca5e5162004-06-06 22:06:33 +00001561 if ( (argc < 1) || (argc > 2) )
1562 {
1563 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1564 return CMD_WARNING;
1565 }
1566
paul718e3742002-12-13 20:15:29 +00001567 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001568 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001569 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001570 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001571 else
1572 {
1573 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1574 return CMD_WARNING;
1575 }
1576
paulca5e5162004-06-06 22:06:33 +00001577 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001578 {
1579 ri->auth_type = auth_type;
1580 return CMD_SUCCESS;
1581 }
paulca5e5162004-06-06 22:06:33 +00001582
Paul Jakma15a2b082006-05-04 07:36:34 +00001583 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001584 {
1585 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1586 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001587 }
paulca5e5162004-06-06 22:06:33 +00001588
1589 if (strncmp ("r", argv[1], 1) == 0)
1590 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1591 else if (strncmp ("o", argv[1], 1) == 0)
1592 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1593 else
1594 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001595
1596 ri->auth_type = auth_type;
1597
paul718e3742002-12-13 20:15:29 +00001598 return CMD_SUCCESS;
1599}
1600
paulca5e5162004-06-06 22:06:33 +00001601ALIAS (ip_rip_authentication_mode,
1602 ip_rip_authentication_mode_authlen_cmd,
1603 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1604 IP_STR
1605 "Routing Information Protocol\n"
1606 "Authentication control\n"
1607 "Authentication mode\n"
1608 "Keyed message digest\n"
1609 "Clear text authentication\n"
1610 "MD5 authentication data length\n"
1611 "RFC compatible\n"
1612 "Old ripd compatible\n")
1613
paul718e3742002-12-13 20:15:29 +00001614DEFUN (no_ip_rip_authentication_mode,
1615 no_ip_rip_authentication_mode_cmd,
1616 "no ip rip authentication mode",
1617 NO_STR
1618 IP_STR
1619 "Routing Information Protocol\n"
1620 "Authentication control\n"
1621 "Authentication mode\n")
1622{
1623 struct interface *ifp;
1624 struct rip_interface *ri;
1625
1626 ifp = (struct interface *)vty->index;
1627 ri = ifp->info;
1628
paul7755a8c2005-06-02 08:20:53 +00001629 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001630 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001631
1632 return CMD_SUCCESS;
1633}
1634
1635ALIAS (no_ip_rip_authentication_mode,
1636 no_ip_rip_authentication_mode_type_cmd,
1637 "no ip rip authentication mode (md5|text)",
1638 NO_STR
1639 IP_STR
1640 "Routing Information Protocol\n"
1641 "Authentication control\n"
1642 "Authentication mode\n"
1643 "Keyed message digest\n"
1644 "Clear text authentication\n")
1645
paulca5e5162004-06-06 22:06:33 +00001646ALIAS (no_ip_rip_authentication_mode,
1647 no_ip_rip_authentication_mode_type_authlen_cmd,
1648 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1649 NO_STR
1650 IP_STR
1651 "Routing Information Protocol\n"
1652 "Authentication control\n"
1653 "Authentication mode\n"
1654 "Keyed message digest\n"
1655 "Clear text authentication\n"
1656 "MD5 authentication data length\n"
1657 "RFC compatible\n"
1658 "Old ripd compatible\n")
1659
paul718e3742002-12-13 20:15:29 +00001660DEFUN (ip_rip_authentication_string,
1661 ip_rip_authentication_string_cmd,
1662 "ip rip authentication string LINE",
1663 IP_STR
1664 "Routing Information Protocol\n"
1665 "Authentication control\n"
1666 "Authentication string\n"
1667 "Authentication string\n")
1668{
1669 struct interface *ifp;
1670 struct rip_interface *ri;
1671
1672 ifp = (struct interface *)vty->index;
1673 ri = ifp->info;
1674
1675 if (strlen (argv[0]) > 16)
1676 {
1677 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1678 VTY_NEWLINE);
1679 return CMD_WARNING;
1680 }
1681
1682 if (ri->key_chain)
1683 {
1684 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1685 return CMD_WARNING;
1686 }
1687
1688 if (ri->auth_str)
1689 free (ri->auth_str);
1690
1691 ri->auth_str = strdup (argv[0]);
1692
1693 return CMD_SUCCESS;
1694}
1695
1696DEFUN (no_ip_rip_authentication_string,
1697 no_ip_rip_authentication_string_cmd,
1698 "no ip rip authentication string",
1699 NO_STR
1700 IP_STR
1701 "Routing Information Protocol\n"
1702 "Authentication control\n"
1703 "Authentication string\n")
1704{
1705 struct interface *ifp;
1706 struct rip_interface *ri;
1707
1708 ifp = (struct interface *)vty->index;
1709 ri = ifp->info;
1710
1711 if (ri->auth_str)
1712 free (ri->auth_str);
1713
1714 ri->auth_str = NULL;
1715
1716 return CMD_SUCCESS;
1717}
1718
1719ALIAS (no_ip_rip_authentication_string,
1720 no_ip_rip_authentication_string2_cmd,
1721 "no ip rip authentication string LINE",
1722 NO_STR
1723 IP_STR
1724 "Routing Information Protocol\n"
1725 "Authentication control\n"
1726 "Authentication string\n"
1727 "Authentication string\n")
1728
1729DEFUN (ip_rip_authentication_key_chain,
1730 ip_rip_authentication_key_chain_cmd,
1731 "ip rip authentication key-chain LINE",
1732 IP_STR
1733 "Routing Information Protocol\n"
1734 "Authentication control\n"
1735 "Authentication key-chain\n"
1736 "name of key-chain\n")
1737{
1738 struct interface *ifp;
1739 struct rip_interface *ri;
1740
1741 ifp = (struct interface *) vty->index;
1742 ri = ifp->info;
1743
1744 if (ri->auth_str)
1745 {
1746 vty_out (vty, "%% authentication string configuration exists%s",
1747 VTY_NEWLINE);
1748 return CMD_WARNING;
1749 }
1750
1751 if (ri->key_chain)
1752 free (ri->key_chain);
1753
1754 ri->key_chain = strdup (argv[0]);
1755
1756 return CMD_SUCCESS;
1757}
1758
1759DEFUN (no_ip_rip_authentication_key_chain,
1760 no_ip_rip_authentication_key_chain_cmd,
1761 "no ip rip authentication key-chain",
1762 NO_STR
1763 IP_STR
1764 "Routing Information Protocol\n"
1765 "Authentication control\n"
1766 "Authentication key-chain\n")
1767{
1768 struct interface *ifp;
1769 struct rip_interface *ri;
1770
1771 ifp = (struct interface *) vty->index;
1772 ri = ifp->info;
1773
1774 if (ri->key_chain)
1775 free (ri->key_chain);
1776
1777 ri->key_chain = NULL;
1778
1779 return CMD_SUCCESS;
1780}
1781
1782ALIAS (no_ip_rip_authentication_key_chain,
1783 no_ip_rip_authentication_key_chain2_cmd,
1784 "no ip rip authentication key-chain LINE",
1785 NO_STR
1786 IP_STR
1787 "Routing Information Protocol\n"
1788 "Authentication control\n"
1789 "Authentication key-chain\n"
1790 "name of key-chain\n")
1791
hasso16705132003-05-25 14:49:19 +00001792/* CHANGED: ip rip split-horizon
1793 Cisco and Zebra's command is
1794 ip split-horizon
1795 */
1796DEFUN (ip_rip_split_horizon,
1797 ip_rip_split_horizon_cmd,
1798 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001799 IP_STR
hasso16705132003-05-25 14:49:19 +00001800 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001801 "Perform split horizon\n")
1802{
1803 struct interface *ifp;
1804 struct rip_interface *ri;
1805
1806 ifp = vty->index;
1807 ri = ifp->info;
1808
hasso16705132003-05-25 14:49:19 +00001809 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001810 return CMD_SUCCESS;
1811}
1812
hasso16705132003-05-25 14:49:19 +00001813DEFUN (ip_rip_split_horizon_poisoned_reverse,
1814 ip_rip_split_horizon_poisoned_reverse_cmd,
1815 "ip rip split-horizon poisoned-reverse",
1816 IP_STR
1817 "Routing Information Protocol\n"
1818 "Perform split horizon\n"
1819 "With poisoned-reverse\n")
1820{
1821 struct interface *ifp;
1822 struct rip_interface *ri;
1823
1824 ifp = vty->index;
1825 ri = ifp->info;
1826
1827 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1828 return CMD_SUCCESS;
1829}
1830
1831/* CHANGED: no ip rip split-horizon
1832 Cisco and Zebra's command is
1833 no ip split-horizon
1834 */
1835DEFUN (no_ip_rip_split_horizon,
1836 no_ip_rip_split_horizon_cmd,
1837 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001838 NO_STR
1839 IP_STR
hasso16705132003-05-25 14:49:19 +00001840 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001841 "Perform split horizon\n")
1842{
1843 struct interface *ifp;
1844 struct rip_interface *ri;
1845
1846 ifp = vty->index;
1847 ri = ifp->info;
1848
hasso16705132003-05-25 14:49:19 +00001849 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001850 return CMD_SUCCESS;
1851}
1852
vincentfac3e842005-10-06 07:45:43 +00001853DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001854 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1855 "no ip rip split-horizon poisoned-reverse",
1856 NO_STR
1857 IP_STR
1858 "Routing Information Protocol\n"
1859 "Perform split horizon\n"
1860 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001861{
1862 struct interface *ifp;
1863 struct rip_interface *ri;
1864
1865 ifp = vty->index;
1866 ri = ifp->info;
1867
1868 switch( ri->split_horizon )
1869 {
1870 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1871 ri->split_horizon = RIP_SPLIT_HORIZON;
1872 default:
1873 break;
1874 }
1875
1876 return CMD_SUCCESS;
1877}
hasso16705132003-05-25 14:49:19 +00001878
paul718e3742002-12-13 20:15:29 +00001879DEFUN (rip_passive_interface,
1880 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001881 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001882 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001883 "Interface name\n"
1884 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001885{
hasso98b718a2004-10-11 12:57:57 +00001886 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001887
1888 if (!strcmp(ifname,"default")) {
1889 passive_default = 1;
1890 rip_passive_nondefault_clean();
1891 return CMD_SUCCESS;
1892 }
1893 if (passive_default)
1894 return rip_passive_nondefault_unset (vty, ifname);
1895 else
1896 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001897}
1898
1899DEFUN (no_rip_passive_interface,
1900 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001901 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001902 NO_STR
1903 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001904 "Interface name\n"
1905 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001906{
hasso98b718a2004-10-11 12:57:57 +00001907 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001908
1909 if (!strcmp(ifname,"default")) {
1910 passive_default = 0;
1911 rip_passive_nondefault_clean();
1912 return CMD_SUCCESS;
1913 }
1914 if (passive_default)
1915 return rip_passive_nondefault_set (vty, ifname);
1916 else
1917 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001918}
1919
1920/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001921static int
paul718e3742002-12-13 20:15:29 +00001922rip_interface_config_write (struct vty *vty)
1923{
hasso52dc7ee2004-09-23 19:18:23 +00001924 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001925 struct interface *ifp;
1926
paul1eb8ef22005-04-07 07:30:20 +00001927 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001928 {
1929 struct rip_interface *ri;
1930
paul718e3742002-12-13 20:15:29 +00001931 ri = ifp->info;
1932
hasso16705132003-05-25 14:49:19 +00001933 /* Do not display the interface if there is no
1934 * configuration about it.
1935 **/
1936 if ((!ifp->desc) &&
1937 (ri->split_horizon == ri->split_horizon_default) &&
1938 (ri->ri_send == RI_RIP_UNSPEC) &&
1939 (ri->ri_receive == RI_RIP_UNSPEC) &&
1940 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001941 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001942 (!ri->auth_str) &&
1943 (!ri->key_chain) )
1944 continue;
1945
paul718e3742002-12-13 20:15:29 +00001946 vty_out (vty, "interface %s%s", ifp->name,
1947 VTY_NEWLINE);
1948
1949 if (ifp->desc)
1950 vty_out (vty, " description %s%s", ifp->desc,
1951 VTY_NEWLINE);
1952
1953 /* Split horizon. */
1954 if (ri->split_horizon != ri->split_horizon_default)
1955 {
hasso16705132003-05-25 14:49:19 +00001956 switch (ri->split_horizon) {
1957 case RIP_SPLIT_HORIZON:
1958 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1959 break;
1960 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1961 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1962 VTY_NEWLINE);
1963 break;
1964 case RIP_NO_SPLIT_HORIZON:
1965 default:
1966 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1967 break;
1968 }
paul718e3742002-12-13 20:15:29 +00001969 }
1970
1971 /* RIP version setting. */
1972 if (ri->ri_send != RI_RIP_UNSPEC)
1973 vty_out (vty, " ip rip send version %s%s",
1974 lookup (ri_version_msg, ri->ri_send),
1975 VTY_NEWLINE);
1976
1977 if (ri->ri_receive != RI_RIP_UNSPEC)
1978 vty_out (vty, " ip rip receive version %s%s",
1979 lookup (ri_version_msg, ri->ri_receive),
1980 VTY_NEWLINE);
1981
1982 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001983 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1984 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001985
paul718e3742002-12-13 20:15:29 +00001986 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001987 {
1988 vty_out (vty, " ip rip authentication mode md5");
1989 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1990 vty_out (vty, " auth-length old-ripd");
1991 else
1992 vty_out (vty, " auth-length rfc");
1993 vty_out (vty, "%s", VTY_NEWLINE);
1994 }
paul718e3742002-12-13 20:15:29 +00001995
1996 if (ri->auth_str)
1997 vty_out (vty, " ip rip authentication string %s%s",
1998 ri->auth_str, VTY_NEWLINE);
1999
2000 if (ri->key_chain)
2001 vty_out (vty, " ip rip authentication key-chain %s%s",
2002 ri->key_chain, VTY_NEWLINE);
2003
2004 vty_out (vty, "!%s", VTY_NEWLINE);
2005 }
2006 return 0;
2007}
2008
2009int
2010config_write_rip_network (struct vty *vty, int config_mode)
2011{
hasso8a676be2004-10-08 06:36:38 +00002012 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002013 char *ifname;
2014 struct route_node *node;
2015
2016 /* Network type RIP enable interface statement. */
2017 for (node = route_top (rip_enable_network); node; node = route_next (node))
2018 if (node->info)
2019 vty_out (vty, "%s%s/%d%s",
2020 config_mode ? " network " : " ",
2021 inet_ntoa (node->p.u.prefix4),
2022 node->p.prefixlen,
2023 VTY_NEWLINE);
2024
2025 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002026 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002027 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2028 vty_out (vty, "%s%s%s",
2029 config_mode ? " network " : " ",
2030 ifname,
2031 VTY_NEWLINE);
2032
2033 /* RIP neighbors listing. */
2034 for (node = route_top (rip->neighbor); node; node = route_next (node))
2035 if (node->info)
2036 vty_out (vty, "%s%s%s",
2037 config_mode ? " neighbor " : " ",
2038 inet_ntoa (node->p.u.prefix4),
2039 VTY_NEWLINE);
2040
2041 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002042 if (config_mode) {
2043 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002044 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002045 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002046 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2047 vty_out (vty, " %spassive-interface %s%s",
2048 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2049 }
paul718e3742002-12-13 20:15:29 +00002050
2051 return 0;
2052}
2053
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002054static struct cmd_node interface_node =
paul718e3742002-12-13 20:15:29 +00002055{
2056 INTERFACE_NODE,
2057 "%s(config-if)# ",
2058 1,
2059};
2060
2061/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002062static int
paul718e3742002-12-13 20:15:29 +00002063rip_interface_new_hook (struct interface *ifp)
2064{
2065 ifp->info = rip_interface_new ();
2066 return 0;
2067}
2068
2069/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002070static int
paul718e3742002-12-13 20:15:29 +00002071rip_interface_delete_hook (struct interface *ifp)
2072{
2073 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002074 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002075 return 0;
2076}
2077
2078/* Allocate and initialize interface vector. */
2079void
pauldc63bfd2005-10-25 23:31:05 +00002080rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002081{
2082 /* Default initial size of interface vector. */
2083 if_init();
2084 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2085 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2086
2087 /* RIP network init. */
2088 rip_enable_interface = vector_init (1);
2089 rip_enable_network = route_table_init ();
2090
2091 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002092 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002093
2094 /* Install interface node. */
2095 install_node (&interface_node, rip_interface_config_write);
2096
2097 /* Install commands. */
2098 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002099 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002100 install_default (INTERFACE_NODE);
2101 install_element (INTERFACE_NODE, &interface_desc_cmd);
2102 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2103 install_element (RIP_NODE, &rip_network_cmd);
2104 install_element (RIP_NODE, &no_rip_network_cmd);
2105 install_element (RIP_NODE, &rip_neighbor_cmd);
2106 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2107
2108 install_element (RIP_NODE, &rip_passive_interface_cmd);
2109 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2110
2111 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2112 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2113 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2114 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2115 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2116
2117 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2118 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2119 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2120 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2121 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2122
2123 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002124 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002125 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2126 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002127 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002128
2129 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2130 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2131 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2132
2133 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2134 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2135 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2136
hasso16705132003-05-25 14:49:19 +00002137 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2138 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2139 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2140 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002141}