blob: c8a1a84f9b3e982297d5b6cf78d6aaf92350fbf2 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Interface related function for RIP.
2 * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "command.h"
25#include "if.h"
26#include "sockunion.h"
27#include "prefix.h"
28#include "memory.h"
29#include "network.h"
30#include "table.h"
31#include "log.h"
32#include "stream.h"
33#include "thread.h"
34#include "zclient.h"
35#include "filter.h"
36#include "sockopt.h"
pauledd7c242003-06-04 13:59:38 +000037#include "privs.h"
paul718e3742002-12-13 20:15:29 +000038
39#include "zebra/connected.h"
40
41#include "ripd/ripd.h"
42#include "ripd/rip_debug.h"
pauldc63bfd2005-10-25 23:31:05 +000043#include "ripd/rip_interface.h"
44
45/* static prototypes */
46static void rip_enable_apply (struct interface *);
47static void rip_passive_interface_apply (struct interface *);
48static int rip_if_down(struct interface *ifp);
49static int rip_enable_if_lookup (const char *ifname);
50static int rip_enable_network_lookup2 (struct connected *connected);
51static void rip_enable_apply_all (void);
52
paul718e3742002-12-13 20:15:29 +000053struct message ri_version_msg[] =
54{
55 {RI_RIP_VERSION_1, "1"},
56 {RI_RIP_VERSION_2, "2"},
57 {RI_RIP_VERSION_1_AND_2, "1 2"},
58 {0, NULL}
59};
60
pauledd7c242003-06-04 13:59:38 +000061extern struct zebra_privs_t ripd_privs;
62
paul718e3742002-12-13 20:15:29 +000063/* RIP enabled network vector. */
64vector rip_enable_interface;
65
66/* RIP enabled interface table. */
67struct route_table *rip_enable_network;
68
69/* Vector to store passive-interface name. */
paul4aaff3f2003-06-07 01:04:45 +000070static int passive_default; /* are we in passive-interface default mode? */
71vector Vrip_passive_nondefault;
paul718e3742002-12-13 20:15:29 +000072
73/* Join to the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000074static int
paul718e3742002-12-13 20:15:29 +000075ipv4_multicast_join (int sock,
76 struct in_addr group,
77 struct in_addr ifa,
78 unsigned int ifindex)
79{
80 int ret;
81
82 ret = setsockopt_multicast_ipv4 (sock,
83 IP_ADD_MEMBERSHIP,
84 ifa,
85 group.s_addr,
86 ifindex);
87
88 if (ret < 0)
89 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
ajs6099b3b2004-11-20 02:06:59 +000090 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +000091
92 return ret;
93}
94
95/* Leave from the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000096static int
paul718e3742002-12-13 20:15:29 +000097ipv4_multicast_leave (int sock,
98 struct in_addr group,
99 struct in_addr ifa,
100 unsigned int ifindex)
101{
102 int ret;
103
104 ret = setsockopt_multicast_ipv4 (sock,
105 IP_DROP_MEMBERSHIP,
106 ifa,
107 group.s_addr,
108 ifindex);
109
110 if (ret < 0)
111 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
112
113 return ret;
114}
115
116/* Allocate new RIP's interface configuration. */
pauldc63bfd2005-10-25 23:31:05 +0000117static struct rip_interface *
118rip_interface_new (void)
paul718e3742002-12-13 20:15:29 +0000119{
120 struct rip_interface *ri;
121
122 ri = XMALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
123 memset (ri, 0, sizeof (struct rip_interface));
124
125 /* Default authentication type is simple password for Cisco
126 compatibility. */
paul7755a8c2005-06-02 08:20:53 +0000127 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +0000128 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +0000129
130 /* Set default split-horizon behavior. If the interface is Frame
131 Relay or SMDS is enabled, the default value for split-horizon is
132 off. But currently Zebra does detect Frame Relay or SMDS
133 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000134 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000135 ri->split_horizon = ri->split_horizon_default;
136
137 return ri;
138}
139
140void
paul1a517862004-08-19 04:03:08 +0000141rip_interface_multicast_set (int sock, struct connected *connected)
paul718e3742002-12-13 20:15:29 +0000142{
hasso3fb9cd62004-10-19 19:44:43 +0000143 struct in_addr addr;
paulc49ad8f2004-10-22 10:27:28 +0000144
145 assert (connected != NULL);
146
Andrew J. Schorre4529632006-12-12 19:18:21 +0000147 addr = CONNECTED_ID(connected)->u.prefix4;
paul718e3742002-12-13 20:15:29 +0000148
paul1a517862004-08-19 04:03:08 +0000149 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
150 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000151 {
152 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
153 "source address %s for interface %s",
154 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000155 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000156 }
paul2c61ae32005-08-16 15:22:14 +0000157
hasso3fb9cd62004-10-19 19:44:43 +0000158 return;
159}
paul718e3742002-12-13 20:15:29 +0000160
161/* Send RIP request packet to specified interface. */
pauldc63bfd2005-10-25 23:31:05 +0000162static void
paul718e3742002-12-13 20:15:29 +0000163rip_request_interface_send (struct interface *ifp, u_char version)
164{
165 struct sockaddr_in to;
166
167 /* RIPv2 support multicast. */
168 if (version == RIPv2 && if_is_multicast (ifp))
169 {
170
171 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000172 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000173
paul931cd542004-01-23 15:31:42 +0000174 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000175 return;
176 }
177
178 /* RIPv1 and non multicast interface. */
179 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
180 {
paul1eb8ef22005-04-07 07:30:20 +0000181 struct listnode *cnode, *cnnode;
182 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000183
184 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000185 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000186
paul1eb8ef22005-04-07 07:30:20 +0000187 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000188 {
hasso3fb9cd62004-10-19 19:44:43 +0000189 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000190 {
191 memset (&to, 0, sizeof (struct sockaddr_in));
192 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000193 if (connected->destination)
Andrew J. Schorre4529632006-12-12 19:18:21 +0000194 /* use specified broadcast or peer destination addr */
hasso3fb9cd62004-10-19 19:44:43 +0000195 to.sin_addr = connected->destination->u.prefix4;
Andrew J. Schorre4529632006-12-12 19:18:21 +0000196 else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
hasso3fb9cd62004-10-19 19:44:43 +0000197 /* calculate the appropriate broadcast address */
198 to.sin_addr.s_addr =
199 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
200 connected->address->prefixlen);
Andrew J. Schorre4529632006-12-12 19:18:21 +0000201 else
202 /* do not know where to send the packet */
203 continue;
paul718e3742002-12-13 20:15:29 +0000204
paul718e3742002-12-13 20:15:29 +0000205 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000206 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000207
paul931cd542004-01-23 15:31:42 +0000208 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000209 }
210 }
211 }
212}
213
214/* This will be executed when interface goes up. */
pauldc63bfd2005-10-25 23:31:05 +0000215static void
paul718e3742002-12-13 20:15:29 +0000216rip_request_interface (struct interface *ifp)
217{
218 struct rip_interface *ri;
219
220 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
221 if (if_is_loopback (ifp))
222 return;
223
224 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000225 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000226 return;
227
228 /* Fetch RIP interface information. */
229 ri = ifp->info;
230
231
232 /* If there is no version configuration in the interface,
233 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000234 {
235 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
236 rip->version_send : ri->ri_send);
237 if (vsend & RIPv1)
238 rip_request_interface_send (ifp, RIPv1);
239 if (vsend & RIPv2)
240 rip_request_interface_send (ifp, RIPv2);
241 }
paul718e3742002-12-13 20:15:29 +0000242}
243
244/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000245static void
paul718e3742002-12-13 20:15:29 +0000246rip_request_neighbor (struct in_addr addr)
247{
248 struct sockaddr_in to;
249
250 memset (&to, 0, sizeof (struct sockaddr_in));
251 to.sin_port = htons (RIP_PORT_DEFAULT);
252 to.sin_addr = addr;
253
paul931cd542004-01-23 15:31:42 +0000254 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000255}
256
257/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000258static void
259rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000260{
261 struct route_node *rp;
262
263 if (! rip)
264 return;
265
266 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000267 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000268
269 /* Send request to all neighbor. */
270 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
271 if (rp->info)
272 rip_request_neighbor (rp->p.u.prefix4);
273}
274
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)
ajs5d6c3772004-12-08 19:24:06 +0000407 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000408 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
409
410 return 0;
411}
412
413/* Inteface link up message processing */
414int
415rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
416{
417 struct interface *ifp;
418
419 /* zebra_interface_state_read () updates interface structure in
420 iflist. */
421 ifp = zebra_interface_state_read (zclient->ibuf);
422
423 if (ifp == NULL)
424 return 0;
425
426 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000427 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000428 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
429
430 /* Check if this interface is RIP enabled or not.*/
431 rip_enable_apply (ifp);
432
433 /* Check for a passive interface */
434 rip_passive_interface_apply (ifp);
435
436 /* Apply distribute list to the all interface. */
437 rip_distribute_update_interface (ifp);
438
439 return 0;
440}
441
442/* Inteface addition message from zebra. */
443int
444rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
445{
446 struct interface *ifp;
447
448 ifp = zebra_interface_add_read (zclient->ibuf);
449
450 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000451 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000452 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
453
454 /* Check if this interface is RIP enabled or not.*/
455 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000456
457 /* Check for a passive interface */
458 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000459
460 /* Apply distribute list to the all interface. */
461 rip_distribute_update_interface (ifp);
462
463 /* rip_request_neighbor_all (); */
464
hasso16705132003-05-25 14:49:19 +0000465 /* Check interface routemap. */
466 rip_if_rmap_update_interface (ifp);
467
paul718e3742002-12-13 20:15:29 +0000468 return 0;
469}
470
471int
472rip_interface_delete (int command, struct zclient *zclient,
473 zebra_size_t length)
474{
475 struct interface *ifp;
476 struct stream *s;
477
478
479 s = zclient->ibuf;
480 /* zebra_interface_state_read() updates interface structure in iflist */
481 ifp = zebra_interface_state_read(s);
482
483 if (ifp == NULL)
484 return 0;
485
486 if (if_is_up (ifp)) {
487 rip_if_down(ifp);
488 }
489
490 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
491 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
492
493 /* To support pseudo interface do not free interface structure. */
494 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000495 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000496
497 return 0;
498}
499
500void
pauldc63bfd2005-10-25 23:31:05 +0000501rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000502{
hasso52dc7ee2004-09-23 19:18:23 +0000503 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000504 struct interface *ifp;
505 struct rip_interface *ri;
506
paul1eb8ef22005-04-07 07:30:20 +0000507 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000508 {
paul718e3742002-12-13 20:15:29 +0000509 ri = ifp->info;
510
511 ri->enable_network = 0;
512 ri->enable_interface = 0;
513 ri->running = 0;
514
515 if (ri->t_wakeup)
516 {
517 thread_cancel (ri->t_wakeup);
518 ri->t_wakeup = NULL;
519 }
520 }
521}
522
523void
pauldc63bfd2005-10-25 23:31:05 +0000524rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000525{
hasso52dc7ee2004-09-23 19:18:23 +0000526 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000527 struct interface *ifp;
528 struct rip_interface *ri;
529
paul1eb8ef22005-04-07 07:30:20 +0000530 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000531 {
paul718e3742002-12-13 20:15:29 +0000532 ri = ifp->info;
533
534 ri->enable_network = 0;
535 ri->enable_interface = 0;
536 ri->running = 0;
537
538 ri->ri_send = RI_RIP_UNSPEC;
539 ri->ri_receive = RI_RIP_UNSPEC;
540
paul7755a8c2005-06-02 08:20:53 +0000541 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000542
543 if (ri->auth_str)
544 {
545 free (ri->auth_str);
546 ri->auth_str = NULL;
547 }
548 if (ri->key_chain)
549 {
550 free (ri->key_chain);
551 ri->key_chain = NULL;
552 }
553
hasso16705132003-05-25 14:49:19 +0000554 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
555 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000556
557 ri->list[RIP_FILTER_IN] = NULL;
558 ri->list[RIP_FILTER_OUT] = NULL;
559
560 ri->prefix[RIP_FILTER_IN] = NULL;
561 ri->prefix[RIP_FILTER_OUT] = NULL;
562
563 if (ri->t_wakeup)
564 {
565 thread_cancel (ri->t_wakeup);
566 ri->t_wakeup = NULL;
567 }
568
569 ri->recv_badpackets = 0;
570 ri->recv_badroutes = 0;
571 ri->sent_updates = 0;
572
573 ri->passive = 0;
574 }
575}
576
577int
578rip_if_down(struct interface *ifp)
579{
580 struct route_node *rp;
581 struct rip_info *rinfo;
582 struct rip_interface *ri = NULL;
583 if (rip)
584 {
585 for (rp = route_top (rip->table); rp; rp = route_next (rp))
586 if ((rinfo = rp->info) != NULL)
587 {
588 /* Routes got through this interface. */
589 if (rinfo->ifindex == ifp->ifindex &&
590 rinfo->type == ZEBRA_ROUTE_RIP &&
591 rinfo->sub_type == RIP_ROUTE_RTE)
592 {
593 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
594 &rinfo->nexthop,
595 rinfo->ifindex);
596
597 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
598 (struct prefix_ipv4 *)&rp->p,
599 rinfo->ifindex);
600 }
601 else
602 {
603 /* All redistributed routes but static and system */
604 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000605 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000606 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
607 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
608 (struct prefix_ipv4 *)&rp->p,
609 rinfo->ifindex);
610 }
611 }
612 }
613
614 ri = ifp->info;
615
616 if (ri->running)
617 {
618 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000619 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000620
621 /* Leave from multicast group. */
622 rip_multicast_leave (ifp, rip->sock);
623
624 ri->running = 0;
625 }
626
627 return 0;
628}
629
630/* Needed for stop RIP process. */
631void
632rip_if_down_all ()
633{
634 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000635 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000636
paul1eb8ef22005-04-07 07:30:20 +0000637 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
638 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000639}
640
hasso16705132003-05-25 14:49:19 +0000641static void
pauldc63bfd2005-10-25 23:31:05 +0000642rip_apply_address_add (struct connected *ifc)
643{
hasso16705132003-05-25 14:49:19 +0000644 struct prefix_ipv4 address;
645 struct prefix *p;
646
647 if (!rip)
648 return;
649
650 if (! if_is_up(ifc->ifp))
651 return;
652
653 p = ifc->address;
654
655 memset (&address, 0, sizeof (address));
656 address.family = p->family;
657 address.prefix = p->u.prefix4;
658 address.prefixlen = p->prefixlen;
659 apply_mask_ipv4(&address);
660
661 /* Check if this interface is RIP enabled or not
662 or Check if this address's prefix is RIP enabled */
663 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
664 (rip_enable_network_lookup2(ifc) >= 0))
665 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000666 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000667
668}
669
paul718e3742002-12-13 20:15:29 +0000670int
671rip_interface_address_add (int command, struct zclient *zclient,
672 zebra_size_t length)
673{
674 struct connected *ifc;
675 struct prefix *p;
676
paul0a589352004-05-08 11:48:26 +0000677 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
678 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000679
680 if (ifc == NULL)
681 return 0;
682
683 p = ifc->address;
684
685 if (p->family == AF_INET)
686 {
687 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000688 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000689 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000690
paul878ef2e2003-09-23 23:41:50 +0000691 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000692 /* Check if this prefix needs to be redistributed */
693 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000694
695#ifdef HAVE_SNMP
696 rip_ifaddr_add (ifc->ifp, ifc);
697#endif /* HAVE_SNMP */
698 }
699
700 return 0;
701}
702
hasso16705132003-05-25 14:49:19 +0000703static void
704rip_apply_address_del (struct connected *ifc) {
705 struct prefix_ipv4 address;
706 struct prefix *p;
707
708 if (!rip)
709 return;
710
711 if (! if_is_up(ifc->ifp))
712 return;
713
714 p = ifc->address;
715
716 memset (&address, 0, sizeof (address));
717 address.family = p->family;
718 address.prefix = p->u.prefix4;
719 address.prefixlen = p->prefixlen;
720 apply_mask_ipv4(&address);
721
722 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
723 &address, ifc->ifp->ifindex);
724}
725
paul718e3742002-12-13 20:15:29 +0000726int
727rip_interface_address_delete (int command, struct zclient *zclient,
728 zebra_size_t length)
729{
730 struct connected *ifc;
731 struct prefix *p;
732
paul0a589352004-05-08 11:48:26 +0000733 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
734 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000735
736 if (ifc)
737 {
738 p = ifc->address;
739 if (p->family == AF_INET)
740 {
741 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000742 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000743 inet_ntoa (p->u.prefix4), p->prefixlen);
744
745#ifdef HAVE_SNMP
746 rip_ifaddr_delete (ifc->ifp, ifc);
747#endif /* HAVE_SNMP */
748
hasso16705132003-05-25 14:49:19 +0000749 /* Chech wether this prefix needs to be removed */
750 rip_apply_address_del(ifc);
751
paul718e3742002-12-13 20:15:29 +0000752 }
753
754 connected_free (ifc);
755
756 }
757
758 return 0;
759}
760
761/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000762/* Check wether the interface has at least a connected prefix that
763 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000764static int
hasso16705132003-05-25 14:49:19 +0000765rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000766{
paul1eb8ef22005-04-07 07:30:20 +0000767 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000768 struct connected *connected;
769 struct prefix_ipv4 address;
770
paul1eb8ef22005-04-07 07:30:20 +0000771 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
772 {
773 struct prefix *p;
774 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000775
paul1eb8ef22005-04-07 07:30:20 +0000776 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000777
paul1eb8ef22005-04-07 07:30:20 +0000778 if (p->family == AF_INET)
779 {
780 address.family = AF_INET;
781 address.prefix = p->u.prefix4;
782 address.prefixlen = IPV4_MAX_BITLEN;
783
784 node = route_node_match (rip_enable_network,
785 (struct prefix *)&address);
786 if (node)
787 {
788 route_unlock_node (node);
789 return 1;
790 }
791 }
792 }
paul718e3742002-12-13 20:15:29 +0000793 return -1;
794}
795
hasso16705132003-05-25 14:49:19 +0000796/* Check wether connected is within the ripng_enable_network table. */
797int
798rip_enable_network_lookup2 (struct connected *connected)
799{
800 struct prefix_ipv4 address;
801 struct prefix *p;
802
803 p = connected->address;
804
805 if (p->family == AF_INET) {
806 struct route_node *node;
807
808 address.family = p->family;
809 address.prefix = p->u.prefix4;
810 address.prefixlen = IPV4_MAX_BITLEN;
811
812 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
813 node = route_node_match (rip_enable_network,
814 (struct prefix *)&address);
815
816 if (node) {
817 route_unlock_node (node);
818 return 1;
819 }
820 }
821
822 return -1;
823}
paul718e3742002-12-13 20:15:29 +0000824/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000825static int
paul718e3742002-12-13 20:15:29 +0000826rip_enable_network_add (struct prefix *p)
827{
828 struct route_node *node;
829
830 node = route_node_get (rip_enable_network, p);
831
832 if (node->info)
833 {
834 route_unlock_node (node);
835 return -1;
836 }
837 else
hasso8a676be2004-10-08 06:36:38 +0000838 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000839
hasso16705132003-05-25 14:49:19 +0000840 /* XXX: One should find a better solution than a generic one */
841 rip_enable_apply_all();
842
paul718e3742002-12-13 20:15:29 +0000843 return 1;
844}
845
846/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000847static int
paul718e3742002-12-13 20:15:29 +0000848rip_enable_network_delete (struct prefix *p)
849{
850 struct route_node *node;
851
852 node = route_node_lookup (rip_enable_network, p);
853 if (node)
854 {
855 node->info = NULL;
856
857 /* Unlock info lock. */
858 route_unlock_node (node);
859
860 /* Unlock lookup lock. */
861 route_unlock_node (node);
862
hasso16705132003-05-25 14:49:19 +0000863 /* XXX: One should find a better solution than a generic one */
864 rip_enable_apply_all ();
865
paul718e3742002-12-13 20:15:29 +0000866 return 1;
867 }
868 return -1;
869}
870
871/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000872static int
hasso98b718a2004-10-11 12:57:57 +0000873rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000874{
hasso8a676be2004-10-08 06:36:38 +0000875 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000876 char *str;
877
paul55468c82005-03-14 20:19:01 +0000878 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000879 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
880 if (strcmp (str, ifname) == 0)
881 return i;
882 return -1;
883}
884
885/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000886static int
hasso98b718a2004-10-11 12:57:57 +0000887rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000888{
889 int ret;
890
891 ret = rip_enable_if_lookup (ifname);
892 if (ret >= 0)
893 return -1;
894
895 vector_set (rip_enable_interface, strdup (ifname));
896
hasso16705132003-05-25 14:49:19 +0000897 rip_enable_apply_all(); /* TODOVJ */
898
paul718e3742002-12-13 20:15:29 +0000899 return 1;
900}
901
902/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000903static int
hasso98b718a2004-10-11 12:57:57 +0000904rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000905{
906 int index;
907 char *str;
908
909 index = rip_enable_if_lookup (ifname);
910 if (index < 0)
911 return -1;
912
913 str = vector_slot (rip_enable_interface, index);
914 free (str);
915 vector_unset (rip_enable_interface, index);
916
hasso16705132003-05-25 14:49:19 +0000917 rip_enable_apply_all(); /* TODOVJ */
918
paul718e3742002-12-13 20:15:29 +0000919 return 1;
920}
921
922/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000923static int
paul718e3742002-12-13 20:15:29 +0000924rip_interface_wakeup (struct thread *t)
925{
926 struct interface *ifp;
927 struct rip_interface *ri;
928
929 /* Get interface. */
930 ifp = THREAD_ARG (t);
931
932 ri = ifp->info;
933 ri->t_wakeup = NULL;
934
935 /* Join to multicast group. */
936 if (rip_multicast_join (ifp, rip->sock) < 0)
937 {
938 zlog_err ("multicast join failed, interface %s not running", ifp->name);
939 return 0;
940 }
941
942 /* Set running flag. */
943 ri->running = 1;
944
945 /* Send RIP request to the interface. */
946 rip_request_interface (ifp);
947
948 return 0;
949}
950
951int rip_redistribute_check (int);
952
pauldc63bfd2005-10-25 23:31:05 +0000953static void
paul718e3742002-12-13 20:15:29 +0000954rip_connect_set (struct interface *ifp, int set)
955{
paul1eb8ef22005-04-07 07:30:20 +0000956 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000957 struct connected *connected;
958 struct prefix_ipv4 address;
959
paul1eb8ef22005-04-07 07:30:20 +0000960 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
961 {
962 struct prefix *p;
963 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000964
paul1eb8ef22005-04-07 07:30:20 +0000965 if (p->family != AF_INET)
966 continue;
paul718e3742002-12-13 20:15:29 +0000967
paul1eb8ef22005-04-07 07:30:20 +0000968 address.family = AF_INET;
969 address.prefix = p->u.prefix4;
970 address.prefixlen = p->prefixlen;
971 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000972
paul1eb8ef22005-04-07 07:30:20 +0000973 if (set) {
974 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
975 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
976 (rip_enable_network_lookup2(connected) >= 0))
977 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000978 &address, connected->ifp->ifindex,
979 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000980 } else
981 {
982 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
983 &address, connected->ifp->ifindex);
984 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
985 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000986 &address, connected->ifp->ifindex,
987 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000988 }
989 }
paul718e3742002-12-13 20:15:29 +0000990}
991
992/* Update interface status. */
993void
994rip_enable_apply (struct interface *ifp)
995{
996 int ret;
997 struct rip_interface *ri = NULL;
998
999 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001000 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001001 return;
1002
1003 ri = ifp->info;
1004
1005 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001006 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001007
1008 /* If the interface is matched. */
1009 if (ret > 0)
1010 ri->enable_network = 1;
1011 else
1012 ri->enable_network = 0;
1013
1014 /* Check interface name configuration. */
1015 ret = rip_enable_if_lookup (ifp->name);
1016 if (ret >= 0)
1017 ri->enable_interface = 1;
1018 else
1019 ri->enable_interface = 0;
1020
1021 /* any interface MUST have an IPv4 address */
1022 if ( ! rip_if_ipv4_address_check (ifp) )
1023 {
1024 ri->enable_network = 0;
1025 ri->enable_interface = 0;
1026 }
1027
1028 /* Update running status of the interface. */
1029 if (ri->enable_network || ri->enable_interface)
1030 {
paul718e3742002-12-13 20:15:29 +00001031 {
1032 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001033 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001034
1035 /* Add interface wake up thread. */
1036 if (! ri->t_wakeup)
1037 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1038 ifp, 1);
1039 rip_connect_set (ifp, 1);
1040 }
1041 }
1042 else
1043 {
1044 if (ri->running)
1045 {
hasso16705132003-05-25 14:49:19 +00001046 /* Might as well clean up the route table as well
1047 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1048 **/
paul718e3742002-12-13 20:15:29 +00001049 rip_if_down(ifp);
1050
paul718e3742002-12-13 20:15:29 +00001051 rip_connect_set (ifp, 0);
1052 }
1053 }
1054}
1055
1056/* Apply network configuration to all interface. */
1057void
1058rip_enable_apply_all ()
1059{
1060 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001061 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001062
1063 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001064 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1065 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001066}
1067
1068int
1069rip_neighbor_lookup (struct sockaddr_in *from)
1070{
1071 struct prefix_ipv4 p;
1072 struct route_node *node;
1073
1074 memset (&p, 0, sizeof (struct prefix_ipv4));
1075 p.family = AF_INET;
1076 p.prefix = from->sin_addr;
1077 p.prefixlen = IPV4_MAX_BITLEN;
1078
1079 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1080 if (node)
1081 {
1082 route_unlock_node (node);
1083 return 1;
1084 }
1085 return 0;
1086}
1087
1088/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001089static int
paul718e3742002-12-13 20:15:29 +00001090rip_neighbor_add (struct prefix_ipv4 *p)
1091{
1092 struct route_node *node;
1093
1094 node = route_node_get (rip->neighbor, (struct prefix *) p);
1095
1096 if (node->info)
1097 return -1;
1098
1099 node->info = rip->neighbor;
1100
1101 return 0;
1102}
1103
1104/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001105static int
paul718e3742002-12-13 20:15:29 +00001106rip_neighbor_delete (struct prefix_ipv4 *p)
1107{
1108 struct route_node *node;
1109
1110 /* Lock for look up. */
1111 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1112 if (! node)
1113 return -1;
1114
1115 node->info = NULL;
1116
1117 /* Unlock lookup lock. */
1118 route_unlock_node (node);
1119
1120 /* Unlock real neighbor information lock. */
1121 route_unlock_node (node);
1122
1123 return 0;
1124}
1125
1126/* Clear all network and neighbor configuration. */
1127void
1128rip_clean_network ()
1129{
hasso8a676be2004-10-08 06:36:38 +00001130 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001131 char *str;
1132 struct route_node *rn;
1133
1134 /* rip_enable_network. */
1135 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1136 if (rn->info)
1137 {
1138 rn->info = NULL;
1139 route_unlock_node (rn);
1140 }
1141
1142 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001143 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001144 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1145 {
1146 free (str);
1147 vector_slot (rip_enable_interface, i) = NULL;
1148 }
1149}
1150
1151/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001152static int
hasso98b718a2004-10-11 12:57:57 +00001153rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001154{
hasso8a676be2004-10-08 06:36:38 +00001155 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001156 char *str;
1157
paul55468c82005-03-14 20:19:01 +00001158 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001159 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001160 if (strcmp (str, ifname) == 0)
1161 return i;
1162 return -1;
1163}
1164
1165void
1166rip_passive_interface_apply (struct interface *ifp)
1167{
paul718e3742002-12-13 20:15:29 +00001168 struct rip_interface *ri;
1169
1170 ri = ifp->info;
1171
paul4aaff3f2003-06-07 01:04:45 +00001172 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1173 passive_default : !passive_default);
1174
1175 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001176 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001177}
1178
pauldc63bfd2005-10-25 23:31:05 +00001179static void
1180rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001181{
1182 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001183 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001184
paul1eb8ef22005-04-07 07:30:20 +00001185 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1186 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001187}
1188
1189/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001190static int
hasso98b718a2004-10-11 12:57:57 +00001191rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001192{
paul4aaff3f2003-06-07 01:04:45 +00001193 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001194 return CMD_WARNING;
1195
paul4aaff3f2003-06-07 01:04:45 +00001196 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001197
1198 rip_passive_interface_apply_all ();
1199
1200 return CMD_SUCCESS;
1201}
1202
pauldc63bfd2005-10-25 23:31:05 +00001203static int
hasso98b718a2004-10-11 12:57:57 +00001204rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001205{
1206 int i;
1207 char *str;
1208
paul4aaff3f2003-06-07 01:04:45 +00001209 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001210 if (i < 0)
1211 return CMD_WARNING;
1212
paul4aaff3f2003-06-07 01:04:45 +00001213 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001214 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001215 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001216
1217 rip_passive_interface_apply_all ();
1218
1219 return CMD_SUCCESS;
1220}
1221
1222/* Free all configured RIP passive-interface settings. */
1223void
pauldc63bfd2005-10-25 23:31:05 +00001224rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001225{
hasso8a676be2004-10-08 06:36:38 +00001226 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001227 char *str;
1228
paul55468c82005-03-14 20:19:01 +00001229 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001230 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001231 {
1232 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001233 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001234 }
1235 rip_passive_interface_apply_all ();
1236}
1237
1238/* RIP enable network or interface configuration. */
1239DEFUN (rip_network,
1240 rip_network_cmd,
1241 "network (A.B.C.D/M|WORD)",
1242 "Enable routing on an IP network\n"
1243 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1244 "Interface name\n")
1245{
1246 int ret;
1247 struct prefix_ipv4 p;
1248
1249 ret = str2prefix_ipv4 (argv[0], &p);
1250
1251 if (ret)
1252 ret = rip_enable_network_add ((struct prefix *) &p);
1253 else
1254 ret = rip_enable_if_add (argv[0]);
1255
1256 if (ret < 0)
1257 {
1258 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1259 VTY_NEWLINE);
1260 return CMD_WARNING;
1261 }
1262
paul718e3742002-12-13 20:15:29 +00001263 return CMD_SUCCESS;
1264}
1265
1266/* RIP enable network or interface configuration. */
1267DEFUN (no_rip_network,
1268 no_rip_network_cmd,
1269 "no network (A.B.C.D/M|WORD)",
1270 NO_STR
1271 "Enable routing on an IP network\n"
1272 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1273 "Interface name\n")
1274{
1275 int ret;
1276 struct prefix_ipv4 p;
1277
1278 ret = str2prefix_ipv4 (argv[0], &p);
1279
1280 if (ret)
1281 ret = rip_enable_network_delete ((struct prefix *) &p);
1282 else
1283 ret = rip_enable_if_delete (argv[0]);
1284
1285 if (ret < 0)
1286 {
1287 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1288 VTY_NEWLINE);
1289 return CMD_WARNING;
1290 }
1291
paul718e3742002-12-13 20:15:29 +00001292 return CMD_SUCCESS;
1293}
1294
1295/* RIP neighbor configuration set. */
1296DEFUN (rip_neighbor,
1297 rip_neighbor_cmd,
1298 "neighbor A.B.C.D",
1299 "Specify a neighbor router\n"
1300 "Neighbor address\n")
1301{
1302 int ret;
1303 struct prefix_ipv4 p;
1304
1305 ret = str2prefix_ipv4 (argv[0], &p);
1306
1307 if (ret <= 0)
1308 {
1309 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1310 return CMD_WARNING;
1311 }
1312
1313 rip_neighbor_add (&p);
1314
1315 return CMD_SUCCESS;
1316}
1317
1318/* RIP neighbor configuration unset. */
1319DEFUN (no_rip_neighbor,
1320 no_rip_neighbor_cmd,
1321 "no neighbor A.B.C.D",
1322 NO_STR
1323 "Specify a neighbor router\n"
1324 "Neighbor address\n")
1325{
1326 int ret;
1327 struct prefix_ipv4 p;
1328
1329 ret = str2prefix_ipv4 (argv[0], &p);
1330
1331 if (ret <= 0)
1332 {
1333 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1334 return CMD_WARNING;
1335 }
1336
1337 rip_neighbor_delete (&p);
1338
1339 return CMD_SUCCESS;
1340}
1341
1342DEFUN (ip_rip_receive_version,
1343 ip_rip_receive_version_cmd,
1344 "ip rip receive version (1|2)",
1345 IP_STR
1346 "Routing Information Protocol\n"
1347 "Advertisement reception\n"
1348 "Version control\n"
1349 "RIP version 1\n"
1350 "RIP version 2\n")
1351{
1352 struct interface *ifp;
1353 struct rip_interface *ri;
1354
1355 ifp = (struct interface *)vty->index;
1356 ri = ifp->info;
1357
1358 /* Version 1. */
1359 if (atoi (argv[0]) == 1)
1360 {
1361 ri->ri_receive = RI_RIP_VERSION_1;
1362 return CMD_SUCCESS;
1363 }
1364 if (atoi (argv[0]) == 2)
1365 {
1366 ri->ri_receive = RI_RIP_VERSION_2;
1367 return CMD_SUCCESS;
1368 }
1369 return CMD_WARNING;
1370}
1371
1372DEFUN (ip_rip_receive_version_1,
1373 ip_rip_receive_version_1_cmd,
1374 "ip rip receive version 1 2",
1375 IP_STR
1376 "Routing Information Protocol\n"
1377 "Advertisement reception\n"
1378 "Version control\n"
1379 "RIP version 1\n"
1380 "RIP version 2\n")
1381{
1382 struct interface *ifp;
1383 struct rip_interface *ri;
1384
1385 ifp = (struct interface *)vty->index;
1386 ri = ifp->info;
1387
1388 /* Version 1 and 2. */
1389 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1390 return CMD_SUCCESS;
1391}
1392
1393DEFUN (ip_rip_receive_version_2,
1394 ip_rip_receive_version_2_cmd,
1395 "ip rip receive version 2 1",
1396 IP_STR
1397 "Routing Information Protocol\n"
1398 "Advertisement reception\n"
1399 "Version control\n"
1400 "RIP version 2\n"
1401 "RIP version 1\n")
1402{
1403 struct interface *ifp;
1404 struct rip_interface *ri;
1405
1406 ifp = (struct interface *)vty->index;
1407 ri = ifp->info;
1408
1409 /* Version 1 and 2. */
1410 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1411 return CMD_SUCCESS;
1412}
1413
1414DEFUN (no_ip_rip_receive_version,
1415 no_ip_rip_receive_version_cmd,
1416 "no ip rip receive version",
1417 NO_STR
1418 IP_STR
1419 "Routing Information Protocol\n"
1420 "Advertisement reception\n"
1421 "Version control\n")
1422{
1423 struct interface *ifp;
1424 struct rip_interface *ri;
1425
1426 ifp = (struct interface *)vty->index;
1427 ri = ifp->info;
1428
1429 ri->ri_receive = RI_RIP_UNSPEC;
1430 return CMD_SUCCESS;
1431}
1432
1433ALIAS (no_ip_rip_receive_version,
1434 no_ip_rip_receive_version_num_cmd,
1435 "no ip rip receive version (1|2)",
1436 NO_STR
1437 IP_STR
1438 "Routing Information Protocol\n"
1439 "Advertisement reception\n"
1440 "Version control\n"
1441 "Version 1\n"
1442 "Version 2\n")
1443
1444DEFUN (ip_rip_send_version,
1445 ip_rip_send_version_cmd,
1446 "ip rip send version (1|2)",
1447 IP_STR
1448 "Routing Information Protocol\n"
1449 "Advertisement transmission\n"
1450 "Version control\n"
1451 "RIP version 1\n"
1452 "RIP version 2\n")
1453{
1454 struct interface *ifp;
1455 struct rip_interface *ri;
1456
1457 ifp = (struct interface *)vty->index;
1458 ri = ifp->info;
1459
1460 /* Version 1. */
1461 if (atoi (argv[0]) == 1)
1462 {
1463 ri->ri_send = RI_RIP_VERSION_1;
1464 return CMD_SUCCESS;
1465 }
1466 if (atoi (argv[0]) == 2)
1467 {
1468 ri->ri_send = RI_RIP_VERSION_2;
1469 return CMD_SUCCESS;
1470 }
1471 return CMD_WARNING;
1472}
1473
1474DEFUN (ip_rip_send_version_1,
1475 ip_rip_send_version_1_cmd,
1476 "ip rip send version 1 2",
1477 IP_STR
1478 "Routing Information Protocol\n"
1479 "Advertisement transmission\n"
1480 "Version control\n"
1481 "RIP version 1\n"
1482 "RIP version 2\n")
1483{
1484 struct interface *ifp;
1485 struct rip_interface *ri;
1486
1487 ifp = (struct interface *)vty->index;
1488 ri = ifp->info;
1489
1490 /* Version 1 and 2. */
1491 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1492 return CMD_SUCCESS;
1493}
1494
1495DEFUN (ip_rip_send_version_2,
1496 ip_rip_send_version_2_cmd,
1497 "ip rip send version 2 1",
1498 IP_STR
1499 "Routing Information Protocol\n"
1500 "Advertisement transmission\n"
1501 "Version control\n"
1502 "RIP version 2\n"
1503 "RIP version 1\n")
1504{
1505 struct interface *ifp;
1506 struct rip_interface *ri;
1507
1508 ifp = (struct interface *)vty->index;
1509 ri = ifp->info;
1510
1511 /* Version 1 and 2. */
1512 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1513 return CMD_SUCCESS;
1514}
1515
1516DEFUN (no_ip_rip_send_version,
1517 no_ip_rip_send_version_cmd,
1518 "no ip rip send version",
1519 NO_STR
1520 IP_STR
1521 "Routing Information Protocol\n"
1522 "Advertisement transmission\n"
1523 "Version control\n")
1524{
1525 struct interface *ifp;
1526 struct rip_interface *ri;
1527
1528 ifp = (struct interface *)vty->index;
1529 ri = ifp->info;
1530
1531 ri->ri_send = RI_RIP_UNSPEC;
1532 return CMD_SUCCESS;
1533}
1534
1535ALIAS (no_ip_rip_send_version,
1536 no_ip_rip_send_version_num_cmd,
1537 "no ip rip send version (1|2)",
1538 NO_STR
1539 IP_STR
1540 "Routing Information Protocol\n"
1541 "Advertisement transmission\n"
1542 "Version control\n"
1543 "Version 1\n"
1544 "Version 2\n")
1545
1546DEFUN (ip_rip_authentication_mode,
1547 ip_rip_authentication_mode_cmd,
1548 "ip rip authentication mode (md5|text)",
1549 IP_STR
1550 "Routing Information Protocol\n"
1551 "Authentication control\n"
1552 "Authentication mode\n"
1553 "Keyed message digest\n"
1554 "Clear text authentication\n")
1555{
1556 struct interface *ifp;
1557 struct rip_interface *ri;
Paul Jakma15a2b082006-05-04 07:36:34 +00001558 int auth_type;
paul718e3742002-12-13 20:15:29 +00001559
1560 ifp = (struct interface *)vty->index;
1561 ri = ifp->info;
1562
paulca5e5162004-06-06 22:06:33 +00001563 if ( (argc < 1) || (argc > 2) )
1564 {
1565 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1566 return CMD_WARNING;
1567 }
1568
paul718e3742002-12-13 20:15:29 +00001569 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001570 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001571 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001572 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001573 else
1574 {
1575 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1576 return CMD_WARNING;
1577 }
1578
paulca5e5162004-06-06 22:06:33 +00001579 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001580 {
1581 ri->auth_type = auth_type;
1582 return CMD_SUCCESS;
1583 }
paulca5e5162004-06-06 22:06:33 +00001584
Paul Jakma15a2b082006-05-04 07:36:34 +00001585 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001586 {
1587 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1588 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001589 }
paulca5e5162004-06-06 22:06:33 +00001590
1591 if (strncmp ("r", argv[1], 1) == 0)
1592 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1593 else if (strncmp ("o", argv[1], 1) == 0)
1594 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1595 else
1596 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001597
1598 ri->auth_type = auth_type;
1599
paul718e3742002-12-13 20:15:29 +00001600 return CMD_SUCCESS;
1601}
1602
paulca5e5162004-06-06 22:06:33 +00001603ALIAS (ip_rip_authentication_mode,
1604 ip_rip_authentication_mode_authlen_cmd,
1605 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1606 IP_STR
1607 "Routing Information Protocol\n"
1608 "Authentication control\n"
1609 "Authentication mode\n"
1610 "Keyed message digest\n"
1611 "Clear text authentication\n"
1612 "MD5 authentication data length\n"
1613 "RFC compatible\n"
1614 "Old ripd compatible\n")
1615
paul718e3742002-12-13 20:15:29 +00001616DEFUN (no_ip_rip_authentication_mode,
1617 no_ip_rip_authentication_mode_cmd,
1618 "no ip rip authentication mode",
1619 NO_STR
1620 IP_STR
1621 "Routing Information Protocol\n"
1622 "Authentication control\n"
1623 "Authentication mode\n")
1624{
1625 struct interface *ifp;
1626 struct rip_interface *ri;
1627
1628 ifp = (struct interface *)vty->index;
1629 ri = ifp->info;
1630
paul7755a8c2005-06-02 08:20:53 +00001631 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001632 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001633
1634 return CMD_SUCCESS;
1635}
1636
1637ALIAS (no_ip_rip_authentication_mode,
1638 no_ip_rip_authentication_mode_type_cmd,
1639 "no ip rip authentication mode (md5|text)",
1640 NO_STR
1641 IP_STR
1642 "Routing Information Protocol\n"
1643 "Authentication control\n"
1644 "Authentication mode\n"
1645 "Keyed message digest\n"
1646 "Clear text authentication\n")
1647
paulca5e5162004-06-06 22:06:33 +00001648ALIAS (no_ip_rip_authentication_mode,
1649 no_ip_rip_authentication_mode_type_authlen_cmd,
1650 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1651 NO_STR
1652 IP_STR
1653 "Routing Information Protocol\n"
1654 "Authentication control\n"
1655 "Authentication mode\n"
1656 "Keyed message digest\n"
1657 "Clear text authentication\n"
1658 "MD5 authentication data length\n"
1659 "RFC compatible\n"
1660 "Old ripd compatible\n")
1661
paul718e3742002-12-13 20:15:29 +00001662DEFUN (ip_rip_authentication_string,
1663 ip_rip_authentication_string_cmd,
1664 "ip rip authentication string LINE",
1665 IP_STR
1666 "Routing Information Protocol\n"
1667 "Authentication control\n"
1668 "Authentication string\n"
1669 "Authentication string\n")
1670{
1671 struct interface *ifp;
1672 struct rip_interface *ri;
1673
1674 ifp = (struct interface *)vty->index;
1675 ri = ifp->info;
1676
1677 if (strlen (argv[0]) > 16)
1678 {
1679 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1680 VTY_NEWLINE);
1681 return CMD_WARNING;
1682 }
1683
1684 if (ri->key_chain)
1685 {
1686 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1687 return CMD_WARNING;
1688 }
1689
1690 if (ri->auth_str)
1691 free (ri->auth_str);
1692
1693 ri->auth_str = strdup (argv[0]);
1694
1695 return CMD_SUCCESS;
1696}
1697
1698DEFUN (no_ip_rip_authentication_string,
1699 no_ip_rip_authentication_string_cmd,
1700 "no ip rip authentication string",
1701 NO_STR
1702 IP_STR
1703 "Routing Information Protocol\n"
1704 "Authentication control\n"
1705 "Authentication string\n")
1706{
1707 struct interface *ifp;
1708 struct rip_interface *ri;
1709
1710 ifp = (struct interface *)vty->index;
1711 ri = ifp->info;
1712
1713 if (ri->auth_str)
1714 free (ri->auth_str);
1715
1716 ri->auth_str = NULL;
1717
1718 return CMD_SUCCESS;
1719}
1720
1721ALIAS (no_ip_rip_authentication_string,
1722 no_ip_rip_authentication_string2_cmd,
1723 "no ip rip authentication string LINE",
1724 NO_STR
1725 IP_STR
1726 "Routing Information Protocol\n"
1727 "Authentication control\n"
1728 "Authentication string\n"
1729 "Authentication string\n")
1730
1731DEFUN (ip_rip_authentication_key_chain,
1732 ip_rip_authentication_key_chain_cmd,
1733 "ip rip authentication key-chain LINE",
1734 IP_STR
1735 "Routing Information Protocol\n"
1736 "Authentication control\n"
1737 "Authentication key-chain\n"
1738 "name of key-chain\n")
1739{
1740 struct interface *ifp;
1741 struct rip_interface *ri;
1742
1743 ifp = (struct interface *) vty->index;
1744 ri = ifp->info;
1745
1746 if (ri->auth_str)
1747 {
1748 vty_out (vty, "%% authentication string configuration exists%s",
1749 VTY_NEWLINE);
1750 return CMD_WARNING;
1751 }
1752
1753 if (ri->key_chain)
1754 free (ri->key_chain);
1755
1756 ri->key_chain = strdup (argv[0]);
1757
1758 return CMD_SUCCESS;
1759}
1760
1761DEFUN (no_ip_rip_authentication_key_chain,
1762 no_ip_rip_authentication_key_chain_cmd,
1763 "no ip rip authentication key-chain",
1764 NO_STR
1765 IP_STR
1766 "Routing Information Protocol\n"
1767 "Authentication control\n"
1768 "Authentication key-chain\n")
1769{
1770 struct interface *ifp;
1771 struct rip_interface *ri;
1772
1773 ifp = (struct interface *) vty->index;
1774 ri = ifp->info;
1775
1776 if (ri->key_chain)
1777 free (ri->key_chain);
1778
1779 ri->key_chain = NULL;
1780
1781 return CMD_SUCCESS;
1782}
1783
1784ALIAS (no_ip_rip_authentication_key_chain,
1785 no_ip_rip_authentication_key_chain2_cmd,
1786 "no ip rip authentication key-chain LINE",
1787 NO_STR
1788 IP_STR
1789 "Routing Information Protocol\n"
1790 "Authentication control\n"
1791 "Authentication key-chain\n"
1792 "name of key-chain\n")
1793
hasso16705132003-05-25 14:49:19 +00001794/* CHANGED: ip rip split-horizon
1795 Cisco and Zebra's command is
1796 ip split-horizon
1797 */
1798DEFUN (ip_rip_split_horizon,
1799 ip_rip_split_horizon_cmd,
1800 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001801 IP_STR
hasso16705132003-05-25 14:49:19 +00001802 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001803 "Perform split horizon\n")
1804{
1805 struct interface *ifp;
1806 struct rip_interface *ri;
1807
1808 ifp = vty->index;
1809 ri = ifp->info;
1810
hasso16705132003-05-25 14:49:19 +00001811 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001812 return CMD_SUCCESS;
1813}
1814
hasso16705132003-05-25 14:49:19 +00001815DEFUN (ip_rip_split_horizon_poisoned_reverse,
1816 ip_rip_split_horizon_poisoned_reverse_cmd,
1817 "ip rip split-horizon poisoned-reverse",
1818 IP_STR
1819 "Routing Information Protocol\n"
1820 "Perform split horizon\n"
1821 "With poisoned-reverse\n")
1822{
1823 struct interface *ifp;
1824 struct rip_interface *ri;
1825
1826 ifp = vty->index;
1827 ri = ifp->info;
1828
1829 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1830 return CMD_SUCCESS;
1831}
1832
1833/* CHANGED: no ip rip split-horizon
1834 Cisco and Zebra's command is
1835 no ip split-horizon
1836 */
1837DEFUN (no_ip_rip_split_horizon,
1838 no_ip_rip_split_horizon_cmd,
1839 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001840 NO_STR
1841 IP_STR
hasso16705132003-05-25 14:49:19 +00001842 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001843 "Perform split horizon\n")
1844{
1845 struct interface *ifp;
1846 struct rip_interface *ri;
1847
1848 ifp = vty->index;
1849 ri = ifp->info;
1850
hasso16705132003-05-25 14:49:19 +00001851 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001852 return CMD_SUCCESS;
1853}
1854
vincentfac3e842005-10-06 07:45:43 +00001855DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001856 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1857 "no ip rip split-horizon poisoned-reverse",
1858 NO_STR
1859 IP_STR
1860 "Routing Information Protocol\n"
1861 "Perform split horizon\n"
1862 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001863{
1864 struct interface *ifp;
1865 struct rip_interface *ri;
1866
1867 ifp = vty->index;
1868 ri = ifp->info;
1869
1870 switch( ri->split_horizon )
1871 {
1872 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1873 ri->split_horizon = RIP_SPLIT_HORIZON;
1874 default:
1875 break;
1876 }
1877
1878 return CMD_SUCCESS;
1879}
hasso16705132003-05-25 14:49:19 +00001880
paul718e3742002-12-13 20:15:29 +00001881DEFUN (rip_passive_interface,
1882 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001883 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001884 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001885 "Interface name\n"
1886 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001887{
hasso98b718a2004-10-11 12:57:57 +00001888 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001889
1890 if (!strcmp(ifname,"default")) {
1891 passive_default = 1;
1892 rip_passive_nondefault_clean();
1893 return CMD_SUCCESS;
1894 }
1895 if (passive_default)
1896 return rip_passive_nondefault_unset (vty, ifname);
1897 else
1898 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001899}
1900
1901DEFUN (no_rip_passive_interface,
1902 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001903 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001904 NO_STR
1905 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001906 "Interface name\n"
1907 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001908{
hasso98b718a2004-10-11 12:57:57 +00001909 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001910
1911 if (!strcmp(ifname,"default")) {
1912 passive_default = 0;
1913 rip_passive_nondefault_clean();
1914 return CMD_SUCCESS;
1915 }
1916 if (passive_default)
1917 return rip_passive_nondefault_set (vty, ifname);
1918 else
1919 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001920}
1921
1922/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001923static int
paul718e3742002-12-13 20:15:29 +00001924rip_interface_config_write (struct vty *vty)
1925{
hasso52dc7ee2004-09-23 19:18:23 +00001926 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001927 struct interface *ifp;
1928
paul1eb8ef22005-04-07 07:30:20 +00001929 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001930 {
1931 struct rip_interface *ri;
1932
paul718e3742002-12-13 20:15:29 +00001933 ri = ifp->info;
1934
hasso16705132003-05-25 14:49:19 +00001935 /* Do not display the interface if there is no
1936 * configuration about it.
1937 **/
1938 if ((!ifp->desc) &&
1939 (ri->split_horizon == ri->split_horizon_default) &&
1940 (ri->ri_send == RI_RIP_UNSPEC) &&
1941 (ri->ri_receive == RI_RIP_UNSPEC) &&
1942 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001943 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001944 (!ri->auth_str) &&
1945 (!ri->key_chain) )
1946 continue;
1947
paul718e3742002-12-13 20:15:29 +00001948 vty_out (vty, "interface %s%s", ifp->name,
1949 VTY_NEWLINE);
1950
1951 if (ifp->desc)
1952 vty_out (vty, " description %s%s", ifp->desc,
1953 VTY_NEWLINE);
1954
1955 /* Split horizon. */
1956 if (ri->split_horizon != ri->split_horizon_default)
1957 {
hasso16705132003-05-25 14:49:19 +00001958 switch (ri->split_horizon) {
1959 case RIP_SPLIT_HORIZON:
1960 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1961 break;
1962 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1963 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1964 VTY_NEWLINE);
1965 break;
1966 case RIP_NO_SPLIT_HORIZON:
1967 default:
1968 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1969 break;
1970 }
paul718e3742002-12-13 20:15:29 +00001971 }
1972
1973 /* RIP version setting. */
1974 if (ri->ri_send != RI_RIP_UNSPEC)
1975 vty_out (vty, " ip rip send version %s%s",
1976 lookup (ri_version_msg, ri->ri_send),
1977 VTY_NEWLINE);
1978
1979 if (ri->ri_receive != RI_RIP_UNSPEC)
1980 vty_out (vty, " ip rip receive version %s%s",
1981 lookup (ri_version_msg, ri->ri_receive),
1982 VTY_NEWLINE);
1983
1984 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001985 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1986 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001987
paul718e3742002-12-13 20:15:29 +00001988 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001989 {
1990 vty_out (vty, " ip rip authentication mode md5");
1991 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1992 vty_out (vty, " auth-length old-ripd");
1993 else
1994 vty_out (vty, " auth-length rfc");
1995 vty_out (vty, "%s", VTY_NEWLINE);
1996 }
paul718e3742002-12-13 20:15:29 +00001997
1998 if (ri->auth_str)
1999 vty_out (vty, " ip rip authentication string %s%s",
2000 ri->auth_str, VTY_NEWLINE);
2001
2002 if (ri->key_chain)
2003 vty_out (vty, " ip rip authentication key-chain %s%s",
2004 ri->key_chain, VTY_NEWLINE);
2005
2006 vty_out (vty, "!%s", VTY_NEWLINE);
2007 }
2008 return 0;
2009}
2010
2011int
2012config_write_rip_network (struct vty *vty, int config_mode)
2013{
hasso8a676be2004-10-08 06:36:38 +00002014 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002015 char *ifname;
2016 struct route_node *node;
2017
2018 /* Network type RIP enable interface statement. */
2019 for (node = route_top (rip_enable_network); node; node = route_next (node))
2020 if (node->info)
2021 vty_out (vty, "%s%s/%d%s",
2022 config_mode ? " network " : " ",
2023 inet_ntoa (node->p.u.prefix4),
2024 node->p.prefixlen,
2025 VTY_NEWLINE);
2026
2027 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002028 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002029 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2030 vty_out (vty, "%s%s%s",
2031 config_mode ? " network " : " ",
2032 ifname,
2033 VTY_NEWLINE);
2034
2035 /* RIP neighbors listing. */
2036 for (node = route_top (rip->neighbor); node; node = route_next (node))
2037 if (node->info)
2038 vty_out (vty, "%s%s%s",
2039 config_mode ? " neighbor " : " ",
2040 inet_ntoa (node->p.u.prefix4),
2041 VTY_NEWLINE);
2042
2043 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002044 if (config_mode) {
2045 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002046 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002047 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002048 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2049 vty_out (vty, " %spassive-interface %s%s",
2050 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2051 }
paul718e3742002-12-13 20:15:29 +00002052
2053 return 0;
2054}
2055
2056struct cmd_node interface_node =
2057{
2058 INTERFACE_NODE,
2059 "%s(config-if)# ",
2060 1,
2061};
2062
2063/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002064static int
paul718e3742002-12-13 20:15:29 +00002065rip_interface_new_hook (struct interface *ifp)
2066{
2067 ifp->info = rip_interface_new ();
2068 return 0;
2069}
2070
2071/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002072static int
paul718e3742002-12-13 20:15:29 +00002073rip_interface_delete_hook (struct interface *ifp)
2074{
2075 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002076 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002077 return 0;
2078}
2079
2080/* Allocate and initialize interface vector. */
2081void
pauldc63bfd2005-10-25 23:31:05 +00002082rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002083{
2084 /* Default initial size of interface vector. */
2085 if_init();
2086 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2087 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2088
2089 /* RIP network init. */
2090 rip_enable_interface = vector_init (1);
2091 rip_enable_network = route_table_init ();
2092
2093 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002094 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002095
2096 /* Install interface node. */
2097 install_node (&interface_node, rip_interface_config_write);
2098
2099 /* Install commands. */
2100 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002101 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002102 install_default (INTERFACE_NODE);
2103 install_element (INTERFACE_NODE, &interface_desc_cmd);
2104 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2105 install_element (RIP_NODE, &rip_network_cmd);
2106 install_element (RIP_NODE, &no_rip_network_cmd);
2107 install_element (RIP_NODE, &rip_neighbor_cmd);
2108 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2109
2110 install_element (RIP_NODE, &rip_passive_interface_cmd);
2111 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2112
2113 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2114 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2115 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2116 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2117 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2118
2119 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2120 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2121 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2122 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2123 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2124
2125 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002126 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002127 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2128 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002129 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002130
2131 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2132 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2133 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2134
2135 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2136 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2137 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2138
hasso16705132003-05-25 14:49:19 +00002139 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2140 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2141 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2142 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002143}