blob: 17b25ff8aed0d04f901f2641bc77c0b1eddfa9ec [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Interface related function for RIP.
2 * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "command.h"
25#include "if.h"
26#include "sockunion.h"
27#include "prefix.h"
28#include "memory.h"
29#include "network.h"
30#include "table.h"
31#include "log.h"
32#include "stream.h"
33#include "thread.h"
34#include "zclient.h"
35#include "filter.h"
36#include "sockopt.h"
pauledd7c242003-06-04 13:59:38 +000037#include "privs.h"
paul718e3742002-12-13 20:15:29 +000038
39#include "zebra/connected.h"
40
41#include "ripd/ripd.h"
42#include "ripd/rip_debug.h"
pauldc63bfd2005-10-25 23:31:05 +000043#include "ripd/rip_interface.h"
44
45/* static prototypes */
46static void rip_enable_apply (struct interface *);
47static void rip_passive_interface_apply (struct interface *);
48static int rip_if_down(struct interface *ifp);
49static int rip_enable_if_lookup (const char *ifname);
50static int rip_enable_network_lookup2 (struct connected *connected);
51static void rip_enable_apply_all (void);
52
paul718e3742002-12-13 20:15:29 +000053struct message ri_version_msg[] =
54{
55 {RI_RIP_VERSION_1, "1"},
56 {RI_RIP_VERSION_2, "2"},
57 {RI_RIP_VERSION_1_AND_2, "1 2"},
58 {0, NULL}
59};
60
pauledd7c242003-06-04 13:59:38 +000061extern struct zebra_privs_t ripd_privs;
62
paul718e3742002-12-13 20:15:29 +000063/* RIP enabled network vector. */
64vector rip_enable_interface;
65
66/* RIP enabled interface table. */
67struct route_table *rip_enable_network;
68
69/* Vector to store passive-interface name. */
paul4aaff3f2003-06-07 01:04:45 +000070static int passive_default; /* are we in passive-interface default mode? */
71vector Vrip_passive_nondefault;
paul718e3742002-12-13 20:15:29 +000072
73/* Join to the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000074static int
paul718e3742002-12-13 20:15:29 +000075ipv4_multicast_join (int sock,
76 struct in_addr group,
77 struct in_addr ifa,
78 unsigned int ifindex)
79{
80 int ret;
81
82 ret = setsockopt_multicast_ipv4 (sock,
83 IP_ADD_MEMBERSHIP,
84 ifa,
85 group.s_addr,
86 ifindex);
87
88 if (ret < 0)
89 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
ajs6099b3b2004-11-20 02:06:59 +000090 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +000091
92 return ret;
93}
94
95/* Leave from the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000096static int
paul718e3742002-12-13 20:15:29 +000097ipv4_multicast_leave (int sock,
98 struct in_addr group,
99 struct in_addr ifa,
100 unsigned int ifindex)
101{
102 int ret;
103
104 ret = setsockopt_multicast_ipv4 (sock,
105 IP_DROP_MEMBERSHIP,
106 ifa,
107 group.s_addr,
108 ifindex);
109
110 if (ret < 0)
111 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
112
113 return ret;
114}
115
116/* Allocate new RIP's interface configuration. */
pauldc63bfd2005-10-25 23:31:05 +0000117static struct rip_interface *
118rip_interface_new (void)
paul718e3742002-12-13 20:15:29 +0000119{
120 struct rip_interface *ri;
121
122 ri = XMALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
123 memset (ri, 0, sizeof (struct rip_interface));
124
125 /* Default authentication type is simple password for Cisco
126 compatibility. */
paul7755a8c2005-06-02 08:20:53 +0000127 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +0000128 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +0000129
130 /* Set default split-horizon behavior. If the interface is Frame
131 Relay or SMDS is enabled, the default value for split-horizon is
132 off. But currently Zebra does detect Frame Relay or SMDS
133 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000134 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000135 ri->split_horizon = ri->split_horizon_default;
136
137 return ri;
138}
139
140void
paul1a517862004-08-19 04:03:08 +0000141rip_interface_multicast_set (int sock, struct connected *connected)
paul718e3742002-12-13 20:15:29 +0000142{
hasso3fb9cd62004-10-19 19:44:43 +0000143 struct in_addr addr;
paulcc1131a2003-10-15 23:20:17 +0000144 struct prefix_ipv4 *p;
paulc49ad8f2004-10-22 10:27:28 +0000145
146 assert (connected != NULL);
147
148 if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected))
149 p = (struct prefix_ipv4 *) connected->destination;
150 else
151 p = (struct prefix_ipv4 *) connected->address;
152
153 addr = p->prefix;
paul718e3742002-12-13 20:15:29 +0000154
paul1a517862004-08-19 04:03:08 +0000155 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
156 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000157 {
158 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
159 "source address %s for interface %s",
160 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000161 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000162 }
paul2c61ae32005-08-16 15:22:14 +0000163
hasso3fb9cd62004-10-19 19:44:43 +0000164 return;
165}
paul718e3742002-12-13 20:15:29 +0000166
167/* Send RIP request packet to specified interface. */
pauldc63bfd2005-10-25 23:31:05 +0000168static void
paul718e3742002-12-13 20:15:29 +0000169rip_request_interface_send (struct interface *ifp, u_char version)
170{
171 struct sockaddr_in to;
172
173 /* RIPv2 support multicast. */
174 if (version == RIPv2 && if_is_multicast (ifp))
175 {
176
177 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000178 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000179
paul931cd542004-01-23 15:31:42 +0000180 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000181 return;
182 }
183
184 /* RIPv1 and non multicast interface. */
185 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
186 {
paul1eb8ef22005-04-07 07:30:20 +0000187 struct listnode *cnode, *cnnode;
188 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000189
190 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000191 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000192
paul1eb8ef22005-04-07 07:30:20 +0000193 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000194 {
hasso3fb9cd62004-10-19 19:44:43 +0000195 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000196 {
197 memset (&to, 0, sizeof (struct sockaddr_in));
198 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000199 if (connected->destination)
200 /* use specified broadcast or point-to-point destination addr */
201 to.sin_addr = connected->destination->u.prefix4;
202 else
203 /* calculate the appropriate broadcast address */
204 to.sin_addr.s_addr =
205 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
206 connected->address->prefixlen);
paul718e3742002-12-13 20:15:29 +0000207
paul718e3742002-12-13 20:15:29 +0000208 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000209 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000210
paul931cd542004-01-23 15:31:42 +0000211 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000212 }
213 }
214 }
215}
216
217/* This will be executed when interface goes up. */
pauldc63bfd2005-10-25 23:31:05 +0000218static void
paul718e3742002-12-13 20:15:29 +0000219rip_request_interface (struct interface *ifp)
220{
221 struct rip_interface *ri;
222
223 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
224 if (if_is_loopback (ifp))
225 return;
226
227 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000228 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000229 return;
230
231 /* Fetch RIP interface information. */
232 ri = ifp->info;
233
234
235 /* If there is no version configuration in the interface,
236 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000237 {
238 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
239 rip->version_send : ri->ri_send);
240 if (vsend & RIPv1)
241 rip_request_interface_send (ifp, RIPv1);
242 if (vsend & RIPv2)
243 rip_request_interface_send (ifp, RIPv2);
244 }
paul718e3742002-12-13 20:15:29 +0000245}
246
247/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000248static void
paul718e3742002-12-13 20:15:29 +0000249rip_request_neighbor (struct in_addr addr)
250{
251 struct sockaddr_in to;
252
253 memset (&to, 0, sizeof (struct sockaddr_in));
254 to.sin_port = htons (RIP_PORT_DEFAULT);
255 to.sin_addr = addr;
256
paul931cd542004-01-23 15:31:42 +0000257 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000258}
259
260/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000261static void
262rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000263{
264 struct route_node *rp;
265
266 if (! rip)
267 return;
268
269 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000270 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000271
272 /* Send request to all neighbor. */
273 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
274 if (rp->info)
275 rip_request_neighbor (rp->p.u.prefix4);
276}
277
278/* Multicast packet receive socket. */
pauldc63bfd2005-10-25 23:31:05 +0000279static int
paul718e3742002-12-13 20:15:29 +0000280rip_multicast_join (struct interface *ifp, int sock)
281{
hasso52dc7ee2004-09-23 19:18:23 +0000282 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000283 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000284
paul2e3b2e42002-12-13 21:03:13 +0000285 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000286 {
287 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000288 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000289
paul1eb8ef22005-04-07 07:30:20 +0000290 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000291 {
292 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000293 struct in_addr group;
294
paul1eb8ef22005-04-07 07:30:20 +0000295 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000296
297 if (p->family != AF_INET)
298 continue;
299
300 group.s_addr = htonl (INADDR_RIP_GROUP);
301 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
302 return -1;
303 else
304 return 0;
305 }
306 }
307 return 0;
308}
309
310/* Leave from multicast group. */
pauldc63bfd2005-10-25 23:31:05 +0000311static void
paul718e3742002-12-13 20:15:29 +0000312rip_multicast_leave (struct interface *ifp, int sock)
313{
hasso52dc7ee2004-09-23 19:18:23 +0000314 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000315 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000316
317 if (if_is_up (ifp) && if_is_multicast (ifp))
318 {
319 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000320 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000321
paul1eb8ef22005-04-07 07:30:20 +0000322 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000323 {
324 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000325 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000326
paul718e3742002-12-13 20:15:29 +0000327 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000328
paul718e3742002-12-13 20:15:29 +0000329 if (p->family != AF_INET)
330 continue;
331
332 group.s_addr = htonl (INADDR_RIP_GROUP);
333 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
334 return;
335 }
336 }
337}
338
339/* Is there and address on interface that I could use ? */
pauldc63bfd2005-10-25 23:31:05 +0000340static int
paul718e3742002-12-13 20:15:29 +0000341rip_if_ipv4_address_check (struct interface *ifp)
342{
343 struct listnode *nn;
344 struct connected *connected;
345 int count = 0;
346
paul1eb8ef22005-04-07 07:30:20 +0000347 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
348 {
349 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000350
paul1eb8ef22005-04-07 07:30:20 +0000351 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000352
paul1eb8ef22005-04-07 07:30:20 +0000353 if (p->family == AF_INET)
354 count++;
355 }
paul718e3742002-12-13 20:15:29 +0000356
357 return count;
358}
paul31a476c2003-09-29 19:54:53 +0000359
360
361
362
363/* Does this address belongs to me ? */
364int
365if_check_address (struct in_addr addr)
366{
hasso52dc7ee2004-09-23 19:18:23 +0000367 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000368 struct interface *ifp;
369
370 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000371 {
hasso52dc7ee2004-09-23 19:18:23 +0000372 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000373 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000374
paul1eb8ef22005-04-07 07:30:20 +0000375 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000376 {
paul31a476c2003-09-29 19:54:53 +0000377 struct prefix_ipv4 *p;
378
paul31a476c2003-09-29 19:54:53 +0000379 p = (struct prefix_ipv4 *) connected->address;
380
381 if (p->family != AF_INET)
382 continue;
383
384 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
385 return 1;
386 }
387 }
388 return 0;
389}
390
391/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
392int
393if_valid_neighbor (struct in_addr addr)
394{
hasso52dc7ee2004-09-23 19:18:23 +0000395 struct listnode *node;
paul31a476c2003-09-29 19:54:53 +0000396 struct connected *connected = NULL;
paul1eb8ef22005-04-07 07:30:20 +0000397 struct interface *ifp;
paul31a476c2003-09-29 19:54:53 +0000398 struct prefix_ipv4 *p;
hasso3fb9cd62004-10-19 19:44:43 +0000399 struct prefix_ipv4 pa;
400
401 pa.family = AF_INET;
402 pa.prefix = addr;
403 pa.prefixlen = IPV4_MAX_PREFIXLEN;
paul31a476c2003-09-29 19:54:53 +0000404
paul1eb8ef22005-04-07 07:30:20 +0000405 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000406 {
hasso52dc7ee2004-09-23 19:18:23 +0000407 struct listnode *cnode;
paul31a476c2003-09-29 19:54:53 +0000408
paul1eb8ef22005-04-07 07:30:20 +0000409 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000410 {
paul31a476c2003-09-29 19:54:53 +0000411 if (if_is_pointopoint (ifp))
412 {
413 p = (struct prefix_ipv4 *) connected->address;
414
415 if (p && p->family == AF_INET)
416 {
417 if (IPV4_ADDR_SAME (&p->prefix, &addr))
418 return 1;
419
420 p = (struct prefix_ipv4 *) connected->destination;
hasso3fb9cd62004-10-19 19:44:43 +0000421 if (p)
422 {
423 if (IPV4_ADDR_SAME (&p->prefix, &addr))
424 return 1;
425 }
426 else
427 {
428 if (prefix_match(connected->address,(struct prefix *)&pa))
429 return 1;
430 }
paul31a476c2003-09-29 19:54:53 +0000431 }
432 }
433 else
434 {
hasso3fb9cd62004-10-19 19:44:43 +0000435 if ((connected->address->family == AF_INET) &&
436 prefix_match(connected->address,(struct prefix *)&pa))
437 return 1;
paul31a476c2003-09-29 19:54:53 +0000438 }
439 }
440 }
441 return 0;
442}
paul718e3742002-12-13 20:15:29 +0000443
444/* Inteface link down message processing. */
445int
446rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
447{
448 struct interface *ifp;
449 struct stream *s;
450
451 s = zclient->ibuf;
452
453 /* zebra_interface_state_read() updates interface structure in
454 iflist. */
455 ifp = zebra_interface_state_read(s);
456
457 if (ifp == NULL)
458 return 0;
459
460 rip_if_down(ifp);
461
462 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000463 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000464 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
465
466 return 0;
467}
468
469/* Inteface link up message processing */
470int
471rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
472{
473 struct interface *ifp;
474
475 /* zebra_interface_state_read () updates interface structure in
476 iflist. */
477 ifp = zebra_interface_state_read (zclient->ibuf);
478
479 if (ifp == NULL)
480 return 0;
481
482 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000483 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000484 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
485
486 /* Check if this interface is RIP enabled or not.*/
487 rip_enable_apply (ifp);
488
489 /* Check for a passive interface */
490 rip_passive_interface_apply (ifp);
491
492 /* Apply distribute list to the all interface. */
493 rip_distribute_update_interface (ifp);
494
495 return 0;
496}
497
498/* Inteface addition message from zebra. */
499int
500rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
501{
502 struct interface *ifp;
503
504 ifp = zebra_interface_add_read (zclient->ibuf);
505
506 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000507 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000508 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
509
510 /* Check if this interface is RIP enabled or not.*/
511 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000512
513 /* Check for a passive interface */
514 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000515
516 /* Apply distribute list to the all interface. */
517 rip_distribute_update_interface (ifp);
518
519 /* rip_request_neighbor_all (); */
520
hasso16705132003-05-25 14:49:19 +0000521 /* Check interface routemap. */
522 rip_if_rmap_update_interface (ifp);
523
paul718e3742002-12-13 20:15:29 +0000524 return 0;
525}
526
527int
528rip_interface_delete (int command, struct zclient *zclient,
529 zebra_size_t length)
530{
531 struct interface *ifp;
532 struct stream *s;
533
534
535 s = zclient->ibuf;
536 /* zebra_interface_state_read() updates interface structure in iflist */
537 ifp = zebra_interface_state_read(s);
538
539 if (ifp == NULL)
540 return 0;
541
542 if (if_is_up (ifp)) {
543 rip_if_down(ifp);
544 }
545
546 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
547 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
548
549 /* To support pseudo interface do not free interface structure. */
550 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000551 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000552
553 return 0;
554}
555
556void
pauldc63bfd2005-10-25 23:31:05 +0000557rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000558{
hasso52dc7ee2004-09-23 19:18:23 +0000559 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000560 struct interface *ifp;
561 struct rip_interface *ri;
562
paul1eb8ef22005-04-07 07:30:20 +0000563 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000564 {
paul718e3742002-12-13 20:15:29 +0000565 ri = ifp->info;
566
567 ri->enable_network = 0;
568 ri->enable_interface = 0;
569 ri->running = 0;
570
571 if (ri->t_wakeup)
572 {
573 thread_cancel (ri->t_wakeup);
574 ri->t_wakeup = NULL;
575 }
576 }
577}
578
579void
pauldc63bfd2005-10-25 23:31:05 +0000580rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000581{
hasso52dc7ee2004-09-23 19:18:23 +0000582 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000583 struct interface *ifp;
584 struct rip_interface *ri;
585
paul1eb8ef22005-04-07 07:30:20 +0000586 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000587 {
paul718e3742002-12-13 20:15:29 +0000588 ri = ifp->info;
589
590 ri->enable_network = 0;
591 ri->enable_interface = 0;
592 ri->running = 0;
593
594 ri->ri_send = RI_RIP_UNSPEC;
595 ri->ri_receive = RI_RIP_UNSPEC;
596
paul7755a8c2005-06-02 08:20:53 +0000597 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000598
599 if (ri->auth_str)
600 {
601 free (ri->auth_str);
602 ri->auth_str = NULL;
603 }
604 if (ri->key_chain)
605 {
606 free (ri->key_chain);
607 ri->key_chain = NULL;
608 }
609
hasso16705132003-05-25 14:49:19 +0000610 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
611 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000612
613 ri->list[RIP_FILTER_IN] = NULL;
614 ri->list[RIP_FILTER_OUT] = NULL;
615
616 ri->prefix[RIP_FILTER_IN] = NULL;
617 ri->prefix[RIP_FILTER_OUT] = NULL;
618
619 if (ri->t_wakeup)
620 {
621 thread_cancel (ri->t_wakeup);
622 ri->t_wakeup = NULL;
623 }
624
625 ri->recv_badpackets = 0;
626 ri->recv_badroutes = 0;
627 ri->sent_updates = 0;
628
629 ri->passive = 0;
630 }
631}
632
633int
634rip_if_down(struct interface *ifp)
635{
636 struct route_node *rp;
637 struct rip_info *rinfo;
638 struct rip_interface *ri = NULL;
639 if (rip)
640 {
641 for (rp = route_top (rip->table); rp; rp = route_next (rp))
642 if ((rinfo = rp->info) != NULL)
643 {
644 /* Routes got through this interface. */
645 if (rinfo->ifindex == ifp->ifindex &&
646 rinfo->type == ZEBRA_ROUTE_RIP &&
647 rinfo->sub_type == RIP_ROUTE_RTE)
648 {
649 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
650 &rinfo->nexthop,
651 rinfo->ifindex);
652
653 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
654 (struct prefix_ipv4 *)&rp->p,
655 rinfo->ifindex);
656 }
657 else
658 {
659 /* All redistributed routes but static and system */
660 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000661 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000662 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
663 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
664 (struct prefix_ipv4 *)&rp->p,
665 rinfo->ifindex);
666 }
667 }
668 }
669
670 ri = ifp->info;
671
672 if (ri->running)
673 {
674 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000675 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000676
677 /* Leave from multicast group. */
678 rip_multicast_leave (ifp, rip->sock);
679
680 ri->running = 0;
681 }
682
683 return 0;
684}
685
686/* Needed for stop RIP process. */
687void
688rip_if_down_all ()
689{
690 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000691 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000692
paul1eb8ef22005-04-07 07:30:20 +0000693 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
694 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000695}
696
hasso16705132003-05-25 14:49:19 +0000697static void
pauldc63bfd2005-10-25 23:31:05 +0000698rip_apply_address_add (struct connected *ifc)
699{
hasso16705132003-05-25 14:49:19 +0000700 struct prefix_ipv4 address;
701 struct prefix *p;
702
703 if (!rip)
704 return;
705
706 if (! if_is_up(ifc->ifp))
707 return;
708
709 p = ifc->address;
710
711 memset (&address, 0, sizeof (address));
712 address.family = p->family;
713 address.prefix = p->u.prefix4;
714 address.prefixlen = p->prefixlen;
715 apply_mask_ipv4(&address);
716
717 /* Check if this interface is RIP enabled or not
718 or Check if this address's prefix is RIP enabled */
719 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
720 (rip_enable_network_lookup2(ifc) >= 0))
721 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000722 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000723
724}
725
paul718e3742002-12-13 20:15:29 +0000726int
727rip_interface_address_add (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_ADD,
734 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000735
736 if (ifc == NULL)
737 return 0;
738
739 p = ifc->address;
740
741 if (p->family == AF_INET)
742 {
743 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000744 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000745 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000746
paul878ef2e2003-09-23 23:41:50 +0000747 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000748 /* Check if this prefix needs to be redistributed */
749 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000750
751#ifdef HAVE_SNMP
752 rip_ifaddr_add (ifc->ifp, ifc);
753#endif /* HAVE_SNMP */
754 }
755
756 return 0;
757}
758
hasso16705132003-05-25 14:49:19 +0000759static void
760rip_apply_address_del (struct connected *ifc) {
761 struct prefix_ipv4 address;
762 struct prefix *p;
763
764 if (!rip)
765 return;
766
767 if (! if_is_up(ifc->ifp))
768 return;
769
770 p = ifc->address;
771
772 memset (&address, 0, sizeof (address));
773 address.family = p->family;
774 address.prefix = p->u.prefix4;
775 address.prefixlen = p->prefixlen;
776 apply_mask_ipv4(&address);
777
778 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
779 &address, ifc->ifp->ifindex);
780}
781
paul718e3742002-12-13 20:15:29 +0000782int
783rip_interface_address_delete (int command, struct zclient *zclient,
784 zebra_size_t length)
785{
786 struct connected *ifc;
787 struct prefix *p;
788
paul0a589352004-05-08 11:48:26 +0000789 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
790 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000791
792 if (ifc)
793 {
794 p = ifc->address;
795 if (p->family == AF_INET)
796 {
797 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000798 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000799 inet_ntoa (p->u.prefix4), p->prefixlen);
800
801#ifdef HAVE_SNMP
802 rip_ifaddr_delete (ifc->ifp, ifc);
803#endif /* HAVE_SNMP */
804
hasso16705132003-05-25 14:49:19 +0000805 /* Chech wether this prefix needs to be removed */
806 rip_apply_address_del(ifc);
807
paul718e3742002-12-13 20:15:29 +0000808 }
809
810 connected_free (ifc);
811
812 }
813
814 return 0;
815}
816
817/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000818/* Check wether the interface has at least a connected prefix that
819 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000820static int
hasso16705132003-05-25 14:49:19 +0000821rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000822{
paul1eb8ef22005-04-07 07:30:20 +0000823 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000824 struct connected *connected;
825 struct prefix_ipv4 address;
826
paul1eb8ef22005-04-07 07:30:20 +0000827 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
828 {
829 struct prefix *p;
830 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000831
paul1eb8ef22005-04-07 07:30:20 +0000832 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000833
paul1eb8ef22005-04-07 07:30:20 +0000834 if (p->family == AF_INET)
835 {
836 address.family = AF_INET;
837 address.prefix = p->u.prefix4;
838 address.prefixlen = IPV4_MAX_BITLEN;
839
840 node = route_node_match (rip_enable_network,
841 (struct prefix *)&address);
842 if (node)
843 {
844 route_unlock_node (node);
845 return 1;
846 }
847 }
848 }
paul718e3742002-12-13 20:15:29 +0000849 return -1;
850}
851
hasso16705132003-05-25 14:49:19 +0000852/* Check wether connected is within the ripng_enable_network table. */
853int
854rip_enable_network_lookup2 (struct connected *connected)
855{
856 struct prefix_ipv4 address;
857 struct prefix *p;
858
859 p = connected->address;
860
861 if (p->family == AF_INET) {
862 struct route_node *node;
863
864 address.family = p->family;
865 address.prefix = p->u.prefix4;
866 address.prefixlen = IPV4_MAX_BITLEN;
867
868 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
869 node = route_node_match (rip_enable_network,
870 (struct prefix *)&address);
871
872 if (node) {
873 route_unlock_node (node);
874 return 1;
875 }
876 }
877
878 return -1;
879}
paul718e3742002-12-13 20:15:29 +0000880/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000881static int
paul718e3742002-12-13 20:15:29 +0000882rip_enable_network_add (struct prefix *p)
883{
884 struct route_node *node;
885
886 node = route_node_get (rip_enable_network, p);
887
888 if (node->info)
889 {
890 route_unlock_node (node);
891 return -1;
892 }
893 else
hasso8a676be2004-10-08 06:36:38 +0000894 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000895
hasso16705132003-05-25 14:49:19 +0000896 /* XXX: One should find a better solution than a generic one */
897 rip_enable_apply_all();
898
paul718e3742002-12-13 20:15:29 +0000899 return 1;
900}
901
902/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000903static int
paul718e3742002-12-13 20:15:29 +0000904rip_enable_network_delete (struct prefix *p)
905{
906 struct route_node *node;
907
908 node = route_node_lookup (rip_enable_network, p);
909 if (node)
910 {
911 node->info = NULL;
912
913 /* Unlock info lock. */
914 route_unlock_node (node);
915
916 /* Unlock lookup lock. */
917 route_unlock_node (node);
918
hasso16705132003-05-25 14:49:19 +0000919 /* XXX: One should find a better solution than a generic one */
920 rip_enable_apply_all ();
921
paul718e3742002-12-13 20:15:29 +0000922 return 1;
923 }
924 return -1;
925}
926
927/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000928static int
hasso98b718a2004-10-11 12:57:57 +0000929rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000930{
hasso8a676be2004-10-08 06:36:38 +0000931 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000932 char *str;
933
paul55468c82005-03-14 20:19:01 +0000934 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000935 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
936 if (strcmp (str, ifname) == 0)
937 return i;
938 return -1;
939}
940
941/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000942static int
hasso98b718a2004-10-11 12:57:57 +0000943rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000944{
945 int ret;
946
947 ret = rip_enable_if_lookup (ifname);
948 if (ret >= 0)
949 return -1;
950
951 vector_set (rip_enable_interface, strdup (ifname));
952
hasso16705132003-05-25 14:49:19 +0000953 rip_enable_apply_all(); /* TODOVJ */
954
paul718e3742002-12-13 20:15:29 +0000955 return 1;
956}
957
958/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000959static int
hasso98b718a2004-10-11 12:57:57 +0000960rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000961{
962 int index;
963 char *str;
964
965 index = rip_enable_if_lookup (ifname);
966 if (index < 0)
967 return -1;
968
969 str = vector_slot (rip_enable_interface, index);
970 free (str);
971 vector_unset (rip_enable_interface, index);
972
hasso16705132003-05-25 14:49:19 +0000973 rip_enable_apply_all(); /* TODOVJ */
974
paul718e3742002-12-13 20:15:29 +0000975 return 1;
976}
977
978/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000979static int
paul718e3742002-12-13 20:15:29 +0000980rip_interface_wakeup (struct thread *t)
981{
982 struct interface *ifp;
983 struct rip_interface *ri;
984
985 /* Get interface. */
986 ifp = THREAD_ARG (t);
987
988 ri = ifp->info;
989 ri->t_wakeup = NULL;
990
991 /* Join to multicast group. */
992 if (rip_multicast_join (ifp, rip->sock) < 0)
993 {
994 zlog_err ("multicast join failed, interface %s not running", ifp->name);
995 return 0;
996 }
997
998 /* Set running flag. */
999 ri->running = 1;
1000
1001 /* Send RIP request to the interface. */
1002 rip_request_interface (ifp);
1003
1004 return 0;
1005}
1006
1007int rip_redistribute_check (int);
1008
pauldc63bfd2005-10-25 23:31:05 +00001009static void
paul718e3742002-12-13 20:15:29 +00001010rip_connect_set (struct interface *ifp, int set)
1011{
paul1eb8ef22005-04-07 07:30:20 +00001012 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001013 struct connected *connected;
1014 struct prefix_ipv4 address;
1015
paul1eb8ef22005-04-07 07:30:20 +00001016 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
1017 {
1018 struct prefix *p;
1019 p = connected->address;
paul718e3742002-12-13 20:15:29 +00001020
paul1eb8ef22005-04-07 07:30:20 +00001021 if (p->family != AF_INET)
1022 continue;
paul718e3742002-12-13 20:15:29 +00001023
paul1eb8ef22005-04-07 07:30:20 +00001024 address.family = AF_INET;
1025 address.prefix = p->u.prefix4;
1026 address.prefixlen = p->prefixlen;
1027 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +00001028
paul1eb8ef22005-04-07 07:30:20 +00001029 if (set) {
1030 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1031 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1032 (rip_enable_network_lookup2(connected) >= 0))
1033 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +00001034 &address, connected->ifp->ifindex,
1035 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +00001036 } else
1037 {
1038 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1039 &address, connected->ifp->ifindex);
1040 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1041 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +00001042 &address, connected->ifp->ifindex,
1043 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +00001044 }
1045 }
paul718e3742002-12-13 20:15:29 +00001046}
1047
1048/* Update interface status. */
1049void
1050rip_enable_apply (struct interface *ifp)
1051{
1052 int ret;
1053 struct rip_interface *ri = NULL;
1054
1055 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001056 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001057 return;
1058
1059 ri = ifp->info;
1060
1061 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001062 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001063
1064 /* If the interface is matched. */
1065 if (ret > 0)
1066 ri->enable_network = 1;
1067 else
1068 ri->enable_network = 0;
1069
1070 /* Check interface name configuration. */
1071 ret = rip_enable_if_lookup (ifp->name);
1072 if (ret >= 0)
1073 ri->enable_interface = 1;
1074 else
1075 ri->enable_interface = 0;
1076
1077 /* any interface MUST have an IPv4 address */
1078 if ( ! rip_if_ipv4_address_check (ifp) )
1079 {
1080 ri->enable_network = 0;
1081 ri->enable_interface = 0;
1082 }
1083
1084 /* Update running status of the interface. */
1085 if (ri->enable_network || ri->enable_interface)
1086 {
paul718e3742002-12-13 20:15:29 +00001087 {
1088 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001089 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001090
1091 /* Add interface wake up thread. */
1092 if (! ri->t_wakeup)
1093 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1094 ifp, 1);
1095 rip_connect_set (ifp, 1);
1096 }
1097 }
1098 else
1099 {
1100 if (ri->running)
1101 {
hasso16705132003-05-25 14:49:19 +00001102 /* Might as well clean up the route table as well
1103 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1104 **/
paul718e3742002-12-13 20:15:29 +00001105 rip_if_down(ifp);
1106
paul718e3742002-12-13 20:15:29 +00001107 rip_connect_set (ifp, 0);
1108 }
1109 }
1110}
1111
1112/* Apply network configuration to all interface. */
1113void
1114rip_enable_apply_all ()
1115{
1116 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001117 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001118
1119 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001120 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1121 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001122}
1123
1124int
1125rip_neighbor_lookup (struct sockaddr_in *from)
1126{
1127 struct prefix_ipv4 p;
1128 struct route_node *node;
1129
1130 memset (&p, 0, sizeof (struct prefix_ipv4));
1131 p.family = AF_INET;
1132 p.prefix = from->sin_addr;
1133 p.prefixlen = IPV4_MAX_BITLEN;
1134
1135 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1136 if (node)
1137 {
1138 route_unlock_node (node);
1139 return 1;
1140 }
1141 return 0;
1142}
1143
1144/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001145static int
paul718e3742002-12-13 20:15:29 +00001146rip_neighbor_add (struct prefix_ipv4 *p)
1147{
1148 struct route_node *node;
1149
1150 node = route_node_get (rip->neighbor, (struct prefix *) p);
1151
1152 if (node->info)
1153 return -1;
1154
1155 node->info = rip->neighbor;
1156
1157 return 0;
1158}
1159
1160/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001161static int
paul718e3742002-12-13 20:15:29 +00001162rip_neighbor_delete (struct prefix_ipv4 *p)
1163{
1164 struct route_node *node;
1165
1166 /* Lock for look up. */
1167 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1168 if (! node)
1169 return -1;
1170
1171 node->info = NULL;
1172
1173 /* Unlock lookup lock. */
1174 route_unlock_node (node);
1175
1176 /* Unlock real neighbor information lock. */
1177 route_unlock_node (node);
1178
1179 return 0;
1180}
1181
1182/* Clear all network and neighbor configuration. */
1183void
1184rip_clean_network ()
1185{
hasso8a676be2004-10-08 06:36:38 +00001186 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001187 char *str;
1188 struct route_node *rn;
1189
1190 /* rip_enable_network. */
1191 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1192 if (rn->info)
1193 {
1194 rn->info = NULL;
1195 route_unlock_node (rn);
1196 }
1197
1198 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001199 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001200 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1201 {
1202 free (str);
1203 vector_slot (rip_enable_interface, i) = NULL;
1204 }
1205}
1206
1207/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001208static int
hasso98b718a2004-10-11 12:57:57 +00001209rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001210{
hasso8a676be2004-10-08 06:36:38 +00001211 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001212 char *str;
1213
paul55468c82005-03-14 20:19:01 +00001214 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001215 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001216 if (strcmp (str, ifname) == 0)
1217 return i;
1218 return -1;
1219}
1220
1221void
1222rip_passive_interface_apply (struct interface *ifp)
1223{
paul718e3742002-12-13 20:15:29 +00001224 struct rip_interface *ri;
1225
1226 ri = ifp->info;
1227
paul4aaff3f2003-06-07 01:04:45 +00001228 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1229 passive_default : !passive_default);
1230
1231 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001232 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001233}
1234
pauldc63bfd2005-10-25 23:31:05 +00001235static void
1236rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001237{
1238 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001239 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001240
paul1eb8ef22005-04-07 07:30:20 +00001241 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1242 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001243}
1244
1245/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001246static int
hasso98b718a2004-10-11 12:57:57 +00001247rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001248{
paul4aaff3f2003-06-07 01:04:45 +00001249 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001250 return CMD_WARNING;
1251
paul4aaff3f2003-06-07 01:04:45 +00001252 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001253
1254 rip_passive_interface_apply_all ();
1255
1256 return CMD_SUCCESS;
1257}
1258
pauldc63bfd2005-10-25 23:31:05 +00001259static int
hasso98b718a2004-10-11 12:57:57 +00001260rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001261{
1262 int i;
1263 char *str;
1264
paul4aaff3f2003-06-07 01:04:45 +00001265 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001266 if (i < 0)
1267 return CMD_WARNING;
1268
paul4aaff3f2003-06-07 01:04:45 +00001269 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001270 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001271 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001272
1273 rip_passive_interface_apply_all ();
1274
1275 return CMD_SUCCESS;
1276}
1277
1278/* Free all configured RIP passive-interface settings. */
1279void
pauldc63bfd2005-10-25 23:31:05 +00001280rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001281{
hasso8a676be2004-10-08 06:36:38 +00001282 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001283 char *str;
1284
paul55468c82005-03-14 20:19:01 +00001285 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001286 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001287 {
1288 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001289 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001290 }
1291 rip_passive_interface_apply_all ();
1292}
1293
1294/* RIP enable network or interface configuration. */
1295DEFUN (rip_network,
1296 rip_network_cmd,
1297 "network (A.B.C.D/M|WORD)",
1298 "Enable routing on an IP network\n"
1299 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1300 "Interface name\n")
1301{
1302 int ret;
1303 struct prefix_ipv4 p;
1304
1305 ret = str2prefix_ipv4 (argv[0], &p);
1306
1307 if (ret)
1308 ret = rip_enable_network_add ((struct prefix *) &p);
1309 else
1310 ret = rip_enable_if_add (argv[0]);
1311
1312 if (ret < 0)
1313 {
1314 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1315 VTY_NEWLINE);
1316 return CMD_WARNING;
1317 }
1318
paul718e3742002-12-13 20:15:29 +00001319 return CMD_SUCCESS;
1320}
1321
1322/* RIP enable network or interface configuration. */
1323DEFUN (no_rip_network,
1324 no_rip_network_cmd,
1325 "no network (A.B.C.D/M|WORD)",
1326 NO_STR
1327 "Enable routing on an IP network\n"
1328 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1329 "Interface name\n")
1330{
1331 int ret;
1332 struct prefix_ipv4 p;
1333
1334 ret = str2prefix_ipv4 (argv[0], &p);
1335
1336 if (ret)
1337 ret = rip_enable_network_delete ((struct prefix *) &p);
1338 else
1339 ret = rip_enable_if_delete (argv[0]);
1340
1341 if (ret < 0)
1342 {
1343 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1344 VTY_NEWLINE);
1345 return CMD_WARNING;
1346 }
1347
paul718e3742002-12-13 20:15:29 +00001348 return CMD_SUCCESS;
1349}
1350
1351/* RIP neighbor configuration set. */
1352DEFUN (rip_neighbor,
1353 rip_neighbor_cmd,
1354 "neighbor A.B.C.D",
1355 "Specify a neighbor router\n"
1356 "Neighbor address\n")
1357{
1358 int ret;
1359 struct prefix_ipv4 p;
1360
1361 ret = str2prefix_ipv4 (argv[0], &p);
1362
1363 if (ret <= 0)
1364 {
1365 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1366 return CMD_WARNING;
1367 }
1368
1369 rip_neighbor_add (&p);
1370
1371 return CMD_SUCCESS;
1372}
1373
1374/* RIP neighbor configuration unset. */
1375DEFUN (no_rip_neighbor,
1376 no_rip_neighbor_cmd,
1377 "no neighbor A.B.C.D",
1378 NO_STR
1379 "Specify a neighbor router\n"
1380 "Neighbor address\n")
1381{
1382 int ret;
1383 struct prefix_ipv4 p;
1384
1385 ret = str2prefix_ipv4 (argv[0], &p);
1386
1387 if (ret <= 0)
1388 {
1389 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1390 return CMD_WARNING;
1391 }
1392
1393 rip_neighbor_delete (&p);
1394
1395 return CMD_SUCCESS;
1396}
1397
1398DEFUN (ip_rip_receive_version,
1399 ip_rip_receive_version_cmd,
1400 "ip rip receive version (1|2)",
1401 IP_STR
1402 "Routing Information Protocol\n"
1403 "Advertisement reception\n"
1404 "Version control\n"
1405 "RIP version 1\n"
1406 "RIP version 2\n")
1407{
1408 struct interface *ifp;
1409 struct rip_interface *ri;
1410
1411 ifp = (struct interface *)vty->index;
1412 ri = ifp->info;
1413
1414 /* Version 1. */
1415 if (atoi (argv[0]) == 1)
1416 {
1417 ri->ri_receive = RI_RIP_VERSION_1;
1418 return CMD_SUCCESS;
1419 }
1420 if (atoi (argv[0]) == 2)
1421 {
1422 ri->ri_receive = RI_RIP_VERSION_2;
1423 return CMD_SUCCESS;
1424 }
1425 return CMD_WARNING;
1426}
1427
1428DEFUN (ip_rip_receive_version_1,
1429 ip_rip_receive_version_1_cmd,
1430 "ip rip receive version 1 2",
1431 IP_STR
1432 "Routing Information Protocol\n"
1433 "Advertisement reception\n"
1434 "Version control\n"
1435 "RIP version 1\n"
1436 "RIP version 2\n")
1437{
1438 struct interface *ifp;
1439 struct rip_interface *ri;
1440
1441 ifp = (struct interface *)vty->index;
1442 ri = ifp->info;
1443
1444 /* Version 1 and 2. */
1445 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1446 return CMD_SUCCESS;
1447}
1448
1449DEFUN (ip_rip_receive_version_2,
1450 ip_rip_receive_version_2_cmd,
1451 "ip rip receive version 2 1",
1452 IP_STR
1453 "Routing Information Protocol\n"
1454 "Advertisement reception\n"
1455 "Version control\n"
1456 "RIP version 2\n"
1457 "RIP version 1\n")
1458{
1459 struct interface *ifp;
1460 struct rip_interface *ri;
1461
1462 ifp = (struct interface *)vty->index;
1463 ri = ifp->info;
1464
1465 /* Version 1 and 2. */
1466 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1467 return CMD_SUCCESS;
1468}
1469
1470DEFUN (no_ip_rip_receive_version,
1471 no_ip_rip_receive_version_cmd,
1472 "no ip rip receive version",
1473 NO_STR
1474 IP_STR
1475 "Routing Information Protocol\n"
1476 "Advertisement reception\n"
1477 "Version control\n")
1478{
1479 struct interface *ifp;
1480 struct rip_interface *ri;
1481
1482 ifp = (struct interface *)vty->index;
1483 ri = ifp->info;
1484
1485 ri->ri_receive = RI_RIP_UNSPEC;
1486 return CMD_SUCCESS;
1487}
1488
1489ALIAS (no_ip_rip_receive_version,
1490 no_ip_rip_receive_version_num_cmd,
1491 "no ip rip receive version (1|2)",
1492 NO_STR
1493 IP_STR
1494 "Routing Information Protocol\n"
1495 "Advertisement reception\n"
1496 "Version control\n"
1497 "Version 1\n"
1498 "Version 2\n")
1499
1500DEFUN (ip_rip_send_version,
1501 ip_rip_send_version_cmd,
1502 "ip rip send version (1|2)",
1503 IP_STR
1504 "Routing Information Protocol\n"
1505 "Advertisement transmission\n"
1506 "Version control\n"
1507 "RIP version 1\n"
1508 "RIP version 2\n")
1509{
1510 struct interface *ifp;
1511 struct rip_interface *ri;
1512
1513 ifp = (struct interface *)vty->index;
1514 ri = ifp->info;
1515
1516 /* Version 1. */
1517 if (atoi (argv[0]) == 1)
1518 {
1519 ri->ri_send = RI_RIP_VERSION_1;
1520 return CMD_SUCCESS;
1521 }
1522 if (atoi (argv[0]) == 2)
1523 {
1524 ri->ri_send = RI_RIP_VERSION_2;
1525 return CMD_SUCCESS;
1526 }
1527 return CMD_WARNING;
1528}
1529
1530DEFUN (ip_rip_send_version_1,
1531 ip_rip_send_version_1_cmd,
1532 "ip rip send version 1 2",
1533 IP_STR
1534 "Routing Information Protocol\n"
1535 "Advertisement transmission\n"
1536 "Version control\n"
1537 "RIP version 1\n"
1538 "RIP version 2\n")
1539{
1540 struct interface *ifp;
1541 struct rip_interface *ri;
1542
1543 ifp = (struct interface *)vty->index;
1544 ri = ifp->info;
1545
1546 /* Version 1 and 2. */
1547 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1548 return CMD_SUCCESS;
1549}
1550
1551DEFUN (ip_rip_send_version_2,
1552 ip_rip_send_version_2_cmd,
1553 "ip rip send version 2 1",
1554 IP_STR
1555 "Routing Information Protocol\n"
1556 "Advertisement transmission\n"
1557 "Version control\n"
1558 "RIP version 2\n"
1559 "RIP version 1\n")
1560{
1561 struct interface *ifp;
1562 struct rip_interface *ri;
1563
1564 ifp = (struct interface *)vty->index;
1565 ri = ifp->info;
1566
1567 /* Version 1 and 2. */
1568 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1569 return CMD_SUCCESS;
1570}
1571
1572DEFUN (no_ip_rip_send_version,
1573 no_ip_rip_send_version_cmd,
1574 "no ip rip send version",
1575 NO_STR
1576 IP_STR
1577 "Routing Information Protocol\n"
1578 "Advertisement transmission\n"
1579 "Version control\n")
1580{
1581 struct interface *ifp;
1582 struct rip_interface *ri;
1583
1584 ifp = (struct interface *)vty->index;
1585 ri = ifp->info;
1586
1587 ri->ri_send = RI_RIP_UNSPEC;
1588 return CMD_SUCCESS;
1589}
1590
1591ALIAS (no_ip_rip_send_version,
1592 no_ip_rip_send_version_num_cmd,
1593 "no ip rip send version (1|2)",
1594 NO_STR
1595 IP_STR
1596 "Routing Information Protocol\n"
1597 "Advertisement transmission\n"
1598 "Version control\n"
1599 "Version 1\n"
1600 "Version 2\n")
1601
1602DEFUN (ip_rip_authentication_mode,
1603 ip_rip_authentication_mode_cmd,
1604 "ip rip authentication mode (md5|text)",
1605 IP_STR
1606 "Routing Information Protocol\n"
1607 "Authentication control\n"
1608 "Authentication mode\n"
1609 "Keyed message digest\n"
1610 "Clear text authentication\n")
1611{
1612 struct interface *ifp;
1613 struct rip_interface *ri;
1614
1615 ifp = (struct interface *)vty->index;
1616 ri = ifp->info;
1617
paulca5e5162004-06-06 22:06:33 +00001618 if ( (argc < 1) || (argc > 2) )
1619 {
1620 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1621 return CMD_WARNING;
1622 }
1623
paul718e3742002-12-13 20:15:29 +00001624 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1625 ri->auth_type = RIP_AUTH_MD5;
1626 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1627 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1628 else
1629 {
1630 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1631 return CMD_WARNING;
1632 }
1633
paulca5e5162004-06-06 22:06:33 +00001634 if (argc == 1)
1635 return CMD_SUCCESS;
1636
1637 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1638 {
1639 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1640 return CMD_WARNING;
1641}
1642
1643 if (strncmp ("r", argv[1], 1) == 0)
1644 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1645 else if (strncmp ("o", argv[1], 1) == 0)
1646 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1647 else
1648 return CMD_WARNING;
1649
paul718e3742002-12-13 20:15:29 +00001650 return CMD_SUCCESS;
1651}
1652
paulca5e5162004-06-06 22:06:33 +00001653ALIAS (ip_rip_authentication_mode,
1654 ip_rip_authentication_mode_authlen_cmd,
1655 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1656 IP_STR
1657 "Routing Information Protocol\n"
1658 "Authentication control\n"
1659 "Authentication mode\n"
1660 "Keyed message digest\n"
1661 "Clear text authentication\n"
1662 "MD5 authentication data length\n"
1663 "RFC compatible\n"
1664 "Old ripd compatible\n")
1665
paul718e3742002-12-13 20:15:29 +00001666DEFUN (no_ip_rip_authentication_mode,
1667 no_ip_rip_authentication_mode_cmd,
1668 "no ip rip authentication mode",
1669 NO_STR
1670 IP_STR
1671 "Routing Information Protocol\n"
1672 "Authentication control\n"
1673 "Authentication mode\n")
1674{
1675 struct interface *ifp;
1676 struct rip_interface *ri;
1677
1678 ifp = (struct interface *)vty->index;
1679 ri = ifp->info;
1680
paul7755a8c2005-06-02 08:20:53 +00001681 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001682 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001683
1684 return CMD_SUCCESS;
1685}
1686
1687ALIAS (no_ip_rip_authentication_mode,
1688 no_ip_rip_authentication_mode_type_cmd,
1689 "no ip rip authentication mode (md5|text)",
1690 NO_STR
1691 IP_STR
1692 "Routing Information Protocol\n"
1693 "Authentication control\n"
1694 "Authentication mode\n"
1695 "Keyed message digest\n"
1696 "Clear text authentication\n")
1697
paulca5e5162004-06-06 22:06:33 +00001698ALIAS (no_ip_rip_authentication_mode,
1699 no_ip_rip_authentication_mode_type_authlen_cmd,
1700 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1701 NO_STR
1702 IP_STR
1703 "Routing Information Protocol\n"
1704 "Authentication control\n"
1705 "Authentication mode\n"
1706 "Keyed message digest\n"
1707 "Clear text authentication\n"
1708 "MD5 authentication data length\n"
1709 "RFC compatible\n"
1710 "Old ripd compatible\n")
1711
paul718e3742002-12-13 20:15:29 +00001712DEFUN (ip_rip_authentication_string,
1713 ip_rip_authentication_string_cmd,
1714 "ip rip authentication string LINE",
1715 IP_STR
1716 "Routing Information Protocol\n"
1717 "Authentication control\n"
1718 "Authentication string\n"
1719 "Authentication string\n")
1720{
1721 struct interface *ifp;
1722 struct rip_interface *ri;
1723
1724 ifp = (struct interface *)vty->index;
1725 ri = ifp->info;
1726
1727 if (strlen (argv[0]) > 16)
1728 {
1729 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1730 VTY_NEWLINE);
1731 return CMD_WARNING;
1732 }
1733
1734 if (ri->key_chain)
1735 {
1736 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1737 return CMD_WARNING;
1738 }
1739
1740 if (ri->auth_str)
1741 free (ri->auth_str);
1742
1743 ri->auth_str = strdup (argv[0]);
1744
1745 return CMD_SUCCESS;
1746}
1747
1748DEFUN (no_ip_rip_authentication_string,
1749 no_ip_rip_authentication_string_cmd,
1750 "no ip rip authentication string",
1751 NO_STR
1752 IP_STR
1753 "Routing Information Protocol\n"
1754 "Authentication control\n"
1755 "Authentication string\n")
1756{
1757 struct interface *ifp;
1758 struct rip_interface *ri;
1759
1760 ifp = (struct interface *)vty->index;
1761 ri = ifp->info;
1762
1763 if (ri->auth_str)
1764 free (ri->auth_str);
1765
1766 ri->auth_str = NULL;
1767
1768 return CMD_SUCCESS;
1769}
1770
1771ALIAS (no_ip_rip_authentication_string,
1772 no_ip_rip_authentication_string2_cmd,
1773 "no ip rip authentication string LINE",
1774 NO_STR
1775 IP_STR
1776 "Routing Information Protocol\n"
1777 "Authentication control\n"
1778 "Authentication string\n"
1779 "Authentication string\n")
1780
1781DEFUN (ip_rip_authentication_key_chain,
1782 ip_rip_authentication_key_chain_cmd,
1783 "ip rip authentication key-chain LINE",
1784 IP_STR
1785 "Routing Information Protocol\n"
1786 "Authentication control\n"
1787 "Authentication key-chain\n"
1788 "name of key-chain\n")
1789{
1790 struct interface *ifp;
1791 struct rip_interface *ri;
1792
1793 ifp = (struct interface *) vty->index;
1794 ri = ifp->info;
1795
1796 if (ri->auth_str)
1797 {
1798 vty_out (vty, "%% authentication string configuration exists%s",
1799 VTY_NEWLINE);
1800 return CMD_WARNING;
1801 }
1802
1803 if (ri->key_chain)
1804 free (ri->key_chain);
1805
1806 ri->key_chain = strdup (argv[0]);
1807
1808 return CMD_SUCCESS;
1809}
1810
1811DEFUN (no_ip_rip_authentication_key_chain,
1812 no_ip_rip_authentication_key_chain_cmd,
1813 "no ip rip authentication key-chain",
1814 NO_STR
1815 IP_STR
1816 "Routing Information Protocol\n"
1817 "Authentication control\n"
1818 "Authentication key-chain\n")
1819{
1820 struct interface *ifp;
1821 struct rip_interface *ri;
1822
1823 ifp = (struct interface *) vty->index;
1824 ri = ifp->info;
1825
1826 if (ri->key_chain)
1827 free (ri->key_chain);
1828
1829 ri->key_chain = NULL;
1830
1831 return CMD_SUCCESS;
1832}
1833
1834ALIAS (no_ip_rip_authentication_key_chain,
1835 no_ip_rip_authentication_key_chain2_cmd,
1836 "no ip rip authentication key-chain LINE",
1837 NO_STR
1838 IP_STR
1839 "Routing Information Protocol\n"
1840 "Authentication control\n"
1841 "Authentication key-chain\n"
1842 "name of key-chain\n")
1843
hasso16705132003-05-25 14:49:19 +00001844/* CHANGED: ip rip split-horizon
1845 Cisco and Zebra's command is
1846 ip split-horizon
1847 */
1848DEFUN (ip_rip_split_horizon,
1849 ip_rip_split_horizon_cmd,
1850 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001851 IP_STR
hasso16705132003-05-25 14:49:19 +00001852 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001853 "Perform split horizon\n")
1854{
1855 struct interface *ifp;
1856 struct rip_interface *ri;
1857
1858 ifp = vty->index;
1859 ri = ifp->info;
1860
hasso16705132003-05-25 14:49:19 +00001861 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001862 return CMD_SUCCESS;
1863}
1864
hasso16705132003-05-25 14:49:19 +00001865DEFUN (ip_rip_split_horizon_poisoned_reverse,
1866 ip_rip_split_horizon_poisoned_reverse_cmd,
1867 "ip rip split-horizon poisoned-reverse",
1868 IP_STR
1869 "Routing Information Protocol\n"
1870 "Perform split horizon\n"
1871 "With poisoned-reverse\n")
1872{
1873 struct interface *ifp;
1874 struct rip_interface *ri;
1875
1876 ifp = vty->index;
1877 ri = ifp->info;
1878
1879 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1880 return CMD_SUCCESS;
1881}
1882
1883/* CHANGED: no ip rip split-horizon
1884 Cisco and Zebra's command is
1885 no ip split-horizon
1886 */
1887DEFUN (no_ip_rip_split_horizon,
1888 no_ip_rip_split_horizon_cmd,
1889 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001890 NO_STR
1891 IP_STR
hasso16705132003-05-25 14:49:19 +00001892 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001893 "Perform split horizon\n")
1894{
1895 struct interface *ifp;
1896 struct rip_interface *ri;
1897
1898 ifp = vty->index;
1899 ri = ifp->info;
1900
hasso16705132003-05-25 14:49:19 +00001901 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001902 return CMD_SUCCESS;
1903}
1904
vincentfac3e842005-10-06 07:45:43 +00001905DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001906 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1907 "no ip rip split-horizon poisoned-reverse",
1908 NO_STR
1909 IP_STR
1910 "Routing Information Protocol\n"
1911 "Perform split horizon\n"
1912 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001913{
1914 struct interface *ifp;
1915 struct rip_interface *ri;
1916
1917 ifp = vty->index;
1918 ri = ifp->info;
1919
1920 switch( ri->split_horizon )
1921 {
1922 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1923 ri->split_horizon = RIP_SPLIT_HORIZON;
1924 default:
1925 break;
1926 }
1927
1928 return CMD_SUCCESS;
1929}
hasso16705132003-05-25 14:49:19 +00001930
paul718e3742002-12-13 20:15:29 +00001931DEFUN (rip_passive_interface,
1932 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001933 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001934 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001935 "Interface name\n"
1936 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001937{
hasso98b718a2004-10-11 12:57:57 +00001938 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001939
1940 if (!strcmp(ifname,"default")) {
1941 passive_default = 1;
1942 rip_passive_nondefault_clean();
1943 return CMD_SUCCESS;
1944 }
1945 if (passive_default)
1946 return rip_passive_nondefault_unset (vty, ifname);
1947 else
1948 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001949}
1950
1951DEFUN (no_rip_passive_interface,
1952 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001953 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001954 NO_STR
1955 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001956 "Interface name\n"
1957 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001958{
hasso98b718a2004-10-11 12:57:57 +00001959 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001960
1961 if (!strcmp(ifname,"default")) {
1962 passive_default = 0;
1963 rip_passive_nondefault_clean();
1964 return CMD_SUCCESS;
1965 }
1966 if (passive_default)
1967 return rip_passive_nondefault_set (vty, ifname);
1968 else
1969 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001970}
1971
1972/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001973static int
paul718e3742002-12-13 20:15:29 +00001974rip_interface_config_write (struct vty *vty)
1975{
hasso52dc7ee2004-09-23 19:18:23 +00001976 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001977 struct interface *ifp;
1978
paul1eb8ef22005-04-07 07:30:20 +00001979 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001980 {
1981 struct rip_interface *ri;
1982
paul718e3742002-12-13 20:15:29 +00001983 ri = ifp->info;
1984
hasso16705132003-05-25 14:49:19 +00001985 /* Do not display the interface if there is no
1986 * configuration about it.
1987 **/
1988 if ((!ifp->desc) &&
1989 (ri->split_horizon == ri->split_horizon_default) &&
1990 (ri->ri_send == RI_RIP_UNSPEC) &&
1991 (ri->ri_receive == RI_RIP_UNSPEC) &&
1992 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001993 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001994 (!ri->auth_str) &&
1995 (!ri->key_chain) )
1996 continue;
1997
paul718e3742002-12-13 20:15:29 +00001998 vty_out (vty, "interface %s%s", ifp->name,
1999 VTY_NEWLINE);
2000
2001 if (ifp->desc)
2002 vty_out (vty, " description %s%s", ifp->desc,
2003 VTY_NEWLINE);
2004
2005 /* Split horizon. */
2006 if (ri->split_horizon != ri->split_horizon_default)
2007 {
hasso16705132003-05-25 14:49:19 +00002008 switch (ri->split_horizon) {
2009 case RIP_SPLIT_HORIZON:
2010 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
2011 break;
2012 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
2013 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
2014 VTY_NEWLINE);
2015 break;
2016 case RIP_NO_SPLIT_HORIZON:
2017 default:
2018 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2019 break;
2020 }
paul718e3742002-12-13 20:15:29 +00002021 }
2022
2023 /* RIP version setting. */
2024 if (ri->ri_send != RI_RIP_UNSPEC)
2025 vty_out (vty, " ip rip send version %s%s",
2026 lookup (ri_version_msg, ri->ri_send),
2027 VTY_NEWLINE);
2028
2029 if (ri->ri_receive != RI_RIP_UNSPEC)
2030 vty_out (vty, " ip rip receive version %s%s",
2031 lookup (ri_version_msg, ri->ri_receive),
2032 VTY_NEWLINE);
2033
2034 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00002035 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2036 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00002037
paul718e3742002-12-13 20:15:29 +00002038 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002039 {
2040 vty_out (vty, " ip rip authentication mode md5");
2041 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2042 vty_out (vty, " auth-length old-ripd");
2043 else
2044 vty_out (vty, " auth-length rfc");
2045 vty_out (vty, "%s", VTY_NEWLINE);
2046 }
paul718e3742002-12-13 20:15:29 +00002047
2048 if (ri->auth_str)
2049 vty_out (vty, " ip rip authentication string %s%s",
2050 ri->auth_str, VTY_NEWLINE);
2051
2052 if (ri->key_chain)
2053 vty_out (vty, " ip rip authentication key-chain %s%s",
2054 ri->key_chain, VTY_NEWLINE);
2055
2056 vty_out (vty, "!%s", VTY_NEWLINE);
2057 }
2058 return 0;
2059}
2060
2061int
2062config_write_rip_network (struct vty *vty, int config_mode)
2063{
hasso8a676be2004-10-08 06:36:38 +00002064 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002065 char *ifname;
2066 struct route_node *node;
2067
2068 /* Network type RIP enable interface statement. */
2069 for (node = route_top (rip_enable_network); node; node = route_next (node))
2070 if (node->info)
2071 vty_out (vty, "%s%s/%d%s",
2072 config_mode ? " network " : " ",
2073 inet_ntoa (node->p.u.prefix4),
2074 node->p.prefixlen,
2075 VTY_NEWLINE);
2076
2077 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002078 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002079 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2080 vty_out (vty, "%s%s%s",
2081 config_mode ? " network " : " ",
2082 ifname,
2083 VTY_NEWLINE);
2084
2085 /* RIP neighbors listing. */
2086 for (node = route_top (rip->neighbor); node; node = route_next (node))
2087 if (node->info)
2088 vty_out (vty, "%s%s%s",
2089 config_mode ? " neighbor " : " ",
2090 inet_ntoa (node->p.u.prefix4),
2091 VTY_NEWLINE);
2092
2093 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002094 if (config_mode) {
2095 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002096 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002097 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002098 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2099 vty_out (vty, " %spassive-interface %s%s",
2100 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2101 }
paul718e3742002-12-13 20:15:29 +00002102
2103 return 0;
2104}
2105
2106struct cmd_node interface_node =
2107{
2108 INTERFACE_NODE,
2109 "%s(config-if)# ",
2110 1,
2111};
2112
2113/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002114static int
paul718e3742002-12-13 20:15:29 +00002115rip_interface_new_hook (struct interface *ifp)
2116{
2117 ifp->info = rip_interface_new ();
2118 return 0;
2119}
2120
2121/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002122static int
paul718e3742002-12-13 20:15:29 +00002123rip_interface_delete_hook (struct interface *ifp)
2124{
2125 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002126 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002127 return 0;
2128}
2129
2130/* Allocate and initialize interface vector. */
2131void
pauldc63bfd2005-10-25 23:31:05 +00002132rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002133{
2134 /* Default initial size of interface vector. */
2135 if_init();
2136 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2137 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2138
2139 /* RIP network init. */
2140 rip_enable_interface = vector_init (1);
2141 rip_enable_network = route_table_init ();
2142
2143 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002144 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002145
2146 /* Install interface node. */
2147 install_node (&interface_node, rip_interface_config_write);
2148
2149 /* Install commands. */
2150 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002151 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002152 install_default (INTERFACE_NODE);
2153 install_element (INTERFACE_NODE, &interface_desc_cmd);
2154 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2155 install_element (RIP_NODE, &rip_network_cmd);
2156 install_element (RIP_NODE, &no_rip_network_cmd);
2157 install_element (RIP_NODE, &rip_neighbor_cmd);
2158 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2159
2160 install_element (RIP_NODE, &rip_passive_interface_cmd);
2161 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2162
2163 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2164 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2165 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2166 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2167 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2168
2169 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2170 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2171 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2172 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2173 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2174
2175 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002176 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002177 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2178 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002179 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002180
2181 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2182 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2183 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2184
2185 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2186 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2187 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2188
hasso16705132003-05-25 14:49:19 +00002189 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2190 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2191 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2192 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002193}