blob: d3b55fc01f52a0ca0a0ef197382d5a643104c96b [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
Stephen Hemminger2c239702009-12-10 19:16:05 +0300242#if 0
paul718e3742002-12-13 20:15:29 +0000243/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000244static void
paul718e3742002-12-13 20:15:29 +0000245rip_request_neighbor (struct in_addr addr)
246{
247 struct sockaddr_in to;
248
249 memset (&to, 0, sizeof (struct sockaddr_in));
250 to.sin_port = htons (RIP_PORT_DEFAULT);
251 to.sin_addr = addr;
252
paul931cd542004-01-23 15:31:42 +0000253 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000254}
255
256/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000257static void
258rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000259{
260 struct route_node *rp;
261
262 if (! rip)
263 return;
264
265 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000266 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000267
268 /* Send request to all neighbor. */
269 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
270 if (rp->info)
271 rip_request_neighbor (rp->p.u.prefix4);
272}
Stephen Hemminger2c239702009-12-10 19:16:05 +0300273#endif
paul718e3742002-12-13 20:15:29 +0000274
275/* Multicast packet receive socket. */
pauldc63bfd2005-10-25 23:31:05 +0000276static int
paul718e3742002-12-13 20:15:29 +0000277rip_multicast_join (struct interface *ifp, int sock)
278{
hasso52dc7ee2004-09-23 19:18:23 +0000279 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000280 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000281
paul2e3b2e42002-12-13 21:03:13 +0000282 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000283 {
284 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000285 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000286
paul1eb8ef22005-04-07 07:30:20 +0000287 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000288 {
289 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000290 struct in_addr group;
291
paul1eb8ef22005-04-07 07:30:20 +0000292 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000293
294 if (p->family != AF_INET)
295 continue;
296
297 group.s_addr = htonl (INADDR_RIP_GROUP);
298 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
299 return -1;
300 else
301 return 0;
302 }
303 }
304 return 0;
305}
306
307/* Leave from multicast group. */
pauldc63bfd2005-10-25 23:31:05 +0000308static void
paul718e3742002-12-13 20:15:29 +0000309rip_multicast_leave (struct interface *ifp, int sock)
310{
hasso52dc7ee2004-09-23 19:18:23 +0000311 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000312 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000313
314 if (if_is_up (ifp) && if_is_multicast (ifp))
315 {
316 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000317 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000318
paul1eb8ef22005-04-07 07:30:20 +0000319 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000320 {
321 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000322 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000323
paul718e3742002-12-13 20:15:29 +0000324 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000325
paul718e3742002-12-13 20:15:29 +0000326 if (p->family != AF_INET)
327 continue;
328
329 group.s_addr = htonl (INADDR_RIP_GROUP);
330 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
331 return;
332 }
333 }
334}
335
336/* Is there and address on interface that I could use ? */
pauldc63bfd2005-10-25 23:31:05 +0000337static int
paul718e3742002-12-13 20:15:29 +0000338rip_if_ipv4_address_check (struct interface *ifp)
339{
340 struct listnode *nn;
341 struct connected *connected;
342 int count = 0;
343
paul1eb8ef22005-04-07 07:30:20 +0000344 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
345 {
346 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000347
paul1eb8ef22005-04-07 07:30:20 +0000348 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000349
paul1eb8ef22005-04-07 07:30:20 +0000350 if (p->family == AF_INET)
351 count++;
352 }
paul718e3742002-12-13 20:15:29 +0000353
354 return count;
355}
paul31a476c2003-09-29 19:54:53 +0000356
357
358
359
360/* Does this address belongs to me ? */
361int
362if_check_address (struct in_addr addr)
363{
hasso52dc7ee2004-09-23 19:18:23 +0000364 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000365 struct interface *ifp;
366
367 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000368 {
hasso52dc7ee2004-09-23 19:18:23 +0000369 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000370 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000371
paul1eb8ef22005-04-07 07:30:20 +0000372 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000373 {
paul31a476c2003-09-29 19:54:53 +0000374 struct prefix_ipv4 *p;
375
paul31a476c2003-09-29 19:54:53 +0000376 p = (struct prefix_ipv4 *) connected->address;
377
378 if (p->family != AF_INET)
379 continue;
380
381 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
382 return 1;
383 }
384 }
385 return 0;
386}
387
paul718e3742002-12-13 20:15:29 +0000388/* Inteface link down message processing. */
389int
390rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
391{
392 struct interface *ifp;
393 struct stream *s;
394
395 s = zclient->ibuf;
396
397 /* zebra_interface_state_read() updates interface structure in
398 iflist. */
399 ifp = zebra_interface_state_read(s);
400
401 if (ifp == NULL)
402 return 0;
403
404 rip_if_down(ifp);
405
406 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger30d20592009-07-28 11:58:51 +0100407 zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down",
408 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
409 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000410
411 return 0;
412}
413
414/* Inteface link up message processing */
415int
416rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
417{
418 struct interface *ifp;
419
420 /* zebra_interface_state_read () updates interface structure in
421 iflist. */
422 ifp = zebra_interface_state_read (zclient->ibuf);
423
424 if (ifp == NULL)
425 return 0;
426
427 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300428 zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up",
429 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
430 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000431
432 /* Check if this interface is RIP enabled or not.*/
433 rip_enable_apply (ifp);
434
435 /* Check for a passive interface */
436 rip_passive_interface_apply (ifp);
437
438 /* Apply distribute list to the all interface. */
439 rip_distribute_update_interface (ifp);
440
441 return 0;
442}
443
444/* Inteface addition message from zebra. */
445int
446rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
447{
448 struct interface *ifp;
449
450 ifp = zebra_interface_add_read (zclient->ibuf);
451
452 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300453 zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d",
454 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
455 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000456
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
Stephen Hemminger2c239702009-12-10 19:16:05 +0300493 zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
494 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
495 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000496
497 /* To support pseudo interface do not free interface structure. */
498 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000499 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000500
501 return 0;
502}
503
504void
pauldc63bfd2005-10-25 23:31:05 +0000505rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000506{
hasso52dc7ee2004-09-23 19:18:23 +0000507 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000508 struct interface *ifp;
509 struct rip_interface *ri;
510
paul1eb8ef22005-04-07 07:30:20 +0000511 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000512 {
paul718e3742002-12-13 20:15:29 +0000513 ri = ifp->info;
514
515 ri->enable_network = 0;
516 ri->enable_interface = 0;
517 ri->running = 0;
518
519 if (ri->t_wakeup)
520 {
521 thread_cancel (ri->t_wakeup);
522 ri->t_wakeup = NULL;
523 }
524 }
525}
526
527void
pauldc63bfd2005-10-25 23:31:05 +0000528rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000529{
hasso52dc7ee2004-09-23 19:18:23 +0000530 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000531 struct interface *ifp;
532 struct rip_interface *ri;
533
paul1eb8ef22005-04-07 07:30:20 +0000534 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000535 {
paul718e3742002-12-13 20:15:29 +0000536 ri = ifp->info;
537
538 ri->enable_network = 0;
539 ri->enable_interface = 0;
540 ri->running = 0;
541
542 ri->ri_send = RI_RIP_UNSPEC;
543 ri->ri_receive = RI_RIP_UNSPEC;
544
paul7755a8c2005-06-02 08:20:53 +0000545 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000546
547 if (ri->auth_str)
548 {
549 free (ri->auth_str);
550 ri->auth_str = NULL;
551 }
552 if (ri->key_chain)
553 {
554 free (ri->key_chain);
555 ri->key_chain = NULL;
556 }
557
hasso16705132003-05-25 14:49:19 +0000558 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
559 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000560
561 ri->list[RIP_FILTER_IN] = NULL;
562 ri->list[RIP_FILTER_OUT] = NULL;
563
564 ri->prefix[RIP_FILTER_IN] = NULL;
565 ri->prefix[RIP_FILTER_OUT] = NULL;
566
567 if (ri->t_wakeup)
568 {
569 thread_cancel (ri->t_wakeup);
570 ri->t_wakeup = NULL;
571 }
572
573 ri->recv_badpackets = 0;
574 ri->recv_badroutes = 0;
575 ri->sent_updates = 0;
576
577 ri->passive = 0;
578 }
579}
580
581int
582rip_if_down(struct interface *ifp)
583{
584 struct route_node *rp;
585 struct rip_info *rinfo;
586 struct rip_interface *ri = NULL;
587 if (rip)
588 {
589 for (rp = route_top (rip->table); rp; rp = route_next (rp))
590 if ((rinfo = rp->info) != NULL)
591 {
592 /* Routes got through this interface. */
593 if (rinfo->ifindex == ifp->ifindex &&
594 rinfo->type == ZEBRA_ROUTE_RIP &&
595 rinfo->sub_type == RIP_ROUTE_RTE)
596 {
597 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
598 &rinfo->nexthop,
Krisztian Kovacsc5a89ff2009-06-02 18:09:48 +0100599 rinfo->metric);
paul718e3742002-12-13 20:15:29 +0000600
601 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
602 (struct prefix_ipv4 *)&rp->p,
603 rinfo->ifindex);
604 }
605 else
606 {
607 /* All redistributed routes but static and system */
608 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000609 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000610 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
611 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
612 (struct prefix_ipv4 *)&rp->p,
613 rinfo->ifindex);
614 }
615 }
616 }
617
618 ri = ifp->info;
619
620 if (ri->running)
621 {
622 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000623 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000624
625 /* Leave from multicast group. */
626 rip_multicast_leave (ifp, rip->sock);
627
628 ri->running = 0;
629 }
630
631 return 0;
632}
633
634/* Needed for stop RIP process. */
635void
636rip_if_down_all ()
637{
638 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000639 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000640
paul1eb8ef22005-04-07 07:30:20 +0000641 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
642 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000643}
644
hasso16705132003-05-25 14:49:19 +0000645static void
pauldc63bfd2005-10-25 23:31:05 +0000646rip_apply_address_add (struct connected *ifc)
647{
hasso16705132003-05-25 14:49:19 +0000648 struct prefix_ipv4 address;
649 struct prefix *p;
650
651 if (!rip)
652 return;
653
654 if (! if_is_up(ifc->ifp))
655 return;
656
657 p = ifc->address;
658
659 memset (&address, 0, sizeof (address));
660 address.family = p->family;
661 address.prefix = p->u.prefix4;
662 address.prefixlen = p->prefixlen;
663 apply_mask_ipv4(&address);
664
665 /* Check if this interface is RIP enabled or not
666 or Check if this address's prefix is RIP enabled */
667 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
668 (rip_enable_network_lookup2(ifc) >= 0))
669 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000670 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000671
672}
673
paul718e3742002-12-13 20:15:29 +0000674int
675rip_interface_address_add (int command, struct zclient *zclient,
676 zebra_size_t length)
677{
678 struct connected *ifc;
679 struct prefix *p;
680
paul0a589352004-05-08 11:48:26 +0000681 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
682 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000683
684 if (ifc == NULL)
685 return 0;
686
687 p = ifc->address;
688
689 if (p->family == AF_INET)
690 {
691 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000692 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000693 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000694
paul878ef2e2003-09-23 23:41:50 +0000695 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000696 /* Check if this prefix needs to be redistributed */
697 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000698
699#ifdef HAVE_SNMP
700 rip_ifaddr_add (ifc->ifp, ifc);
701#endif /* HAVE_SNMP */
702 }
703
704 return 0;
705}
706
hasso16705132003-05-25 14:49:19 +0000707static void
708rip_apply_address_del (struct connected *ifc) {
709 struct prefix_ipv4 address;
710 struct prefix *p;
711
712 if (!rip)
713 return;
714
715 if (! if_is_up(ifc->ifp))
716 return;
717
718 p = ifc->address;
719
720 memset (&address, 0, sizeof (address));
721 address.family = p->family;
722 address.prefix = p->u.prefix4;
723 address.prefixlen = p->prefixlen;
724 apply_mask_ipv4(&address);
725
726 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
727 &address, ifc->ifp->ifindex);
728}
729
paul718e3742002-12-13 20:15:29 +0000730int
731rip_interface_address_delete (int command, struct zclient *zclient,
732 zebra_size_t length)
733{
734 struct connected *ifc;
735 struct prefix *p;
736
paul0a589352004-05-08 11:48:26 +0000737 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
738 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000739
740 if (ifc)
741 {
742 p = ifc->address;
743 if (p->family == AF_INET)
744 {
745 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000746 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000747 inet_ntoa (p->u.prefix4), p->prefixlen);
748
749#ifdef HAVE_SNMP
750 rip_ifaddr_delete (ifc->ifp, ifc);
751#endif /* HAVE_SNMP */
752
hasso16705132003-05-25 14:49:19 +0000753 /* Chech wether this prefix needs to be removed */
754 rip_apply_address_del(ifc);
755
paul718e3742002-12-13 20:15:29 +0000756 }
757
758 connected_free (ifc);
759
760 }
761
762 return 0;
763}
764
765/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000766/* Check wether the interface has at least a connected prefix that
767 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000768static int
hasso16705132003-05-25 14:49:19 +0000769rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000770{
paul1eb8ef22005-04-07 07:30:20 +0000771 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000772 struct connected *connected;
773 struct prefix_ipv4 address;
774
paul1eb8ef22005-04-07 07:30:20 +0000775 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
776 {
777 struct prefix *p;
778 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000779
paul1eb8ef22005-04-07 07:30:20 +0000780 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000781
paul1eb8ef22005-04-07 07:30:20 +0000782 if (p->family == AF_INET)
783 {
784 address.family = AF_INET;
785 address.prefix = p->u.prefix4;
786 address.prefixlen = IPV4_MAX_BITLEN;
787
788 node = route_node_match (rip_enable_network,
789 (struct prefix *)&address);
790 if (node)
791 {
792 route_unlock_node (node);
793 return 1;
794 }
795 }
796 }
paul718e3742002-12-13 20:15:29 +0000797 return -1;
798}
799
hasso16705132003-05-25 14:49:19 +0000800/* Check wether connected is within the ripng_enable_network table. */
801int
802rip_enable_network_lookup2 (struct connected *connected)
803{
804 struct prefix_ipv4 address;
805 struct prefix *p;
806
807 p = connected->address;
808
809 if (p->family == AF_INET) {
810 struct route_node *node;
811
812 address.family = p->family;
813 address.prefix = p->u.prefix4;
814 address.prefixlen = IPV4_MAX_BITLEN;
815
816 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
817 node = route_node_match (rip_enable_network,
818 (struct prefix *)&address);
819
820 if (node) {
821 route_unlock_node (node);
822 return 1;
823 }
824 }
825
826 return -1;
827}
paul718e3742002-12-13 20:15:29 +0000828/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000829static int
paul718e3742002-12-13 20:15:29 +0000830rip_enable_network_add (struct prefix *p)
831{
832 struct route_node *node;
833
834 node = route_node_get (rip_enable_network, p);
835
836 if (node->info)
837 {
838 route_unlock_node (node);
839 return -1;
840 }
841 else
hasso8a676be2004-10-08 06:36:38 +0000842 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000843
hasso16705132003-05-25 14:49:19 +0000844 /* XXX: One should find a better solution than a generic one */
845 rip_enable_apply_all();
846
paul718e3742002-12-13 20:15:29 +0000847 return 1;
848}
849
850/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000851static int
paul718e3742002-12-13 20:15:29 +0000852rip_enable_network_delete (struct prefix *p)
853{
854 struct route_node *node;
855
856 node = route_node_lookup (rip_enable_network, p);
857 if (node)
858 {
859 node->info = NULL;
860
861 /* Unlock info lock. */
862 route_unlock_node (node);
863
864 /* Unlock lookup lock. */
865 route_unlock_node (node);
866
hasso16705132003-05-25 14:49:19 +0000867 /* XXX: One should find a better solution than a generic one */
868 rip_enable_apply_all ();
869
paul718e3742002-12-13 20:15:29 +0000870 return 1;
871 }
872 return -1;
873}
874
875/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000876static int
hasso98b718a2004-10-11 12:57:57 +0000877rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000878{
hasso8a676be2004-10-08 06:36:38 +0000879 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000880 char *str;
881
paul55468c82005-03-14 20:19:01 +0000882 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000883 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
884 if (strcmp (str, ifname) == 0)
885 return i;
886 return -1;
887}
888
889/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000890static int
hasso98b718a2004-10-11 12:57:57 +0000891rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000892{
893 int ret;
894
895 ret = rip_enable_if_lookup (ifname);
896 if (ret >= 0)
897 return -1;
898
899 vector_set (rip_enable_interface, strdup (ifname));
900
hasso16705132003-05-25 14:49:19 +0000901 rip_enable_apply_all(); /* TODOVJ */
902
paul718e3742002-12-13 20:15:29 +0000903 return 1;
904}
905
906/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000907static int
hasso98b718a2004-10-11 12:57:57 +0000908rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000909{
910 int index;
911 char *str;
912
913 index = rip_enable_if_lookup (ifname);
914 if (index < 0)
915 return -1;
916
917 str = vector_slot (rip_enable_interface, index);
918 free (str);
919 vector_unset (rip_enable_interface, index);
920
hasso16705132003-05-25 14:49:19 +0000921 rip_enable_apply_all(); /* TODOVJ */
922
paul718e3742002-12-13 20:15:29 +0000923 return 1;
924}
925
926/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000927static int
paul718e3742002-12-13 20:15:29 +0000928rip_interface_wakeup (struct thread *t)
929{
930 struct interface *ifp;
931 struct rip_interface *ri;
932
933 /* Get interface. */
934 ifp = THREAD_ARG (t);
935
936 ri = ifp->info;
937 ri->t_wakeup = NULL;
938
939 /* Join to multicast group. */
940 if (rip_multicast_join (ifp, rip->sock) < 0)
941 {
942 zlog_err ("multicast join failed, interface %s not running", ifp->name);
943 return 0;
944 }
945
946 /* Set running flag. */
947 ri->running = 1;
948
949 /* Send RIP request to the interface. */
950 rip_request_interface (ifp);
951
952 return 0;
953}
954
pauldc63bfd2005-10-25 23:31:05 +0000955static void
paul718e3742002-12-13 20:15:29 +0000956rip_connect_set (struct interface *ifp, int set)
957{
paul1eb8ef22005-04-07 07:30:20 +0000958 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000959 struct connected *connected;
960 struct prefix_ipv4 address;
961
paul1eb8ef22005-04-07 07:30:20 +0000962 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
963 {
964 struct prefix *p;
965 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000966
paul1eb8ef22005-04-07 07:30:20 +0000967 if (p->family != AF_INET)
968 continue;
paul718e3742002-12-13 20:15:29 +0000969
paul1eb8ef22005-04-07 07:30:20 +0000970 address.family = AF_INET;
971 address.prefix = p->u.prefix4;
972 address.prefixlen = p->prefixlen;
973 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000974
paul1eb8ef22005-04-07 07:30:20 +0000975 if (set) {
976 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
977 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
978 (rip_enable_network_lookup2(connected) >= 0))
979 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000980 &address, connected->ifp->ifindex,
981 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000982 } else
983 {
984 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
985 &address, connected->ifp->ifindex);
986 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
987 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000988 &address, connected->ifp->ifindex,
989 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000990 }
991 }
paul718e3742002-12-13 20:15:29 +0000992}
993
994/* Update interface status. */
995void
996rip_enable_apply (struct interface *ifp)
997{
998 int ret;
999 struct rip_interface *ri = NULL;
1000
1001 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001002 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001003 return;
1004
1005 ri = ifp->info;
1006
1007 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001008 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001009
1010 /* If the interface is matched. */
1011 if (ret > 0)
1012 ri->enable_network = 1;
1013 else
1014 ri->enable_network = 0;
1015
1016 /* Check interface name configuration. */
1017 ret = rip_enable_if_lookup (ifp->name);
1018 if (ret >= 0)
1019 ri->enable_interface = 1;
1020 else
1021 ri->enable_interface = 0;
1022
1023 /* any interface MUST have an IPv4 address */
1024 if ( ! rip_if_ipv4_address_check (ifp) )
1025 {
1026 ri->enable_network = 0;
1027 ri->enable_interface = 0;
1028 }
1029
1030 /* Update running status of the interface. */
1031 if (ri->enable_network || ri->enable_interface)
1032 {
paul718e3742002-12-13 20:15:29 +00001033 {
1034 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001035 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001036
1037 /* Add interface wake up thread. */
1038 if (! ri->t_wakeup)
1039 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1040 ifp, 1);
1041 rip_connect_set (ifp, 1);
1042 }
1043 }
1044 else
1045 {
1046 if (ri->running)
1047 {
hasso16705132003-05-25 14:49:19 +00001048 /* Might as well clean up the route table as well
1049 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1050 **/
paul718e3742002-12-13 20:15:29 +00001051 rip_if_down(ifp);
1052
paul718e3742002-12-13 20:15:29 +00001053 rip_connect_set (ifp, 0);
1054 }
1055 }
1056}
1057
1058/* Apply network configuration to all interface. */
1059void
1060rip_enable_apply_all ()
1061{
1062 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001063 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001064
1065 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001066 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1067 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001068}
1069
1070int
1071rip_neighbor_lookup (struct sockaddr_in *from)
1072{
1073 struct prefix_ipv4 p;
1074 struct route_node *node;
1075
1076 memset (&p, 0, sizeof (struct prefix_ipv4));
1077 p.family = AF_INET;
1078 p.prefix = from->sin_addr;
1079 p.prefixlen = IPV4_MAX_BITLEN;
1080
1081 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1082 if (node)
1083 {
1084 route_unlock_node (node);
1085 return 1;
1086 }
1087 return 0;
1088}
1089
1090/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001091static int
paul718e3742002-12-13 20:15:29 +00001092rip_neighbor_add (struct prefix_ipv4 *p)
1093{
1094 struct route_node *node;
1095
1096 node = route_node_get (rip->neighbor, (struct prefix *) p);
1097
1098 if (node->info)
1099 return -1;
1100
1101 node->info = rip->neighbor;
1102
1103 return 0;
1104}
1105
1106/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001107static int
paul718e3742002-12-13 20:15:29 +00001108rip_neighbor_delete (struct prefix_ipv4 *p)
1109{
1110 struct route_node *node;
1111
1112 /* Lock for look up. */
1113 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1114 if (! node)
1115 return -1;
1116
1117 node->info = NULL;
1118
1119 /* Unlock lookup lock. */
1120 route_unlock_node (node);
1121
1122 /* Unlock real neighbor information lock. */
1123 route_unlock_node (node);
1124
1125 return 0;
1126}
1127
1128/* Clear all network and neighbor configuration. */
1129void
1130rip_clean_network ()
1131{
hasso8a676be2004-10-08 06:36:38 +00001132 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001133 char *str;
1134 struct route_node *rn;
1135
1136 /* rip_enable_network. */
1137 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1138 if (rn->info)
1139 {
1140 rn->info = NULL;
1141 route_unlock_node (rn);
1142 }
1143
1144 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001145 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001146 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1147 {
1148 free (str);
1149 vector_slot (rip_enable_interface, i) = NULL;
1150 }
1151}
1152
1153/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001154static int
hasso98b718a2004-10-11 12:57:57 +00001155rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001156{
hasso8a676be2004-10-08 06:36:38 +00001157 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001158 char *str;
1159
paul55468c82005-03-14 20:19:01 +00001160 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001161 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001162 if (strcmp (str, ifname) == 0)
1163 return i;
1164 return -1;
1165}
1166
1167void
1168rip_passive_interface_apply (struct interface *ifp)
1169{
paul718e3742002-12-13 20:15:29 +00001170 struct rip_interface *ri;
1171
1172 ri = ifp->info;
1173
paul4aaff3f2003-06-07 01:04:45 +00001174 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1175 passive_default : !passive_default);
1176
1177 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001178 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001179}
1180
pauldc63bfd2005-10-25 23:31:05 +00001181static void
1182rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001183{
1184 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001185 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001186
paul1eb8ef22005-04-07 07:30:20 +00001187 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1188 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001189}
1190
1191/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001192static int
hasso98b718a2004-10-11 12:57:57 +00001193rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001194{
paul4aaff3f2003-06-07 01:04:45 +00001195 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001196 return CMD_WARNING;
1197
paul4aaff3f2003-06-07 01:04:45 +00001198 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001199
1200 rip_passive_interface_apply_all ();
1201
1202 return CMD_SUCCESS;
1203}
1204
pauldc63bfd2005-10-25 23:31:05 +00001205static int
hasso98b718a2004-10-11 12:57:57 +00001206rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001207{
1208 int i;
1209 char *str;
1210
paul4aaff3f2003-06-07 01:04:45 +00001211 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001212 if (i < 0)
1213 return CMD_WARNING;
1214
paul4aaff3f2003-06-07 01:04:45 +00001215 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001216 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001217 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001218
1219 rip_passive_interface_apply_all ();
1220
1221 return CMD_SUCCESS;
1222}
1223
1224/* Free all configured RIP passive-interface settings. */
1225void
pauldc63bfd2005-10-25 23:31:05 +00001226rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001227{
hasso8a676be2004-10-08 06:36:38 +00001228 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001229 char *str;
1230
paul55468c82005-03-14 20:19:01 +00001231 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001232 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001233 {
1234 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001235 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001236 }
1237 rip_passive_interface_apply_all ();
1238}
1239
1240/* RIP enable network or interface configuration. */
1241DEFUN (rip_network,
1242 rip_network_cmd,
1243 "network (A.B.C.D/M|WORD)",
1244 "Enable routing on an IP network\n"
1245 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1246 "Interface name\n")
1247{
1248 int ret;
1249 struct prefix_ipv4 p;
1250
1251 ret = str2prefix_ipv4 (argv[0], &p);
1252
1253 if (ret)
1254 ret = rip_enable_network_add ((struct prefix *) &p);
1255 else
1256 ret = rip_enable_if_add (argv[0]);
1257
1258 if (ret < 0)
1259 {
1260 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1261 VTY_NEWLINE);
1262 return CMD_WARNING;
1263 }
1264
paul718e3742002-12-13 20:15:29 +00001265 return CMD_SUCCESS;
1266}
1267
1268/* RIP enable network or interface configuration. */
1269DEFUN (no_rip_network,
1270 no_rip_network_cmd,
1271 "no network (A.B.C.D/M|WORD)",
1272 NO_STR
1273 "Enable routing on an IP network\n"
1274 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1275 "Interface name\n")
1276{
1277 int ret;
1278 struct prefix_ipv4 p;
1279
1280 ret = str2prefix_ipv4 (argv[0], &p);
1281
1282 if (ret)
1283 ret = rip_enable_network_delete ((struct prefix *) &p);
1284 else
1285 ret = rip_enable_if_delete (argv[0]);
1286
1287 if (ret < 0)
1288 {
1289 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1290 VTY_NEWLINE);
1291 return CMD_WARNING;
1292 }
1293
paul718e3742002-12-13 20:15:29 +00001294 return CMD_SUCCESS;
1295}
1296
1297/* RIP neighbor configuration set. */
1298DEFUN (rip_neighbor,
1299 rip_neighbor_cmd,
1300 "neighbor A.B.C.D",
1301 "Specify a neighbor router\n"
1302 "Neighbor address\n")
1303{
1304 int ret;
1305 struct prefix_ipv4 p;
1306
1307 ret = str2prefix_ipv4 (argv[0], &p);
1308
1309 if (ret <= 0)
1310 {
1311 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1312 return CMD_WARNING;
1313 }
1314
1315 rip_neighbor_add (&p);
1316
1317 return CMD_SUCCESS;
1318}
1319
1320/* RIP neighbor configuration unset. */
1321DEFUN (no_rip_neighbor,
1322 no_rip_neighbor_cmd,
1323 "no neighbor A.B.C.D",
1324 NO_STR
1325 "Specify a neighbor router\n"
1326 "Neighbor address\n")
1327{
1328 int ret;
1329 struct prefix_ipv4 p;
1330
1331 ret = str2prefix_ipv4 (argv[0], &p);
1332
1333 if (ret <= 0)
1334 {
1335 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1336 return CMD_WARNING;
1337 }
1338
1339 rip_neighbor_delete (&p);
1340
1341 return CMD_SUCCESS;
1342}
1343
1344DEFUN (ip_rip_receive_version,
1345 ip_rip_receive_version_cmd,
1346 "ip rip receive version (1|2)",
1347 IP_STR
1348 "Routing Information Protocol\n"
1349 "Advertisement reception\n"
1350 "Version control\n"
1351 "RIP version 1\n"
1352 "RIP version 2\n")
1353{
1354 struct interface *ifp;
1355 struct rip_interface *ri;
1356
1357 ifp = (struct interface *)vty->index;
1358 ri = ifp->info;
1359
1360 /* Version 1. */
1361 if (atoi (argv[0]) == 1)
1362 {
1363 ri->ri_receive = RI_RIP_VERSION_1;
1364 return CMD_SUCCESS;
1365 }
1366 if (atoi (argv[0]) == 2)
1367 {
1368 ri->ri_receive = RI_RIP_VERSION_2;
1369 return CMD_SUCCESS;
1370 }
1371 return CMD_WARNING;
1372}
1373
1374DEFUN (ip_rip_receive_version_1,
1375 ip_rip_receive_version_1_cmd,
1376 "ip rip receive version 1 2",
1377 IP_STR
1378 "Routing Information Protocol\n"
1379 "Advertisement reception\n"
1380 "Version control\n"
1381 "RIP version 1\n"
1382 "RIP version 2\n")
1383{
1384 struct interface *ifp;
1385 struct rip_interface *ri;
1386
1387 ifp = (struct interface *)vty->index;
1388 ri = ifp->info;
1389
1390 /* Version 1 and 2. */
1391 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1392 return CMD_SUCCESS;
1393}
1394
1395DEFUN (ip_rip_receive_version_2,
1396 ip_rip_receive_version_2_cmd,
1397 "ip rip receive version 2 1",
1398 IP_STR
1399 "Routing Information Protocol\n"
1400 "Advertisement reception\n"
1401 "Version control\n"
1402 "RIP version 2\n"
1403 "RIP version 1\n")
1404{
1405 struct interface *ifp;
1406 struct rip_interface *ri;
1407
1408 ifp = (struct interface *)vty->index;
1409 ri = ifp->info;
1410
1411 /* Version 1 and 2. */
1412 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1413 return CMD_SUCCESS;
1414}
1415
1416DEFUN (no_ip_rip_receive_version,
1417 no_ip_rip_receive_version_cmd,
1418 "no ip rip receive version",
1419 NO_STR
1420 IP_STR
1421 "Routing Information Protocol\n"
1422 "Advertisement reception\n"
1423 "Version control\n")
1424{
1425 struct interface *ifp;
1426 struct rip_interface *ri;
1427
1428 ifp = (struct interface *)vty->index;
1429 ri = ifp->info;
1430
1431 ri->ri_receive = RI_RIP_UNSPEC;
1432 return CMD_SUCCESS;
1433}
1434
1435ALIAS (no_ip_rip_receive_version,
1436 no_ip_rip_receive_version_num_cmd,
1437 "no ip rip receive version (1|2)",
1438 NO_STR
1439 IP_STR
1440 "Routing Information Protocol\n"
1441 "Advertisement reception\n"
1442 "Version control\n"
1443 "Version 1\n"
1444 "Version 2\n")
1445
1446DEFUN (ip_rip_send_version,
1447 ip_rip_send_version_cmd,
1448 "ip rip send version (1|2)",
1449 IP_STR
1450 "Routing Information Protocol\n"
1451 "Advertisement transmission\n"
1452 "Version control\n"
1453 "RIP version 1\n"
1454 "RIP version 2\n")
1455{
1456 struct interface *ifp;
1457 struct rip_interface *ri;
1458
1459 ifp = (struct interface *)vty->index;
1460 ri = ifp->info;
1461
1462 /* Version 1. */
1463 if (atoi (argv[0]) == 1)
1464 {
1465 ri->ri_send = RI_RIP_VERSION_1;
1466 return CMD_SUCCESS;
1467 }
1468 if (atoi (argv[0]) == 2)
1469 {
1470 ri->ri_send = RI_RIP_VERSION_2;
1471 return CMD_SUCCESS;
1472 }
1473 return CMD_WARNING;
1474}
1475
1476DEFUN (ip_rip_send_version_1,
1477 ip_rip_send_version_1_cmd,
1478 "ip rip send version 1 2",
1479 IP_STR
1480 "Routing Information Protocol\n"
1481 "Advertisement transmission\n"
1482 "Version control\n"
1483 "RIP version 1\n"
1484 "RIP version 2\n")
1485{
1486 struct interface *ifp;
1487 struct rip_interface *ri;
1488
1489 ifp = (struct interface *)vty->index;
1490 ri = ifp->info;
1491
1492 /* Version 1 and 2. */
1493 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1494 return CMD_SUCCESS;
1495}
1496
1497DEFUN (ip_rip_send_version_2,
1498 ip_rip_send_version_2_cmd,
1499 "ip rip send version 2 1",
1500 IP_STR
1501 "Routing Information Protocol\n"
1502 "Advertisement transmission\n"
1503 "Version control\n"
1504 "RIP version 2\n"
1505 "RIP version 1\n")
1506{
1507 struct interface *ifp;
1508 struct rip_interface *ri;
1509
1510 ifp = (struct interface *)vty->index;
1511 ri = ifp->info;
1512
1513 /* Version 1 and 2. */
1514 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1515 return CMD_SUCCESS;
1516}
1517
1518DEFUN (no_ip_rip_send_version,
1519 no_ip_rip_send_version_cmd,
1520 "no ip rip send version",
1521 NO_STR
1522 IP_STR
1523 "Routing Information Protocol\n"
1524 "Advertisement transmission\n"
1525 "Version control\n")
1526{
1527 struct interface *ifp;
1528 struct rip_interface *ri;
1529
1530 ifp = (struct interface *)vty->index;
1531 ri = ifp->info;
1532
1533 ri->ri_send = RI_RIP_UNSPEC;
1534 return CMD_SUCCESS;
1535}
1536
1537ALIAS (no_ip_rip_send_version,
1538 no_ip_rip_send_version_num_cmd,
1539 "no ip rip send version (1|2)",
1540 NO_STR
1541 IP_STR
1542 "Routing Information Protocol\n"
1543 "Advertisement transmission\n"
1544 "Version control\n"
1545 "Version 1\n"
1546 "Version 2\n")
1547
1548DEFUN (ip_rip_authentication_mode,
1549 ip_rip_authentication_mode_cmd,
1550 "ip rip authentication mode (md5|text)",
1551 IP_STR
1552 "Routing Information Protocol\n"
1553 "Authentication control\n"
1554 "Authentication mode\n"
1555 "Keyed message digest\n"
1556 "Clear text authentication\n")
1557{
1558 struct interface *ifp;
1559 struct rip_interface *ri;
Paul Jakma15a2b082006-05-04 07:36:34 +00001560 int auth_type;
paul718e3742002-12-13 20:15:29 +00001561
1562 ifp = (struct interface *)vty->index;
1563 ri = ifp->info;
1564
paulca5e5162004-06-06 22:06:33 +00001565 if ( (argc < 1) || (argc > 2) )
1566 {
1567 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1568 return CMD_WARNING;
1569 }
1570
paul718e3742002-12-13 20:15:29 +00001571 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001572 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001573 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001574 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001575 else
1576 {
1577 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1578 return CMD_WARNING;
1579 }
1580
paulca5e5162004-06-06 22:06:33 +00001581 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001582 {
1583 ri->auth_type = auth_type;
1584 return CMD_SUCCESS;
1585 }
paulca5e5162004-06-06 22:06:33 +00001586
Paul Jakma15a2b082006-05-04 07:36:34 +00001587 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001588 {
1589 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1590 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001591 }
paulca5e5162004-06-06 22:06:33 +00001592
1593 if (strncmp ("r", argv[1], 1) == 0)
1594 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1595 else if (strncmp ("o", argv[1], 1) == 0)
1596 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1597 else
1598 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001599
1600 ri->auth_type = auth_type;
1601
paul718e3742002-12-13 20:15:29 +00001602 return CMD_SUCCESS;
1603}
1604
paulca5e5162004-06-06 22:06:33 +00001605ALIAS (ip_rip_authentication_mode,
1606 ip_rip_authentication_mode_authlen_cmd,
1607 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1608 IP_STR
1609 "Routing Information Protocol\n"
1610 "Authentication control\n"
1611 "Authentication mode\n"
1612 "Keyed message digest\n"
1613 "Clear text authentication\n"
1614 "MD5 authentication data length\n"
1615 "RFC compatible\n"
1616 "Old ripd compatible\n")
1617
paul718e3742002-12-13 20:15:29 +00001618DEFUN (no_ip_rip_authentication_mode,
1619 no_ip_rip_authentication_mode_cmd,
1620 "no ip rip authentication mode",
1621 NO_STR
1622 IP_STR
1623 "Routing Information Protocol\n"
1624 "Authentication control\n"
1625 "Authentication mode\n")
1626{
1627 struct interface *ifp;
1628 struct rip_interface *ri;
1629
1630 ifp = (struct interface *)vty->index;
1631 ri = ifp->info;
1632
paul7755a8c2005-06-02 08:20:53 +00001633 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001634 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001635
1636 return CMD_SUCCESS;
1637}
1638
1639ALIAS (no_ip_rip_authentication_mode,
1640 no_ip_rip_authentication_mode_type_cmd,
1641 "no ip rip authentication mode (md5|text)",
1642 NO_STR
1643 IP_STR
1644 "Routing Information Protocol\n"
1645 "Authentication control\n"
1646 "Authentication mode\n"
1647 "Keyed message digest\n"
1648 "Clear text authentication\n")
1649
paulca5e5162004-06-06 22:06:33 +00001650ALIAS (no_ip_rip_authentication_mode,
1651 no_ip_rip_authentication_mode_type_authlen_cmd,
1652 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1653 NO_STR
1654 IP_STR
1655 "Routing Information Protocol\n"
1656 "Authentication control\n"
1657 "Authentication mode\n"
1658 "Keyed message digest\n"
1659 "Clear text authentication\n"
1660 "MD5 authentication data length\n"
1661 "RFC compatible\n"
1662 "Old ripd compatible\n")
1663
paul718e3742002-12-13 20:15:29 +00001664DEFUN (ip_rip_authentication_string,
1665 ip_rip_authentication_string_cmd,
1666 "ip rip authentication string LINE",
1667 IP_STR
1668 "Routing Information Protocol\n"
1669 "Authentication control\n"
1670 "Authentication string\n"
1671 "Authentication string\n")
1672{
1673 struct interface *ifp;
1674 struct rip_interface *ri;
1675
1676 ifp = (struct interface *)vty->index;
1677 ri = ifp->info;
1678
1679 if (strlen (argv[0]) > 16)
1680 {
1681 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1682 VTY_NEWLINE);
1683 return CMD_WARNING;
1684 }
1685
1686 if (ri->key_chain)
1687 {
1688 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1689 return CMD_WARNING;
1690 }
1691
1692 if (ri->auth_str)
1693 free (ri->auth_str);
1694
1695 ri->auth_str = strdup (argv[0]);
1696
1697 return CMD_SUCCESS;
1698}
1699
1700DEFUN (no_ip_rip_authentication_string,
1701 no_ip_rip_authentication_string_cmd,
1702 "no ip rip authentication string",
1703 NO_STR
1704 IP_STR
1705 "Routing Information Protocol\n"
1706 "Authentication control\n"
1707 "Authentication string\n")
1708{
1709 struct interface *ifp;
1710 struct rip_interface *ri;
1711
1712 ifp = (struct interface *)vty->index;
1713 ri = ifp->info;
1714
1715 if (ri->auth_str)
1716 free (ri->auth_str);
1717
1718 ri->auth_str = NULL;
1719
1720 return CMD_SUCCESS;
1721}
1722
1723ALIAS (no_ip_rip_authentication_string,
1724 no_ip_rip_authentication_string2_cmd,
1725 "no ip rip authentication string LINE",
1726 NO_STR
1727 IP_STR
1728 "Routing Information Protocol\n"
1729 "Authentication control\n"
1730 "Authentication string\n"
1731 "Authentication string\n")
1732
1733DEFUN (ip_rip_authentication_key_chain,
1734 ip_rip_authentication_key_chain_cmd,
1735 "ip rip authentication key-chain LINE",
1736 IP_STR
1737 "Routing Information Protocol\n"
1738 "Authentication control\n"
1739 "Authentication key-chain\n"
1740 "name of key-chain\n")
1741{
1742 struct interface *ifp;
1743 struct rip_interface *ri;
1744
1745 ifp = (struct interface *) vty->index;
1746 ri = ifp->info;
1747
1748 if (ri->auth_str)
1749 {
1750 vty_out (vty, "%% authentication string configuration exists%s",
1751 VTY_NEWLINE);
1752 return CMD_WARNING;
1753 }
1754
1755 if (ri->key_chain)
1756 free (ri->key_chain);
1757
1758 ri->key_chain = strdup (argv[0]);
1759
1760 return CMD_SUCCESS;
1761}
1762
1763DEFUN (no_ip_rip_authentication_key_chain,
1764 no_ip_rip_authentication_key_chain_cmd,
1765 "no ip rip authentication key-chain",
1766 NO_STR
1767 IP_STR
1768 "Routing Information Protocol\n"
1769 "Authentication control\n"
1770 "Authentication key-chain\n")
1771{
1772 struct interface *ifp;
1773 struct rip_interface *ri;
1774
1775 ifp = (struct interface *) vty->index;
1776 ri = ifp->info;
1777
1778 if (ri->key_chain)
1779 free (ri->key_chain);
1780
1781 ri->key_chain = NULL;
1782
1783 return CMD_SUCCESS;
1784}
1785
1786ALIAS (no_ip_rip_authentication_key_chain,
1787 no_ip_rip_authentication_key_chain2_cmd,
1788 "no ip rip authentication key-chain LINE",
1789 NO_STR
1790 IP_STR
1791 "Routing Information Protocol\n"
1792 "Authentication control\n"
1793 "Authentication key-chain\n"
1794 "name of key-chain\n")
1795
hasso16705132003-05-25 14:49:19 +00001796/* CHANGED: ip rip split-horizon
1797 Cisco and Zebra's command is
1798 ip split-horizon
1799 */
1800DEFUN (ip_rip_split_horizon,
1801 ip_rip_split_horizon_cmd,
1802 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001803 IP_STR
hasso16705132003-05-25 14:49:19 +00001804 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001805 "Perform split horizon\n")
1806{
1807 struct interface *ifp;
1808 struct rip_interface *ri;
1809
1810 ifp = vty->index;
1811 ri = ifp->info;
1812
hasso16705132003-05-25 14:49:19 +00001813 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001814 return CMD_SUCCESS;
1815}
1816
hasso16705132003-05-25 14:49:19 +00001817DEFUN (ip_rip_split_horizon_poisoned_reverse,
1818 ip_rip_split_horizon_poisoned_reverse_cmd,
1819 "ip rip split-horizon poisoned-reverse",
1820 IP_STR
1821 "Routing Information Protocol\n"
1822 "Perform split horizon\n"
1823 "With poisoned-reverse\n")
1824{
1825 struct interface *ifp;
1826 struct rip_interface *ri;
1827
1828 ifp = vty->index;
1829 ri = ifp->info;
1830
1831 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1832 return CMD_SUCCESS;
1833}
1834
1835/* CHANGED: no ip rip split-horizon
1836 Cisco and Zebra's command is
1837 no ip split-horizon
1838 */
1839DEFUN (no_ip_rip_split_horizon,
1840 no_ip_rip_split_horizon_cmd,
1841 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001842 NO_STR
1843 IP_STR
hasso16705132003-05-25 14:49:19 +00001844 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001845 "Perform split horizon\n")
1846{
1847 struct interface *ifp;
1848 struct rip_interface *ri;
1849
1850 ifp = vty->index;
1851 ri = ifp->info;
1852
hasso16705132003-05-25 14:49:19 +00001853 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001854 return CMD_SUCCESS;
1855}
1856
vincentfac3e842005-10-06 07:45:43 +00001857DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001858 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1859 "no ip rip split-horizon poisoned-reverse",
1860 NO_STR
1861 IP_STR
1862 "Routing Information Protocol\n"
1863 "Perform split horizon\n"
1864 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001865{
1866 struct interface *ifp;
1867 struct rip_interface *ri;
1868
1869 ifp = vty->index;
1870 ri = ifp->info;
1871
1872 switch( ri->split_horizon )
1873 {
1874 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1875 ri->split_horizon = RIP_SPLIT_HORIZON;
1876 default:
1877 break;
1878 }
1879
1880 return CMD_SUCCESS;
1881}
hasso16705132003-05-25 14:49:19 +00001882
paul718e3742002-12-13 20:15:29 +00001883DEFUN (rip_passive_interface,
1884 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001885 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001886 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001887 "Interface name\n"
1888 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001889{
hasso98b718a2004-10-11 12:57:57 +00001890 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001891
1892 if (!strcmp(ifname,"default")) {
1893 passive_default = 1;
1894 rip_passive_nondefault_clean();
1895 return CMD_SUCCESS;
1896 }
1897 if (passive_default)
1898 return rip_passive_nondefault_unset (vty, ifname);
1899 else
1900 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001901}
1902
1903DEFUN (no_rip_passive_interface,
1904 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001905 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001906 NO_STR
1907 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001908 "Interface name\n"
1909 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001910{
hasso98b718a2004-10-11 12:57:57 +00001911 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001912
1913 if (!strcmp(ifname,"default")) {
1914 passive_default = 0;
1915 rip_passive_nondefault_clean();
1916 return CMD_SUCCESS;
1917 }
1918 if (passive_default)
1919 return rip_passive_nondefault_set (vty, ifname);
1920 else
1921 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001922}
1923
1924/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001925static int
paul718e3742002-12-13 20:15:29 +00001926rip_interface_config_write (struct vty *vty)
1927{
hasso52dc7ee2004-09-23 19:18:23 +00001928 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001929 struct interface *ifp;
1930
paul1eb8ef22005-04-07 07:30:20 +00001931 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001932 {
1933 struct rip_interface *ri;
1934
paul718e3742002-12-13 20:15:29 +00001935 ri = ifp->info;
1936
hasso16705132003-05-25 14:49:19 +00001937 /* Do not display the interface if there is no
1938 * configuration about it.
1939 **/
1940 if ((!ifp->desc) &&
1941 (ri->split_horizon == ri->split_horizon_default) &&
1942 (ri->ri_send == RI_RIP_UNSPEC) &&
1943 (ri->ri_receive == RI_RIP_UNSPEC) &&
1944 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001945 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001946 (!ri->auth_str) &&
1947 (!ri->key_chain) )
1948 continue;
1949
paul718e3742002-12-13 20:15:29 +00001950 vty_out (vty, "interface %s%s", ifp->name,
1951 VTY_NEWLINE);
1952
1953 if (ifp->desc)
1954 vty_out (vty, " description %s%s", ifp->desc,
1955 VTY_NEWLINE);
1956
1957 /* Split horizon. */
1958 if (ri->split_horizon != ri->split_horizon_default)
1959 {
hasso16705132003-05-25 14:49:19 +00001960 switch (ri->split_horizon) {
1961 case RIP_SPLIT_HORIZON:
1962 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1963 break;
1964 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1965 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1966 VTY_NEWLINE);
1967 break;
1968 case RIP_NO_SPLIT_HORIZON:
1969 default:
1970 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1971 break;
1972 }
paul718e3742002-12-13 20:15:29 +00001973 }
1974
1975 /* RIP version setting. */
1976 if (ri->ri_send != RI_RIP_UNSPEC)
1977 vty_out (vty, " ip rip send version %s%s",
1978 lookup (ri_version_msg, ri->ri_send),
1979 VTY_NEWLINE);
1980
1981 if (ri->ri_receive != RI_RIP_UNSPEC)
1982 vty_out (vty, " ip rip receive version %s%s",
1983 lookup (ri_version_msg, ri->ri_receive),
1984 VTY_NEWLINE);
1985
1986 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001987 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1988 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001989
paul718e3742002-12-13 20:15:29 +00001990 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001991 {
1992 vty_out (vty, " ip rip authentication mode md5");
1993 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1994 vty_out (vty, " auth-length old-ripd");
1995 else
1996 vty_out (vty, " auth-length rfc");
1997 vty_out (vty, "%s", VTY_NEWLINE);
1998 }
paul718e3742002-12-13 20:15:29 +00001999
2000 if (ri->auth_str)
2001 vty_out (vty, " ip rip authentication string %s%s",
2002 ri->auth_str, VTY_NEWLINE);
2003
2004 if (ri->key_chain)
2005 vty_out (vty, " ip rip authentication key-chain %s%s",
2006 ri->key_chain, VTY_NEWLINE);
2007
2008 vty_out (vty, "!%s", VTY_NEWLINE);
2009 }
2010 return 0;
2011}
2012
2013int
2014config_write_rip_network (struct vty *vty, int config_mode)
2015{
hasso8a676be2004-10-08 06:36:38 +00002016 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002017 char *ifname;
2018 struct route_node *node;
2019
2020 /* Network type RIP enable interface statement. */
2021 for (node = route_top (rip_enable_network); node; node = route_next (node))
2022 if (node->info)
2023 vty_out (vty, "%s%s/%d%s",
2024 config_mode ? " network " : " ",
2025 inet_ntoa (node->p.u.prefix4),
2026 node->p.prefixlen,
2027 VTY_NEWLINE);
2028
2029 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002030 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002031 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2032 vty_out (vty, "%s%s%s",
2033 config_mode ? " network " : " ",
2034 ifname,
2035 VTY_NEWLINE);
2036
2037 /* RIP neighbors listing. */
2038 for (node = route_top (rip->neighbor); node; node = route_next (node))
2039 if (node->info)
2040 vty_out (vty, "%s%s%s",
2041 config_mode ? " neighbor " : " ",
2042 inet_ntoa (node->p.u.prefix4),
2043 VTY_NEWLINE);
2044
2045 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002046 if (config_mode) {
2047 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002048 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002049 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002050 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2051 vty_out (vty, " %spassive-interface %s%s",
2052 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2053 }
paul718e3742002-12-13 20:15:29 +00002054
2055 return 0;
2056}
2057
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002058static struct cmd_node interface_node =
paul718e3742002-12-13 20:15:29 +00002059{
2060 INTERFACE_NODE,
2061 "%s(config-if)# ",
2062 1,
2063};
2064
2065/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002066static int
paul718e3742002-12-13 20:15:29 +00002067rip_interface_new_hook (struct interface *ifp)
2068{
2069 ifp->info = rip_interface_new ();
2070 return 0;
2071}
2072
2073/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002074static int
paul718e3742002-12-13 20:15:29 +00002075rip_interface_delete_hook (struct interface *ifp)
2076{
2077 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002078 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002079 return 0;
2080}
2081
2082/* Allocate and initialize interface vector. */
2083void
pauldc63bfd2005-10-25 23:31:05 +00002084rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002085{
2086 /* Default initial size of interface vector. */
2087 if_init();
2088 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2089 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2090
2091 /* RIP network init. */
2092 rip_enable_interface = vector_init (1);
2093 rip_enable_network = route_table_init ();
2094
2095 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002096 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002097
2098 /* Install interface node. */
2099 install_node (&interface_node, rip_interface_config_write);
2100
2101 /* Install commands. */
2102 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002103 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002104 install_default (INTERFACE_NODE);
2105 install_element (INTERFACE_NODE, &interface_desc_cmd);
2106 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2107 install_element (RIP_NODE, &rip_network_cmd);
2108 install_element (RIP_NODE, &no_rip_network_cmd);
2109 install_element (RIP_NODE, &rip_neighbor_cmd);
2110 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2111
2112 install_element (RIP_NODE, &rip_passive_interface_cmd);
2113 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2114
2115 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2116 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2117 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2118 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2119 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2120
2121 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2122 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2123 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2124 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2125 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2126
2127 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002128 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002129 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2130 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002131 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002132
2133 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2134 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2135 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2136
2137 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2138 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2139 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2140
hasso16705132003-05-25 14:49:19 +00002141 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2142 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2143 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2144 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002145}