blob: 810b71c0db5ed7a0ea78db491ed8f7264246a28c [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
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +040081 ret = setsockopt_ipv4_multicast (sock,
paul718e3742002-12-13 20:15:29 +000082 IP_ADD_MEMBERSHIP,
paul718e3742002-12-13 20:15:29 +000083 group.s_addr,
84 ifindex);
85
86 if (ret < 0)
87 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
ajs6099b3b2004-11-20 02:06:59 +000088 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +000089
90 return ret;
91}
92
93/* Leave from the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000094static int
paul718e3742002-12-13 20:15:29 +000095ipv4_multicast_leave (int sock,
96 struct in_addr group,
97 struct in_addr ifa,
98 unsigned int ifindex)
99{
100 int ret;
101
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +0400102 ret = setsockopt_ipv4_multicast (sock,
paul718e3742002-12-13 20:15:29 +0000103 IP_DROP_MEMBERSHIP,
paul718e3742002-12-13 20:15:29 +0000104 group.s_addr,
105 ifindex);
106
107 if (ret < 0)
108 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
109
110 return ret;
111}
112
113/* Allocate new RIP's interface configuration. */
pauldc63bfd2005-10-25 23:31:05 +0000114static struct rip_interface *
115rip_interface_new (void)
paul718e3742002-12-13 20:15:29 +0000116{
117 struct rip_interface *ri;
118
Stephen Hemminger393deb92008-08-18 14:13:29 -0700119 ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
paul718e3742002-12-13 20:15:29 +0000120
121 /* Default authentication type is simple password for Cisco
122 compatibility. */
paul7755a8c2005-06-02 08:20:53 +0000123 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +0000124 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +0000125
126 /* Set default split-horizon behavior. If the interface is Frame
127 Relay or SMDS is enabled, the default value for split-horizon is
128 off. But currently Zebra does detect Frame Relay or SMDS
129 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000130 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000131 ri->split_horizon = ri->split_horizon_default;
132
133 return ri;
134}
135
136void
paul1a517862004-08-19 04:03:08 +0000137rip_interface_multicast_set (int sock, struct connected *connected)
paul718e3742002-12-13 20:15:29 +0000138{
paulc49ad8f2004-10-22 10:27:28 +0000139 assert (connected != NULL);
140
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +0400141 if (setsockopt_ipv4_multicast_if (sock, connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000142 {
143 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +0400144 "ifindex %d for interface %s",
145 sock, connected->ifp->ifindex,
paulc49ad8f2004-10-22 10:27:28 +0000146 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000147 }
paul2c61ae32005-08-16 15:22:14 +0000148
hasso3fb9cd62004-10-19 19:44:43 +0000149 return;
150}
paul718e3742002-12-13 20:15:29 +0000151
152/* Send RIP request packet to specified interface. */
pauldc63bfd2005-10-25 23:31:05 +0000153static void
paul718e3742002-12-13 20:15:29 +0000154rip_request_interface_send (struct interface *ifp, u_char version)
155{
156 struct sockaddr_in to;
157
158 /* RIPv2 support multicast. */
159 if (version == RIPv2 && if_is_multicast (ifp))
160 {
161
162 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000163 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000164
paul931cd542004-01-23 15:31:42 +0000165 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000166 return;
167 }
168
169 /* RIPv1 and non multicast interface. */
170 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
171 {
paul1eb8ef22005-04-07 07:30:20 +0000172 struct listnode *cnode, *cnnode;
173 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000174
175 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000176 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000177
paul1eb8ef22005-04-07 07:30:20 +0000178 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000179 {
hasso3fb9cd62004-10-19 19:44:43 +0000180 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000181 {
182 memset (&to, 0, sizeof (struct sockaddr_in));
183 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000184 if (connected->destination)
Andrew J. Schorre4529632006-12-12 19:18:21 +0000185 /* use specified broadcast or peer destination addr */
hasso3fb9cd62004-10-19 19:44:43 +0000186 to.sin_addr = connected->destination->u.prefix4;
Andrew J. Schorre4529632006-12-12 19:18:21 +0000187 else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
hasso3fb9cd62004-10-19 19:44:43 +0000188 /* calculate the appropriate broadcast address */
189 to.sin_addr.s_addr =
190 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
191 connected->address->prefixlen);
Andrew J. Schorre4529632006-12-12 19:18:21 +0000192 else
193 /* do not know where to send the packet */
194 continue;
paul718e3742002-12-13 20:15:29 +0000195
paul718e3742002-12-13 20:15:29 +0000196 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000197 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000198
paul931cd542004-01-23 15:31:42 +0000199 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000200 }
201 }
202 }
203}
204
205/* This will be executed when interface goes up. */
pauldc63bfd2005-10-25 23:31:05 +0000206static void
paul718e3742002-12-13 20:15:29 +0000207rip_request_interface (struct interface *ifp)
208{
209 struct rip_interface *ri;
210
211 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
212 if (if_is_loopback (ifp))
213 return;
214
215 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000216 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000217 return;
218
219 /* Fetch RIP interface information. */
220 ri = ifp->info;
221
222
223 /* If there is no version configuration in the interface,
224 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000225 {
226 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
227 rip->version_send : ri->ri_send);
228 if (vsend & RIPv1)
229 rip_request_interface_send (ifp, RIPv1);
230 if (vsend & RIPv2)
231 rip_request_interface_send (ifp, RIPv2);
232 }
paul718e3742002-12-13 20:15:29 +0000233}
234
Stephen Hemminger2c239702009-12-10 19:16:05 +0300235#if 0
paul718e3742002-12-13 20:15:29 +0000236/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000237static void
paul718e3742002-12-13 20:15:29 +0000238rip_request_neighbor (struct in_addr addr)
239{
240 struct sockaddr_in to;
241
242 memset (&to, 0, sizeof (struct sockaddr_in));
243 to.sin_port = htons (RIP_PORT_DEFAULT);
244 to.sin_addr = addr;
245
paul931cd542004-01-23 15:31:42 +0000246 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000247}
248
249/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000250static void
251rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000252{
253 struct route_node *rp;
254
255 if (! rip)
256 return;
257
258 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000259 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000260
261 /* Send request to all neighbor. */
262 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
263 if (rp->info)
264 rip_request_neighbor (rp->p.u.prefix4);
265}
Stephen Hemminger2c239702009-12-10 19:16:05 +0300266#endif
paul718e3742002-12-13 20:15:29 +0000267
268/* Multicast packet receive socket. */
pauldc63bfd2005-10-25 23:31:05 +0000269static int
paul718e3742002-12-13 20:15:29 +0000270rip_multicast_join (struct interface *ifp, int sock)
271{
hasso52dc7ee2004-09-23 19:18:23 +0000272 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000273 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000274
paul2e3b2e42002-12-13 21:03:13 +0000275 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000276 {
277 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000278 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000279
paul1eb8ef22005-04-07 07:30:20 +0000280 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000281 {
282 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000283 struct in_addr group;
284
paul1eb8ef22005-04-07 07:30:20 +0000285 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000286
287 if (p->family != AF_INET)
288 continue;
289
290 group.s_addr = htonl (INADDR_RIP_GROUP);
291 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
292 return -1;
293 else
294 return 0;
295 }
296 }
297 return 0;
298}
299
300/* Leave from multicast group. */
pauldc63bfd2005-10-25 23:31:05 +0000301static void
paul718e3742002-12-13 20:15:29 +0000302rip_multicast_leave (struct interface *ifp, int sock)
303{
hasso52dc7ee2004-09-23 19:18:23 +0000304 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000305 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000306
307 if (if_is_up (ifp) && if_is_multicast (ifp))
308 {
309 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000310 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000311
paul1eb8ef22005-04-07 07:30:20 +0000312 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000313 {
314 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000315 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000316
paul718e3742002-12-13 20:15:29 +0000317 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000318
paul718e3742002-12-13 20:15:29 +0000319 if (p->family != AF_INET)
320 continue;
321
322 group.s_addr = htonl (INADDR_RIP_GROUP);
323 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
324 return;
325 }
326 }
327}
328
329/* Is there and address on interface that I could use ? */
pauldc63bfd2005-10-25 23:31:05 +0000330static int
paul718e3742002-12-13 20:15:29 +0000331rip_if_ipv4_address_check (struct interface *ifp)
332{
333 struct listnode *nn;
334 struct connected *connected;
335 int count = 0;
336
paul1eb8ef22005-04-07 07:30:20 +0000337 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
338 {
339 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000340
paul1eb8ef22005-04-07 07:30:20 +0000341 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000342
paul1eb8ef22005-04-07 07:30:20 +0000343 if (p->family == AF_INET)
344 count++;
345 }
paul718e3742002-12-13 20:15:29 +0000346
347 return count;
348}
paul31a476c2003-09-29 19:54:53 +0000349
350
351
352
353/* Does this address belongs to me ? */
354int
355if_check_address (struct in_addr addr)
356{
hasso52dc7ee2004-09-23 19:18:23 +0000357 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000358 struct interface *ifp;
359
360 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000361 {
hasso52dc7ee2004-09-23 19:18:23 +0000362 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000363 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000364
paul1eb8ef22005-04-07 07:30:20 +0000365 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000366 {
paul31a476c2003-09-29 19:54:53 +0000367 struct prefix_ipv4 *p;
368
paul31a476c2003-09-29 19:54:53 +0000369 p = (struct prefix_ipv4 *) connected->address;
370
371 if (p->family != AF_INET)
372 continue;
373
374 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
375 return 1;
376 }
377 }
378 return 0;
379}
380
paul718e3742002-12-13 20:15:29 +0000381/* Inteface link down message processing. */
382int
383rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
384{
385 struct interface *ifp;
386 struct stream *s;
387
388 s = zclient->ibuf;
389
390 /* zebra_interface_state_read() updates interface structure in
391 iflist. */
392 ifp = zebra_interface_state_read(s);
393
394 if (ifp == NULL)
395 return 0;
396
397 rip_if_down(ifp);
398
399 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger30d20592009-07-28 11:58:51 +0100400 zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down",
401 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
402 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000403
404 return 0;
405}
406
407/* Inteface link up message processing */
408int
409rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
410{
411 struct interface *ifp;
412
413 /* zebra_interface_state_read () updates interface structure in
414 iflist. */
415 ifp = zebra_interface_state_read (zclient->ibuf);
416
417 if (ifp == NULL)
418 return 0;
419
420 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300421 zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up",
422 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
423 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000424
425 /* Check if this interface is RIP enabled or not.*/
426 rip_enable_apply (ifp);
427
428 /* Check for a passive interface */
429 rip_passive_interface_apply (ifp);
430
431 /* Apply distribute list to the all interface. */
432 rip_distribute_update_interface (ifp);
433
434 return 0;
435}
436
437/* Inteface addition message from zebra. */
438int
439rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
440{
441 struct interface *ifp;
442
443 ifp = zebra_interface_add_read (zclient->ibuf);
444
445 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300446 zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d",
447 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
448 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000449
450 /* Check if this interface is RIP enabled or not.*/
451 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000452
453 /* Check for a passive interface */
454 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000455
456 /* Apply distribute list to the all interface. */
457 rip_distribute_update_interface (ifp);
458
459 /* rip_request_neighbor_all (); */
460
hasso16705132003-05-25 14:49:19 +0000461 /* Check interface routemap. */
462 rip_if_rmap_update_interface (ifp);
463
paul718e3742002-12-13 20:15:29 +0000464 return 0;
465}
466
467int
468rip_interface_delete (int command, struct zclient *zclient,
469 zebra_size_t length)
470{
471 struct interface *ifp;
472 struct stream *s;
473
474
475 s = zclient->ibuf;
476 /* zebra_interface_state_read() updates interface structure in iflist */
477 ifp = zebra_interface_state_read(s);
478
479 if (ifp == NULL)
480 return 0;
481
482 if (if_is_up (ifp)) {
483 rip_if_down(ifp);
484 }
485
Stephen Hemminger2c239702009-12-10 19:16:05 +0300486 zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
487 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
488 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000489
490 /* To support pseudo interface do not free interface structure. */
491 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000492 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000493
494 return 0;
495}
496
497void
pauldc63bfd2005-10-25 23:31:05 +0000498rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000499{
hasso52dc7ee2004-09-23 19:18:23 +0000500 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000501 struct interface *ifp;
502 struct rip_interface *ri;
503
paul1eb8ef22005-04-07 07:30:20 +0000504 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000505 {
paul718e3742002-12-13 20:15:29 +0000506 ri = ifp->info;
507
508 ri->enable_network = 0;
509 ri->enable_interface = 0;
510 ri->running = 0;
511
512 if (ri->t_wakeup)
513 {
514 thread_cancel (ri->t_wakeup);
515 ri->t_wakeup = NULL;
516 }
517 }
518}
519
520void
pauldc63bfd2005-10-25 23:31:05 +0000521rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000522{
hasso52dc7ee2004-09-23 19:18:23 +0000523 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000524 struct interface *ifp;
525 struct rip_interface *ri;
526
paul1eb8ef22005-04-07 07:30:20 +0000527 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000528 {
paul718e3742002-12-13 20:15:29 +0000529 ri = ifp->info;
530
531 ri->enable_network = 0;
532 ri->enable_interface = 0;
533 ri->running = 0;
534
535 ri->ri_send = RI_RIP_UNSPEC;
536 ri->ri_receive = RI_RIP_UNSPEC;
537
paul7755a8c2005-06-02 08:20:53 +0000538 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000539
540 if (ri->auth_str)
541 {
542 free (ri->auth_str);
543 ri->auth_str = NULL;
544 }
545 if (ri->key_chain)
546 {
547 free (ri->key_chain);
548 ri->key_chain = NULL;
549 }
550
hasso16705132003-05-25 14:49:19 +0000551 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
552 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000553
554 ri->list[RIP_FILTER_IN] = NULL;
555 ri->list[RIP_FILTER_OUT] = NULL;
556
557 ri->prefix[RIP_FILTER_IN] = NULL;
558 ri->prefix[RIP_FILTER_OUT] = NULL;
559
560 if (ri->t_wakeup)
561 {
562 thread_cancel (ri->t_wakeup);
563 ri->t_wakeup = NULL;
564 }
565
566 ri->recv_badpackets = 0;
567 ri->recv_badroutes = 0;
568 ri->sent_updates = 0;
569
570 ri->passive = 0;
571 }
572}
573
574int
575rip_if_down(struct interface *ifp)
576{
577 struct route_node *rp;
578 struct rip_info *rinfo;
579 struct rip_interface *ri = NULL;
580 if (rip)
581 {
582 for (rp = route_top (rip->table); rp; rp = route_next (rp))
583 if ((rinfo = rp->info) != NULL)
584 {
585 /* Routes got through this interface. */
586 if (rinfo->ifindex == ifp->ifindex &&
587 rinfo->type == ZEBRA_ROUTE_RIP &&
588 rinfo->sub_type == RIP_ROUTE_RTE)
589 {
590 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
591 &rinfo->nexthop,
Krisztian Kovacsc5a89ff2009-06-02 18:09:48 +0100592 rinfo->metric);
paul718e3742002-12-13 20:15:29 +0000593
594 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
595 (struct prefix_ipv4 *)&rp->p,
596 rinfo->ifindex);
597 }
598 else
599 {
600 /* All redistributed routes but static and system */
601 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000602 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000603 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
604 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
605 (struct prefix_ipv4 *)&rp->p,
606 rinfo->ifindex);
607 }
608 }
609 }
610
611 ri = ifp->info;
612
613 if (ri->running)
614 {
615 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000616 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000617
618 /* Leave from multicast group. */
619 rip_multicast_leave (ifp, rip->sock);
620
621 ri->running = 0;
622 }
623
624 return 0;
625}
626
627/* Needed for stop RIP process. */
628void
629rip_if_down_all ()
630{
631 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000632 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000633
paul1eb8ef22005-04-07 07:30:20 +0000634 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
635 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000636}
637
hasso16705132003-05-25 14:49:19 +0000638static void
pauldc63bfd2005-10-25 23:31:05 +0000639rip_apply_address_add (struct connected *ifc)
640{
hasso16705132003-05-25 14:49:19 +0000641 struct prefix_ipv4 address;
642 struct prefix *p;
643
644 if (!rip)
645 return;
646
647 if (! if_is_up(ifc->ifp))
648 return;
649
650 p = ifc->address;
651
652 memset (&address, 0, sizeof (address));
653 address.family = p->family;
654 address.prefix = p->u.prefix4;
655 address.prefixlen = p->prefixlen;
656 apply_mask_ipv4(&address);
657
658 /* Check if this interface is RIP enabled or not
659 or Check if this address's prefix is RIP enabled */
660 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
661 (rip_enable_network_lookup2(ifc) >= 0))
662 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000663 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000664
665}
666
paul718e3742002-12-13 20:15:29 +0000667int
668rip_interface_address_add (int command, struct zclient *zclient,
669 zebra_size_t length)
670{
671 struct connected *ifc;
672 struct prefix *p;
673
paul0a589352004-05-08 11:48:26 +0000674 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
675 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000676
677 if (ifc == NULL)
678 return 0;
679
680 p = ifc->address;
681
682 if (p->family == AF_INET)
683 {
684 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000685 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000686 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000687
paul878ef2e2003-09-23 23:41:50 +0000688 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000689 /* Check if this prefix needs to be redistributed */
690 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000691
692#ifdef HAVE_SNMP
693 rip_ifaddr_add (ifc->ifp, ifc);
694#endif /* HAVE_SNMP */
695 }
696
697 return 0;
698}
699
hasso16705132003-05-25 14:49:19 +0000700static void
701rip_apply_address_del (struct connected *ifc) {
702 struct prefix_ipv4 address;
703 struct prefix *p;
704
705 if (!rip)
706 return;
707
708 if (! if_is_up(ifc->ifp))
709 return;
710
711 p = ifc->address;
712
713 memset (&address, 0, sizeof (address));
714 address.family = p->family;
715 address.prefix = p->u.prefix4;
716 address.prefixlen = p->prefixlen;
717 apply_mask_ipv4(&address);
718
719 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
720 &address, ifc->ifp->ifindex);
721}
722
paul718e3742002-12-13 20:15:29 +0000723int
724rip_interface_address_delete (int command, struct zclient *zclient,
725 zebra_size_t length)
726{
727 struct connected *ifc;
728 struct prefix *p;
729
paul0a589352004-05-08 11:48:26 +0000730 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
731 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000732
733 if (ifc)
734 {
735 p = ifc->address;
736 if (p->family == AF_INET)
737 {
738 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000739 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000740 inet_ntoa (p->u.prefix4), p->prefixlen);
741
742#ifdef HAVE_SNMP
743 rip_ifaddr_delete (ifc->ifp, ifc);
744#endif /* HAVE_SNMP */
745
hasso16705132003-05-25 14:49:19 +0000746 /* Chech wether this prefix needs to be removed */
747 rip_apply_address_del(ifc);
748
paul718e3742002-12-13 20:15:29 +0000749 }
750
751 connected_free (ifc);
752
753 }
754
755 return 0;
756}
757
758/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000759/* Check wether the interface has at least a connected prefix that
760 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000761static int
hasso16705132003-05-25 14:49:19 +0000762rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000763{
paul1eb8ef22005-04-07 07:30:20 +0000764 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000765 struct connected *connected;
766 struct prefix_ipv4 address;
767
paul1eb8ef22005-04-07 07:30:20 +0000768 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
769 {
770 struct prefix *p;
771 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000772
paul1eb8ef22005-04-07 07:30:20 +0000773 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000774
paul1eb8ef22005-04-07 07:30:20 +0000775 if (p->family == AF_INET)
776 {
777 address.family = AF_INET;
778 address.prefix = p->u.prefix4;
779 address.prefixlen = IPV4_MAX_BITLEN;
780
781 node = route_node_match (rip_enable_network,
782 (struct prefix *)&address);
783 if (node)
784 {
785 route_unlock_node (node);
786 return 1;
787 }
788 }
789 }
paul718e3742002-12-13 20:15:29 +0000790 return -1;
791}
792
hasso16705132003-05-25 14:49:19 +0000793/* Check wether connected is within the ripng_enable_network table. */
794int
795rip_enable_network_lookup2 (struct connected *connected)
796{
797 struct prefix_ipv4 address;
798 struct prefix *p;
799
800 p = connected->address;
801
802 if (p->family == AF_INET) {
803 struct route_node *node;
804
805 address.family = p->family;
806 address.prefix = p->u.prefix4;
807 address.prefixlen = IPV4_MAX_BITLEN;
808
809 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
810 node = route_node_match (rip_enable_network,
811 (struct prefix *)&address);
812
813 if (node) {
814 route_unlock_node (node);
815 return 1;
816 }
817 }
818
819 return -1;
820}
paul718e3742002-12-13 20:15:29 +0000821/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000822static int
paul718e3742002-12-13 20:15:29 +0000823rip_enable_network_add (struct prefix *p)
824{
825 struct route_node *node;
826
827 node = route_node_get (rip_enable_network, p);
828
829 if (node->info)
830 {
831 route_unlock_node (node);
832 return -1;
833 }
834 else
hasso8a676be2004-10-08 06:36:38 +0000835 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000836
hasso16705132003-05-25 14:49:19 +0000837 /* XXX: One should find a better solution than a generic one */
838 rip_enable_apply_all();
839
paul718e3742002-12-13 20:15:29 +0000840 return 1;
841}
842
843/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000844static int
paul718e3742002-12-13 20:15:29 +0000845rip_enable_network_delete (struct prefix *p)
846{
847 struct route_node *node;
848
849 node = route_node_lookup (rip_enable_network, p);
850 if (node)
851 {
852 node->info = NULL;
853
854 /* Unlock info lock. */
855 route_unlock_node (node);
856
857 /* Unlock lookup lock. */
858 route_unlock_node (node);
859
hasso16705132003-05-25 14:49:19 +0000860 /* XXX: One should find a better solution than a generic one */
861 rip_enable_apply_all ();
862
paul718e3742002-12-13 20:15:29 +0000863 return 1;
864 }
865 return -1;
866}
867
868/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000869static int
hasso98b718a2004-10-11 12:57:57 +0000870rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000871{
hasso8a676be2004-10-08 06:36:38 +0000872 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000873 char *str;
874
paul55468c82005-03-14 20:19:01 +0000875 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000876 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
877 if (strcmp (str, ifname) == 0)
878 return i;
879 return -1;
880}
881
882/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000883static int
hasso98b718a2004-10-11 12:57:57 +0000884rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000885{
886 int ret;
887
888 ret = rip_enable_if_lookup (ifname);
889 if (ret >= 0)
890 return -1;
891
892 vector_set (rip_enable_interface, strdup (ifname));
893
hasso16705132003-05-25 14:49:19 +0000894 rip_enable_apply_all(); /* TODOVJ */
895
paul718e3742002-12-13 20:15:29 +0000896 return 1;
897}
898
899/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000900static int
hasso98b718a2004-10-11 12:57:57 +0000901rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000902{
903 int index;
904 char *str;
905
906 index = rip_enable_if_lookup (ifname);
907 if (index < 0)
908 return -1;
909
910 str = vector_slot (rip_enable_interface, index);
911 free (str);
912 vector_unset (rip_enable_interface, index);
913
hasso16705132003-05-25 14:49:19 +0000914 rip_enable_apply_all(); /* TODOVJ */
915
paul718e3742002-12-13 20:15:29 +0000916 return 1;
917}
918
919/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000920static int
paul718e3742002-12-13 20:15:29 +0000921rip_interface_wakeup (struct thread *t)
922{
923 struct interface *ifp;
924 struct rip_interface *ri;
925
926 /* Get interface. */
927 ifp = THREAD_ARG (t);
928
929 ri = ifp->info;
930 ri->t_wakeup = NULL;
931
932 /* Join to multicast group. */
933 if (rip_multicast_join (ifp, rip->sock) < 0)
934 {
935 zlog_err ("multicast join failed, interface %s not running", ifp->name);
936 return 0;
937 }
938
939 /* Set running flag. */
940 ri->running = 1;
941
942 /* Send RIP request to the interface. */
943 rip_request_interface (ifp);
944
945 return 0;
946}
947
pauldc63bfd2005-10-25 23:31:05 +0000948static void
paul718e3742002-12-13 20:15:29 +0000949rip_connect_set (struct interface *ifp, int set)
950{
paul1eb8ef22005-04-07 07:30:20 +0000951 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000952 struct connected *connected;
953 struct prefix_ipv4 address;
954
paul1eb8ef22005-04-07 07:30:20 +0000955 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
956 {
957 struct prefix *p;
958 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000959
paul1eb8ef22005-04-07 07:30:20 +0000960 if (p->family != AF_INET)
961 continue;
paul718e3742002-12-13 20:15:29 +0000962
paul1eb8ef22005-04-07 07:30:20 +0000963 address.family = AF_INET;
964 address.prefix = p->u.prefix4;
965 address.prefixlen = p->prefixlen;
966 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000967
paul1eb8ef22005-04-07 07:30:20 +0000968 if (set) {
969 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
970 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
971 (rip_enable_network_lookup2(connected) >= 0))
972 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000973 &address, connected->ifp->ifindex,
974 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000975 } else
976 {
977 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
978 &address, connected->ifp->ifindex);
979 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
980 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000981 &address, connected->ifp->ifindex,
982 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000983 }
984 }
paul718e3742002-12-13 20:15:29 +0000985}
986
987/* Update interface status. */
988void
989rip_enable_apply (struct interface *ifp)
990{
991 int ret;
992 struct rip_interface *ri = NULL;
993
994 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +0000995 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000996 return;
997
998 ri = ifp->info;
999
1000 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001001 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001002
1003 /* If the interface is matched. */
1004 if (ret > 0)
1005 ri->enable_network = 1;
1006 else
1007 ri->enable_network = 0;
1008
1009 /* Check interface name configuration. */
1010 ret = rip_enable_if_lookup (ifp->name);
1011 if (ret >= 0)
1012 ri->enable_interface = 1;
1013 else
1014 ri->enable_interface = 0;
1015
1016 /* any interface MUST have an IPv4 address */
1017 if ( ! rip_if_ipv4_address_check (ifp) )
1018 {
1019 ri->enable_network = 0;
1020 ri->enable_interface = 0;
1021 }
1022
1023 /* Update running status of the interface. */
1024 if (ri->enable_network || ri->enable_interface)
1025 {
paul718e3742002-12-13 20:15:29 +00001026 {
1027 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001028 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001029
1030 /* Add interface wake up thread. */
1031 if (! ri->t_wakeup)
1032 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1033 ifp, 1);
1034 rip_connect_set (ifp, 1);
1035 }
1036 }
1037 else
1038 {
1039 if (ri->running)
1040 {
hasso16705132003-05-25 14:49:19 +00001041 /* Might as well clean up the route table as well
1042 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1043 **/
paul718e3742002-12-13 20:15:29 +00001044 rip_if_down(ifp);
1045
paul718e3742002-12-13 20:15:29 +00001046 rip_connect_set (ifp, 0);
1047 }
1048 }
1049}
1050
1051/* Apply network configuration to all interface. */
1052void
1053rip_enable_apply_all ()
1054{
1055 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001056 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001057
1058 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001059 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1060 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001061}
1062
1063int
1064rip_neighbor_lookup (struct sockaddr_in *from)
1065{
1066 struct prefix_ipv4 p;
1067 struct route_node *node;
1068
1069 memset (&p, 0, sizeof (struct prefix_ipv4));
1070 p.family = AF_INET;
1071 p.prefix = from->sin_addr;
1072 p.prefixlen = IPV4_MAX_BITLEN;
1073
1074 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1075 if (node)
1076 {
1077 route_unlock_node (node);
1078 return 1;
1079 }
1080 return 0;
1081}
1082
1083/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001084static int
paul718e3742002-12-13 20:15:29 +00001085rip_neighbor_add (struct prefix_ipv4 *p)
1086{
1087 struct route_node *node;
1088
1089 node = route_node_get (rip->neighbor, (struct prefix *) p);
1090
1091 if (node->info)
1092 return -1;
1093
1094 node->info = rip->neighbor;
1095
1096 return 0;
1097}
1098
1099/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001100static int
paul718e3742002-12-13 20:15:29 +00001101rip_neighbor_delete (struct prefix_ipv4 *p)
1102{
1103 struct route_node *node;
1104
1105 /* Lock for look up. */
1106 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1107 if (! node)
1108 return -1;
1109
1110 node->info = NULL;
1111
1112 /* Unlock lookup lock. */
1113 route_unlock_node (node);
1114
1115 /* Unlock real neighbor information lock. */
1116 route_unlock_node (node);
1117
1118 return 0;
1119}
1120
1121/* Clear all network and neighbor configuration. */
1122void
1123rip_clean_network ()
1124{
hasso8a676be2004-10-08 06:36:38 +00001125 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001126 char *str;
1127 struct route_node *rn;
1128
1129 /* rip_enable_network. */
1130 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1131 if (rn->info)
1132 {
1133 rn->info = NULL;
1134 route_unlock_node (rn);
1135 }
1136
1137 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001138 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001139 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1140 {
1141 free (str);
1142 vector_slot (rip_enable_interface, i) = NULL;
1143 }
1144}
1145
1146/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001147static int
hasso98b718a2004-10-11 12:57:57 +00001148rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001149{
hasso8a676be2004-10-08 06:36:38 +00001150 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001151 char *str;
1152
paul55468c82005-03-14 20:19:01 +00001153 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001154 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001155 if (strcmp (str, ifname) == 0)
1156 return i;
1157 return -1;
1158}
1159
1160void
1161rip_passive_interface_apply (struct interface *ifp)
1162{
paul718e3742002-12-13 20:15:29 +00001163 struct rip_interface *ri;
1164
1165 ri = ifp->info;
1166
paul4aaff3f2003-06-07 01:04:45 +00001167 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1168 passive_default : !passive_default);
1169
1170 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001171 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001172}
1173
pauldc63bfd2005-10-25 23:31:05 +00001174static void
1175rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001176{
1177 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001178 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001179
paul1eb8ef22005-04-07 07:30:20 +00001180 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1181 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001182}
1183
1184/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001185static int
hasso98b718a2004-10-11 12:57:57 +00001186rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001187{
paul4aaff3f2003-06-07 01:04:45 +00001188 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001189 return CMD_WARNING;
1190
paul4aaff3f2003-06-07 01:04:45 +00001191 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001192
1193 rip_passive_interface_apply_all ();
1194
1195 return CMD_SUCCESS;
1196}
1197
pauldc63bfd2005-10-25 23:31:05 +00001198static int
hasso98b718a2004-10-11 12:57:57 +00001199rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001200{
1201 int i;
1202 char *str;
1203
paul4aaff3f2003-06-07 01:04:45 +00001204 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001205 if (i < 0)
1206 return CMD_WARNING;
1207
paul4aaff3f2003-06-07 01:04:45 +00001208 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001209 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001210 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001211
1212 rip_passive_interface_apply_all ();
1213
1214 return CMD_SUCCESS;
1215}
1216
1217/* Free all configured RIP passive-interface settings. */
1218void
pauldc63bfd2005-10-25 23:31:05 +00001219rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001220{
hasso8a676be2004-10-08 06:36:38 +00001221 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001222 char *str;
1223
paul55468c82005-03-14 20:19:01 +00001224 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001225 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001226 {
1227 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001228 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001229 }
1230 rip_passive_interface_apply_all ();
1231}
1232
1233/* RIP enable network or interface configuration. */
1234DEFUN (rip_network,
1235 rip_network_cmd,
1236 "network (A.B.C.D/M|WORD)",
1237 "Enable routing on an IP network\n"
1238 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1239 "Interface name\n")
1240{
1241 int ret;
1242 struct prefix_ipv4 p;
1243
1244 ret = str2prefix_ipv4 (argv[0], &p);
1245
1246 if (ret)
1247 ret = rip_enable_network_add ((struct prefix *) &p);
1248 else
1249 ret = rip_enable_if_add (argv[0]);
1250
1251 if (ret < 0)
1252 {
1253 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1254 VTY_NEWLINE);
1255 return CMD_WARNING;
1256 }
1257
paul718e3742002-12-13 20:15:29 +00001258 return CMD_SUCCESS;
1259}
1260
1261/* RIP enable network or interface configuration. */
1262DEFUN (no_rip_network,
1263 no_rip_network_cmd,
1264 "no network (A.B.C.D/M|WORD)",
1265 NO_STR
1266 "Enable routing on an IP network\n"
1267 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1268 "Interface name\n")
1269{
1270 int ret;
1271 struct prefix_ipv4 p;
1272
1273 ret = str2prefix_ipv4 (argv[0], &p);
1274
1275 if (ret)
1276 ret = rip_enable_network_delete ((struct prefix *) &p);
1277 else
1278 ret = rip_enable_if_delete (argv[0]);
1279
1280 if (ret < 0)
1281 {
1282 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1283 VTY_NEWLINE);
1284 return CMD_WARNING;
1285 }
1286
paul718e3742002-12-13 20:15:29 +00001287 return CMD_SUCCESS;
1288}
1289
1290/* RIP neighbor configuration set. */
1291DEFUN (rip_neighbor,
1292 rip_neighbor_cmd,
1293 "neighbor A.B.C.D",
1294 "Specify a neighbor router\n"
1295 "Neighbor address\n")
1296{
1297 int ret;
1298 struct prefix_ipv4 p;
1299
1300 ret = str2prefix_ipv4 (argv[0], &p);
1301
1302 if (ret <= 0)
1303 {
1304 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1305 return CMD_WARNING;
1306 }
1307
1308 rip_neighbor_add (&p);
1309
1310 return CMD_SUCCESS;
1311}
1312
1313/* RIP neighbor configuration unset. */
1314DEFUN (no_rip_neighbor,
1315 no_rip_neighbor_cmd,
1316 "no neighbor A.B.C.D",
1317 NO_STR
1318 "Specify a neighbor router\n"
1319 "Neighbor address\n")
1320{
1321 int ret;
1322 struct prefix_ipv4 p;
1323
1324 ret = str2prefix_ipv4 (argv[0], &p);
1325
1326 if (ret <= 0)
1327 {
1328 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1329 return CMD_WARNING;
1330 }
1331
1332 rip_neighbor_delete (&p);
1333
1334 return CMD_SUCCESS;
1335}
1336
1337DEFUN (ip_rip_receive_version,
1338 ip_rip_receive_version_cmd,
1339 "ip rip receive version (1|2)",
1340 IP_STR
1341 "Routing Information Protocol\n"
1342 "Advertisement reception\n"
1343 "Version control\n"
1344 "RIP version 1\n"
1345 "RIP version 2\n")
1346{
1347 struct interface *ifp;
1348 struct rip_interface *ri;
1349
1350 ifp = (struct interface *)vty->index;
1351 ri = ifp->info;
1352
1353 /* Version 1. */
1354 if (atoi (argv[0]) == 1)
1355 {
1356 ri->ri_receive = RI_RIP_VERSION_1;
1357 return CMD_SUCCESS;
1358 }
1359 if (atoi (argv[0]) == 2)
1360 {
1361 ri->ri_receive = RI_RIP_VERSION_2;
1362 return CMD_SUCCESS;
1363 }
1364 return CMD_WARNING;
1365}
1366
1367DEFUN (ip_rip_receive_version_1,
1368 ip_rip_receive_version_1_cmd,
1369 "ip rip receive version 1 2",
1370 IP_STR
1371 "Routing Information Protocol\n"
1372 "Advertisement reception\n"
1373 "Version control\n"
1374 "RIP version 1\n"
1375 "RIP version 2\n")
1376{
1377 struct interface *ifp;
1378 struct rip_interface *ri;
1379
1380 ifp = (struct interface *)vty->index;
1381 ri = ifp->info;
1382
1383 /* Version 1 and 2. */
1384 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1385 return CMD_SUCCESS;
1386}
1387
1388DEFUN (ip_rip_receive_version_2,
1389 ip_rip_receive_version_2_cmd,
1390 "ip rip receive version 2 1",
1391 IP_STR
1392 "Routing Information Protocol\n"
1393 "Advertisement reception\n"
1394 "Version control\n"
1395 "RIP version 2\n"
1396 "RIP version 1\n")
1397{
1398 struct interface *ifp;
1399 struct rip_interface *ri;
1400
1401 ifp = (struct interface *)vty->index;
1402 ri = ifp->info;
1403
1404 /* Version 1 and 2. */
1405 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1406 return CMD_SUCCESS;
1407}
1408
1409DEFUN (no_ip_rip_receive_version,
1410 no_ip_rip_receive_version_cmd,
1411 "no ip rip receive version",
1412 NO_STR
1413 IP_STR
1414 "Routing Information Protocol\n"
1415 "Advertisement reception\n"
1416 "Version control\n")
1417{
1418 struct interface *ifp;
1419 struct rip_interface *ri;
1420
1421 ifp = (struct interface *)vty->index;
1422 ri = ifp->info;
1423
1424 ri->ri_receive = RI_RIP_UNSPEC;
1425 return CMD_SUCCESS;
1426}
1427
1428ALIAS (no_ip_rip_receive_version,
1429 no_ip_rip_receive_version_num_cmd,
1430 "no ip rip receive version (1|2)",
1431 NO_STR
1432 IP_STR
1433 "Routing Information Protocol\n"
1434 "Advertisement reception\n"
1435 "Version control\n"
1436 "Version 1\n"
1437 "Version 2\n")
1438
1439DEFUN (ip_rip_send_version,
1440 ip_rip_send_version_cmd,
1441 "ip rip send version (1|2)",
1442 IP_STR
1443 "Routing Information Protocol\n"
1444 "Advertisement transmission\n"
1445 "Version control\n"
1446 "RIP version 1\n"
1447 "RIP version 2\n")
1448{
1449 struct interface *ifp;
1450 struct rip_interface *ri;
1451
1452 ifp = (struct interface *)vty->index;
1453 ri = ifp->info;
1454
1455 /* Version 1. */
1456 if (atoi (argv[0]) == 1)
1457 {
1458 ri->ri_send = RI_RIP_VERSION_1;
1459 return CMD_SUCCESS;
1460 }
1461 if (atoi (argv[0]) == 2)
1462 {
1463 ri->ri_send = RI_RIP_VERSION_2;
1464 return CMD_SUCCESS;
1465 }
1466 return CMD_WARNING;
1467}
1468
1469DEFUN (ip_rip_send_version_1,
1470 ip_rip_send_version_1_cmd,
1471 "ip rip send version 1 2",
1472 IP_STR
1473 "Routing Information Protocol\n"
1474 "Advertisement transmission\n"
1475 "Version control\n"
1476 "RIP version 1\n"
1477 "RIP version 2\n")
1478{
1479 struct interface *ifp;
1480 struct rip_interface *ri;
1481
1482 ifp = (struct interface *)vty->index;
1483 ri = ifp->info;
1484
1485 /* Version 1 and 2. */
1486 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1487 return CMD_SUCCESS;
1488}
1489
1490DEFUN (ip_rip_send_version_2,
1491 ip_rip_send_version_2_cmd,
1492 "ip rip send version 2 1",
1493 IP_STR
1494 "Routing Information Protocol\n"
1495 "Advertisement transmission\n"
1496 "Version control\n"
1497 "RIP version 2\n"
1498 "RIP version 1\n")
1499{
1500 struct interface *ifp;
1501 struct rip_interface *ri;
1502
1503 ifp = (struct interface *)vty->index;
1504 ri = ifp->info;
1505
1506 /* Version 1 and 2. */
1507 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1508 return CMD_SUCCESS;
1509}
1510
1511DEFUN (no_ip_rip_send_version,
1512 no_ip_rip_send_version_cmd,
1513 "no ip rip send version",
1514 NO_STR
1515 IP_STR
1516 "Routing Information Protocol\n"
1517 "Advertisement transmission\n"
1518 "Version control\n")
1519{
1520 struct interface *ifp;
1521 struct rip_interface *ri;
1522
1523 ifp = (struct interface *)vty->index;
1524 ri = ifp->info;
1525
1526 ri->ri_send = RI_RIP_UNSPEC;
1527 return CMD_SUCCESS;
1528}
1529
1530ALIAS (no_ip_rip_send_version,
1531 no_ip_rip_send_version_num_cmd,
1532 "no ip rip send version (1|2)",
1533 NO_STR
1534 IP_STR
1535 "Routing Information Protocol\n"
1536 "Advertisement transmission\n"
1537 "Version control\n"
1538 "Version 1\n"
1539 "Version 2\n")
1540
1541DEFUN (ip_rip_authentication_mode,
1542 ip_rip_authentication_mode_cmd,
1543 "ip rip authentication mode (md5|text)",
1544 IP_STR
1545 "Routing Information Protocol\n"
1546 "Authentication control\n"
1547 "Authentication mode\n"
1548 "Keyed message digest\n"
1549 "Clear text authentication\n")
1550{
1551 struct interface *ifp;
1552 struct rip_interface *ri;
Paul Jakma15a2b082006-05-04 07:36:34 +00001553 int auth_type;
paul718e3742002-12-13 20:15:29 +00001554
1555 ifp = (struct interface *)vty->index;
1556 ri = ifp->info;
1557
paulca5e5162004-06-06 22:06:33 +00001558 if ( (argc < 1) || (argc > 2) )
1559 {
1560 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1561 return CMD_WARNING;
1562 }
1563
paul718e3742002-12-13 20:15:29 +00001564 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001565 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001566 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001567 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001568 else
1569 {
1570 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1571 return CMD_WARNING;
1572 }
1573
paulca5e5162004-06-06 22:06:33 +00001574 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001575 {
1576 ri->auth_type = auth_type;
1577 return CMD_SUCCESS;
1578 }
paulca5e5162004-06-06 22:06:33 +00001579
Paul Jakma15a2b082006-05-04 07:36:34 +00001580 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001581 {
1582 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1583 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001584 }
paulca5e5162004-06-06 22:06:33 +00001585
1586 if (strncmp ("r", argv[1], 1) == 0)
1587 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1588 else if (strncmp ("o", argv[1], 1) == 0)
1589 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1590 else
1591 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001592
1593 ri->auth_type = auth_type;
1594
paul718e3742002-12-13 20:15:29 +00001595 return CMD_SUCCESS;
1596}
1597
paulca5e5162004-06-06 22:06:33 +00001598ALIAS (ip_rip_authentication_mode,
1599 ip_rip_authentication_mode_authlen_cmd,
1600 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1601 IP_STR
1602 "Routing Information Protocol\n"
1603 "Authentication control\n"
1604 "Authentication mode\n"
1605 "Keyed message digest\n"
1606 "Clear text authentication\n"
1607 "MD5 authentication data length\n"
1608 "RFC compatible\n"
1609 "Old ripd compatible\n")
1610
paul718e3742002-12-13 20:15:29 +00001611DEFUN (no_ip_rip_authentication_mode,
1612 no_ip_rip_authentication_mode_cmd,
1613 "no ip rip authentication mode",
1614 NO_STR
1615 IP_STR
1616 "Routing Information Protocol\n"
1617 "Authentication control\n"
1618 "Authentication mode\n")
1619{
1620 struct interface *ifp;
1621 struct rip_interface *ri;
1622
1623 ifp = (struct interface *)vty->index;
1624 ri = ifp->info;
1625
paul7755a8c2005-06-02 08:20:53 +00001626 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001627 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001628
1629 return CMD_SUCCESS;
1630}
1631
1632ALIAS (no_ip_rip_authentication_mode,
1633 no_ip_rip_authentication_mode_type_cmd,
1634 "no ip rip authentication mode (md5|text)",
1635 NO_STR
1636 IP_STR
1637 "Routing Information Protocol\n"
1638 "Authentication control\n"
1639 "Authentication mode\n"
1640 "Keyed message digest\n"
1641 "Clear text authentication\n")
1642
paulca5e5162004-06-06 22:06:33 +00001643ALIAS (no_ip_rip_authentication_mode,
1644 no_ip_rip_authentication_mode_type_authlen_cmd,
1645 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1646 NO_STR
1647 IP_STR
1648 "Routing Information Protocol\n"
1649 "Authentication control\n"
1650 "Authentication mode\n"
1651 "Keyed message digest\n"
1652 "Clear text authentication\n"
1653 "MD5 authentication data length\n"
1654 "RFC compatible\n"
1655 "Old ripd compatible\n")
1656
paul718e3742002-12-13 20:15:29 +00001657DEFUN (ip_rip_authentication_string,
1658 ip_rip_authentication_string_cmd,
1659 "ip rip authentication string LINE",
1660 IP_STR
1661 "Routing Information Protocol\n"
1662 "Authentication control\n"
1663 "Authentication string\n"
1664 "Authentication string\n")
1665{
1666 struct interface *ifp;
1667 struct rip_interface *ri;
1668
1669 ifp = (struct interface *)vty->index;
1670 ri = ifp->info;
1671
1672 if (strlen (argv[0]) > 16)
1673 {
1674 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1675 VTY_NEWLINE);
1676 return CMD_WARNING;
1677 }
1678
1679 if (ri->key_chain)
1680 {
1681 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1682 return CMD_WARNING;
1683 }
1684
1685 if (ri->auth_str)
1686 free (ri->auth_str);
1687
1688 ri->auth_str = strdup (argv[0]);
1689
1690 return CMD_SUCCESS;
1691}
1692
1693DEFUN (no_ip_rip_authentication_string,
1694 no_ip_rip_authentication_string_cmd,
1695 "no ip rip authentication string",
1696 NO_STR
1697 IP_STR
1698 "Routing Information Protocol\n"
1699 "Authentication control\n"
1700 "Authentication string\n")
1701{
1702 struct interface *ifp;
1703 struct rip_interface *ri;
1704
1705 ifp = (struct interface *)vty->index;
1706 ri = ifp->info;
1707
1708 if (ri->auth_str)
1709 free (ri->auth_str);
1710
1711 ri->auth_str = NULL;
1712
1713 return CMD_SUCCESS;
1714}
1715
1716ALIAS (no_ip_rip_authentication_string,
1717 no_ip_rip_authentication_string2_cmd,
1718 "no ip rip authentication string LINE",
1719 NO_STR
1720 IP_STR
1721 "Routing Information Protocol\n"
1722 "Authentication control\n"
1723 "Authentication string\n"
1724 "Authentication string\n")
1725
1726DEFUN (ip_rip_authentication_key_chain,
1727 ip_rip_authentication_key_chain_cmd,
1728 "ip rip authentication key-chain LINE",
1729 IP_STR
1730 "Routing Information Protocol\n"
1731 "Authentication control\n"
1732 "Authentication key-chain\n"
1733 "name of key-chain\n")
1734{
1735 struct interface *ifp;
1736 struct rip_interface *ri;
1737
1738 ifp = (struct interface *) vty->index;
1739 ri = ifp->info;
1740
1741 if (ri->auth_str)
1742 {
1743 vty_out (vty, "%% authentication string configuration exists%s",
1744 VTY_NEWLINE);
1745 return CMD_WARNING;
1746 }
1747
1748 if (ri->key_chain)
1749 free (ri->key_chain);
1750
1751 ri->key_chain = strdup (argv[0]);
1752
1753 return CMD_SUCCESS;
1754}
1755
1756DEFUN (no_ip_rip_authentication_key_chain,
1757 no_ip_rip_authentication_key_chain_cmd,
1758 "no ip rip authentication key-chain",
1759 NO_STR
1760 IP_STR
1761 "Routing Information Protocol\n"
1762 "Authentication control\n"
1763 "Authentication key-chain\n")
1764{
1765 struct interface *ifp;
1766 struct rip_interface *ri;
1767
1768 ifp = (struct interface *) vty->index;
1769 ri = ifp->info;
1770
1771 if (ri->key_chain)
1772 free (ri->key_chain);
1773
1774 ri->key_chain = NULL;
1775
1776 return CMD_SUCCESS;
1777}
1778
1779ALIAS (no_ip_rip_authentication_key_chain,
1780 no_ip_rip_authentication_key_chain2_cmd,
1781 "no ip rip authentication key-chain LINE",
1782 NO_STR
1783 IP_STR
1784 "Routing Information Protocol\n"
1785 "Authentication control\n"
1786 "Authentication key-chain\n"
1787 "name of key-chain\n")
1788
hasso16705132003-05-25 14:49:19 +00001789/* CHANGED: ip rip split-horizon
1790 Cisco and Zebra's command is
1791 ip split-horizon
1792 */
1793DEFUN (ip_rip_split_horizon,
1794 ip_rip_split_horizon_cmd,
1795 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001796 IP_STR
hasso16705132003-05-25 14:49:19 +00001797 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001798 "Perform split horizon\n")
1799{
1800 struct interface *ifp;
1801 struct rip_interface *ri;
1802
1803 ifp = vty->index;
1804 ri = ifp->info;
1805
hasso16705132003-05-25 14:49:19 +00001806 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001807 return CMD_SUCCESS;
1808}
1809
hasso16705132003-05-25 14:49:19 +00001810DEFUN (ip_rip_split_horizon_poisoned_reverse,
1811 ip_rip_split_horizon_poisoned_reverse_cmd,
1812 "ip rip split-horizon poisoned-reverse",
1813 IP_STR
1814 "Routing Information Protocol\n"
1815 "Perform split horizon\n"
1816 "With poisoned-reverse\n")
1817{
1818 struct interface *ifp;
1819 struct rip_interface *ri;
1820
1821 ifp = vty->index;
1822 ri = ifp->info;
1823
1824 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1825 return CMD_SUCCESS;
1826}
1827
1828/* CHANGED: no ip rip split-horizon
1829 Cisco and Zebra's command is
1830 no ip split-horizon
1831 */
1832DEFUN (no_ip_rip_split_horizon,
1833 no_ip_rip_split_horizon_cmd,
1834 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001835 NO_STR
1836 IP_STR
hasso16705132003-05-25 14:49:19 +00001837 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001838 "Perform split horizon\n")
1839{
1840 struct interface *ifp;
1841 struct rip_interface *ri;
1842
1843 ifp = vty->index;
1844 ri = ifp->info;
1845
hasso16705132003-05-25 14:49:19 +00001846 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001847 return CMD_SUCCESS;
1848}
1849
vincentfac3e842005-10-06 07:45:43 +00001850DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001851 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1852 "no ip rip split-horizon poisoned-reverse",
1853 NO_STR
1854 IP_STR
1855 "Routing Information Protocol\n"
1856 "Perform split horizon\n"
1857 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001858{
1859 struct interface *ifp;
1860 struct rip_interface *ri;
1861
1862 ifp = vty->index;
1863 ri = ifp->info;
1864
1865 switch( ri->split_horizon )
1866 {
1867 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1868 ri->split_horizon = RIP_SPLIT_HORIZON;
1869 default:
1870 break;
1871 }
1872
1873 return CMD_SUCCESS;
1874}
hasso16705132003-05-25 14:49:19 +00001875
paul718e3742002-12-13 20:15:29 +00001876DEFUN (rip_passive_interface,
1877 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001878 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001879 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001880 "Interface name\n"
1881 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001882{
hasso98b718a2004-10-11 12:57:57 +00001883 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001884
1885 if (!strcmp(ifname,"default")) {
1886 passive_default = 1;
1887 rip_passive_nondefault_clean();
1888 return CMD_SUCCESS;
1889 }
1890 if (passive_default)
1891 return rip_passive_nondefault_unset (vty, ifname);
1892 else
1893 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001894}
1895
1896DEFUN (no_rip_passive_interface,
1897 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001898 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001899 NO_STR
1900 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001901 "Interface name\n"
1902 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001903{
hasso98b718a2004-10-11 12:57:57 +00001904 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001905
1906 if (!strcmp(ifname,"default")) {
1907 passive_default = 0;
1908 rip_passive_nondefault_clean();
1909 return CMD_SUCCESS;
1910 }
1911 if (passive_default)
1912 return rip_passive_nondefault_set (vty, ifname);
1913 else
1914 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001915}
1916
1917/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001918static int
paul718e3742002-12-13 20:15:29 +00001919rip_interface_config_write (struct vty *vty)
1920{
hasso52dc7ee2004-09-23 19:18:23 +00001921 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001922 struct interface *ifp;
1923
paul1eb8ef22005-04-07 07:30:20 +00001924 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001925 {
1926 struct rip_interface *ri;
1927
paul718e3742002-12-13 20:15:29 +00001928 ri = ifp->info;
1929
hasso16705132003-05-25 14:49:19 +00001930 /* Do not display the interface if there is no
1931 * configuration about it.
1932 **/
1933 if ((!ifp->desc) &&
1934 (ri->split_horizon == ri->split_horizon_default) &&
1935 (ri->ri_send == RI_RIP_UNSPEC) &&
1936 (ri->ri_receive == RI_RIP_UNSPEC) &&
1937 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001938 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001939 (!ri->auth_str) &&
1940 (!ri->key_chain) )
1941 continue;
1942
paul718e3742002-12-13 20:15:29 +00001943 vty_out (vty, "interface %s%s", ifp->name,
1944 VTY_NEWLINE);
1945
1946 if (ifp->desc)
1947 vty_out (vty, " description %s%s", ifp->desc,
1948 VTY_NEWLINE);
1949
1950 /* Split horizon. */
1951 if (ri->split_horizon != ri->split_horizon_default)
1952 {
hasso16705132003-05-25 14:49:19 +00001953 switch (ri->split_horizon) {
1954 case RIP_SPLIT_HORIZON:
1955 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1956 break;
1957 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1958 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1959 VTY_NEWLINE);
1960 break;
1961 case RIP_NO_SPLIT_HORIZON:
1962 default:
1963 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1964 break;
1965 }
paul718e3742002-12-13 20:15:29 +00001966 }
1967
1968 /* RIP version setting. */
1969 if (ri->ri_send != RI_RIP_UNSPEC)
1970 vty_out (vty, " ip rip send version %s%s",
1971 lookup (ri_version_msg, ri->ri_send),
1972 VTY_NEWLINE);
1973
1974 if (ri->ri_receive != RI_RIP_UNSPEC)
1975 vty_out (vty, " ip rip receive version %s%s",
1976 lookup (ri_version_msg, ri->ri_receive),
1977 VTY_NEWLINE);
1978
1979 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001980 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1981 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001982
paul718e3742002-12-13 20:15:29 +00001983 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001984 {
1985 vty_out (vty, " ip rip authentication mode md5");
1986 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1987 vty_out (vty, " auth-length old-ripd");
1988 else
1989 vty_out (vty, " auth-length rfc");
1990 vty_out (vty, "%s", VTY_NEWLINE);
1991 }
paul718e3742002-12-13 20:15:29 +00001992
1993 if (ri->auth_str)
1994 vty_out (vty, " ip rip authentication string %s%s",
1995 ri->auth_str, VTY_NEWLINE);
1996
1997 if (ri->key_chain)
1998 vty_out (vty, " ip rip authentication key-chain %s%s",
1999 ri->key_chain, VTY_NEWLINE);
2000
2001 vty_out (vty, "!%s", VTY_NEWLINE);
2002 }
2003 return 0;
2004}
2005
2006int
2007config_write_rip_network (struct vty *vty, int config_mode)
2008{
hasso8a676be2004-10-08 06:36:38 +00002009 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002010 char *ifname;
2011 struct route_node *node;
2012
2013 /* Network type RIP enable interface statement. */
2014 for (node = route_top (rip_enable_network); node; node = route_next (node))
2015 if (node->info)
2016 vty_out (vty, "%s%s/%d%s",
2017 config_mode ? " network " : " ",
2018 inet_ntoa (node->p.u.prefix4),
2019 node->p.prefixlen,
2020 VTY_NEWLINE);
2021
2022 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002023 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002024 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2025 vty_out (vty, "%s%s%s",
2026 config_mode ? " network " : " ",
2027 ifname,
2028 VTY_NEWLINE);
2029
2030 /* RIP neighbors listing. */
2031 for (node = route_top (rip->neighbor); node; node = route_next (node))
2032 if (node->info)
2033 vty_out (vty, "%s%s%s",
2034 config_mode ? " neighbor " : " ",
2035 inet_ntoa (node->p.u.prefix4),
2036 VTY_NEWLINE);
2037
2038 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002039 if (config_mode) {
2040 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002041 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002042 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002043 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2044 vty_out (vty, " %spassive-interface %s%s",
2045 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2046 }
paul718e3742002-12-13 20:15:29 +00002047
2048 return 0;
2049}
2050
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002051static struct cmd_node interface_node =
paul718e3742002-12-13 20:15:29 +00002052{
2053 INTERFACE_NODE,
2054 "%s(config-if)# ",
2055 1,
2056};
2057
2058/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002059static int
paul718e3742002-12-13 20:15:29 +00002060rip_interface_new_hook (struct interface *ifp)
2061{
2062 ifp->info = rip_interface_new ();
2063 return 0;
2064}
2065
2066/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002067static int
paul718e3742002-12-13 20:15:29 +00002068rip_interface_delete_hook (struct interface *ifp)
2069{
2070 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002071 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002072 return 0;
2073}
2074
2075/* Allocate and initialize interface vector. */
2076void
pauldc63bfd2005-10-25 23:31:05 +00002077rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002078{
2079 /* Default initial size of interface vector. */
2080 if_init();
2081 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2082 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2083
2084 /* RIP network init. */
2085 rip_enable_interface = vector_init (1);
2086 rip_enable_network = route_table_init ();
2087
2088 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002089 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002090
2091 /* Install interface node. */
2092 install_node (&interface_node, rip_interface_config_write);
2093
2094 /* Install commands. */
2095 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002096 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002097 install_default (INTERFACE_NODE);
2098 install_element (INTERFACE_NODE, &interface_desc_cmd);
2099 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2100 install_element (RIP_NODE, &rip_network_cmd);
2101 install_element (RIP_NODE, &no_rip_network_cmd);
2102 install_element (RIP_NODE, &rip_neighbor_cmd);
2103 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2104
2105 install_element (RIP_NODE, &rip_passive_interface_cmd);
2106 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2107
2108 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2109 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2110 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2111 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2112 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2113
2114 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2115 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2116 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2117 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2118 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2119
2120 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002121 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002122 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2123 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002124 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002125
2126 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2127 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2128 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2129
2130 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2131 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2132 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2133
hasso16705132003-05-25 14:49:19 +00002134 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2135 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2136 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2137 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002138}