blob: b6d9240f64734e584c5571526e79292f7259a831 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Interface related function for RIP.
2 * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "command.h"
25#include "if.h"
26#include "sockunion.h"
27#include "prefix.h"
28#include "memory.h"
29#include "network.h"
30#include "table.h"
31#include "log.h"
32#include "stream.h"
33#include "thread.h"
34#include "zclient.h"
35#include "filter.h"
36#include "sockopt.h"
pauledd7c242003-06-04 13:59:38 +000037#include "privs.h"
paul718e3742002-12-13 20:15:29 +000038
39#include "zebra/connected.h"
40
41#include "ripd/ripd.h"
42#include "ripd/rip_debug.h"
pauldc63bfd2005-10-25 23:31:05 +000043#include "ripd/rip_interface.h"
44
45/* static prototypes */
46static void rip_enable_apply (struct interface *);
47static void rip_passive_interface_apply (struct interface *);
48static int rip_if_down(struct interface *ifp);
49static int rip_enable_if_lookup (const char *ifname);
50static int rip_enable_network_lookup2 (struct connected *connected);
51static void rip_enable_apply_all (void);
52
paul718e3742002-12-13 20:15:29 +000053struct message ri_version_msg[] =
54{
55 {RI_RIP_VERSION_1, "1"},
56 {RI_RIP_VERSION_2, "2"},
57 {RI_RIP_VERSION_1_AND_2, "1 2"},
paul718e3742002-12-13 20:15:29 +000058};
59
pauledd7c242003-06-04 13:59:38 +000060extern struct zebra_privs_t ripd_privs;
61
paul718e3742002-12-13 20:15:29 +000062/* RIP enabled network vector. */
63vector rip_enable_interface;
64
65/* RIP enabled interface table. */
66struct route_table *rip_enable_network;
67
68/* Vector to store passive-interface name. */
paul4aaff3f2003-06-07 01:04:45 +000069static int passive_default; /* are we in passive-interface default mode? */
70vector Vrip_passive_nondefault;
paul718e3742002-12-13 20:15:29 +000071
72/* Join to the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000073static int
paul718e3742002-12-13 20:15:29 +000074ipv4_multicast_join (int sock,
75 struct in_addr group,
76 struct in_addr ifa,
77 unsigned int ifindex)
78{
79 int ret;
80
81 ret = setsockopt_multicast_ipv4 (sock,
82 IP_ADD_MEMBERSHIP,
83 ifa,
84 group.s_addr,
85 ifindex);
86
87 if (ret < 0)
88 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
ajs6099b3b2004-11-20 02:06:59 +000089 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +000090
91 return ret;
92}
93
94/* Leave from the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000095static int
paul718e3742002-12-13 20:15:29 +000096ipv4_multicast_leave (int sock,
97 struct in_addr group,
98 struct in_addr ifa,
99 unsigned int ifindex)
100{
101 int ret;
102
103 ret = setsockopt_multicast_ipv4 (sock,
104 IP_DROP_MEMBERSHIP,
105 ifa,
106 group.s_addr,
107 ifindex);
108
109 if (ret < 0)
110 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
111
112 return ret;
113}
114
115/* Allocate new RIP's interface configuration. */
pauldc63bfd2005-10-25 23:31:05 +0000116static struct rip_interface *
117rip_interface_new (void)
paul718e3742002-12-13 20:15:29 +0000118{
119 struct rip_interface *ri;
120
121 ri = XMALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
122 memset (ri, 0, sizeof (struct rip_interface));
123
124 /* Default authentication type is simple password for Cisco
125 compatibility. */
paul7755a8c2005-06-02 08:20:53 +0000126 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +0000127 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +0000128
129 /* Set default split-horizon behavior. If the interface is Frame
130 Relay or SMDS is enabled, the default value for split-horizon is
131 off. But currently Zebra does detect Frame Relay or SMDS
132 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000133 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000134 ri->split_horizon = ri->split_horizon_default;
135
136 return ri;
137}
138
139void
paul1a517862004-08-19 04:03:08 +0000140rip_interface_multicast_set (int sock, struct connected *connected)
paul718e3742002-12-13 20:15:29 +0000141{
hasso3fb9cd62004-10-19 19:44:43 +0000142 struct in_addr addr;
paulc49ad8f2004-10-22 10:27:28 +0000143
144 assert (connected != NULL);
145
Andrew J. Schorre4529632006-12-12 19:18:21 +0000146 addr = CONNECTED_ID(connected)->u.prefix4;
paul718e3742002-12-13 20:15:29 +0000147
paul1a517862004-08-19 04:03:08 +0000148 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
149 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000150 {
151 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
152 "source address %s for interface %s",
153 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000154 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000155 }
paul2c61ae32005-08-16 15:22:14 +0000156
hasso3fb9cd62004-10-19 19:44:43 +0000157 return;
158}
paul718e3742002-12-13 20:15:29 +0000159
160/* Send RIP request packet to specified interface. */
pauldc63bfd2005-10-25 23:31:05 +0000161static void
paul718e3742002-12-13 20:15:29 +0000162rip_request_interface_send (struct interface *ifp, u_char version)
163{
164 struct sockaddr_in to;
165
166 /* RIPv2 support multicast. */
167 if (version == RIPv2 && if_is_multicast (ifp))
168 {
169
170 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000171 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000172
paul931cd542004-01-23 15:31:42 +0000173 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000174 return;
175 }
176
177 /* RIPv1 and non multicast interface. */
178 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
179 {
paul1eb8ef22005-04-07 07:30:20 +0000180 struct listnode *cnode, *cnnode;
181 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000182
183 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000184 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000185
paul1eb8ef22005-04-07 07:30:20 +0000186 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000187 {
hasso3fb9cd62004-10-19 19:44:43 +0000188 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000189 {
190 memset (&to, 0, sizeof (struct sockaddr_in));
191 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000192 if (connected->destination)
Andrew J. Schorre4529632006-12-12 19:18:21 +0000193 /* use specified broadcast or peer destination addr */
hasso3fb9cd62004-10-19 19:44:43 +0000194 to.sin_addr = connected->destination->u.prefix4;
Andrew J. Schorre4529632006-12-12 19:18:21 +0000195 else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
hasso3fb9cd62004-10-19 19:44:43 +0000196 /* calculate the appropriate broadcast address */
197 to.sin_addr.s_addr =
198 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
199 connected->address->prefixlen);
Andrew J. Schorre4529632006-12-12 19:18:21 +0000200 else
201 /* do not know where to send the packet */
202 continue;
paul718e3742002-12-13 20:15:29 +0000203
paul718e3742002-12-13 20:15:29 +0000204 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000205 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000206
paul931cd542004-01-23 15:31:42 +0000207 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000208 }
209 }
210 }
211}
212
213/* This will be executed when interface goes up. */
pauldc63bfd2005-10-25 23:31:05 +0000214static void
paul718e3742002-12-13 20:15:29 +0000215rip_request_interface (struct interface *ifp)
216{
217 struct rip_interface *ri;
218
219 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
220 if (if_is_loopback (ifp))
221 return;
222
223 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000224 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000225 return;
226
227 /* Fetch RIP interface information. */
228 ri = ifp->info;
229
230
231 /* If there is no version configuration in the interface,
232 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000233 {
234 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
235 rip->version_send : ri->ri_send);
236 if (vsend & RIPv1)
237 rip_request_interface_send (ifp, RIPv1);
238 if (vsend & RIPv2)
239 rip_request_interface_send (ifp, RIPv2);
240 }
paul718e3742002-12-13 20:15:29 +0000241}
242
243/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000244static void
paul718e3742002-12-13 20:15:29 +0000245rip_request_neighbor (struct in_addr addr)
246{
247 struct sockaddr_in to;
248
249 memset (&to, 0, sizeof (struct sockaddr_in));
250 to.sin_port = htons (RIP_PORT_DEFAULT);
251 to.sin_addr = addr;
252
paul931cd542004-01-23 15:31:42 +0000253 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000254}
255
256/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000257static void
258rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000259{
260 struct route_node *rp;
261
262 if (! rip)
263 return;
264
265 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000266 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000267
268 /* Send request to all neighbor. */
269 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
270 if (rp->info)
271 rip_request_neighbor (rp->p.u.prefix4);
272}
273
274/* Multicast packet receive socket. */
pauldc63bfd2005-10-25 23:31:05 +0000275static int
paul718e3742002-12-13 20:15:29 +0000276rip_multicast_join (struct interface *ifp, int sock)
277{
hasso52dc7ee2004-09-23 19:18:23 +0000278 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000279 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000280
paul2e3b2e42002-12-13 21:03:13 +0000281 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000282 {
283 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000284 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000285
paul1eb8ef22005-04-07 07:30:20 +0000286 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000287 {
288 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000289 struct in_addr group;
290
paul1eb8ef22005-04-07 07:30:20 +0000291 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000292
293 if (p->family != AF_INET)
294 continue;
295
296 group.s_addr = htonl (INADDR_RIP_GROUP);
297 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
298 return -1;
299 else
300 return 0;
301 }
302 }
303 return 0;
304}
305
306/* Leave from multicast group. */
pauldc63bfd2005-10-25 23:31:05 +0000307static void
paul718e3742002-12-13 20:15:29 +0000308rip_multicast_leave (struct interface *ifp, int sock)
309{
hasso52dc7ee2004-09-23 19:18:23 +0000310 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000311 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000312
313 if (if_is_up (ifp) && if_is_multicast (ifp))
314 {
315 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000316 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000317
paul1eb8ef22005-04-07 07:30:20 +0000318 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000319 {
320 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000321 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000322
paul718e3742002-12-13 20:15:29 +0000323 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000324
paul718e3742002-12-13 20:15:29 +0000325 if (p->family != AF_INET)
326 continue;
327
328 group.s_addr = htonl (INADDR_RIP_GROUP);
329 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
330 return;
331 }
332 }
333}
334
335/* Is there and address on interface that I could use ? */
pauldc63bfd2005-10-25 23:31:05 +0000336static int
paul718e3742002-12-13 20:15:29 +0000337rip_if_ipv4_address_check (struct interface *ifp)
338{
339 struct listnode *nn;
340 struct connected *connected;
341 int count = 0;
342
paul1eb8ef22005-04-07 07:30:20 +0000343 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
344 {
345 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000346
paul1eb8ef22005-04-07 07:30:20 +0000347 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000348
paul1eb8ef22005-04-07 07:30:20 +0000349 if (p->family == AF_INET)
350 count++;
351 }
paul718e3742002-12-13 20:15:29 +0000352
353 return count;
354}
paul31a476c2003-09-29 19:54:53 +0000355
356
357
358
359/* Does this address belongs to me ? */
360int
361if_check_address (struct in_addr addr)
362{
hasso52dc7ee2004-09-23 19:18:23 +0000363 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000364 struct interface *ifp;
365
366 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000367 {
hasso52dc7ee2004-09-23 19:18:23 +0000368 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000369 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000370
paul1eb8ef22005-04-07 07:30:20 +0000371 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000372 {
paul31a476c2003-09-29 19:54:53 +0000373 struct prefix_ipv4 *p;
374
paul31a476c2003-09-29 19:54:53 +0000375 p = (struct prefix_ipv4 *) connected->address;
376
377 if (p->family != AF_INET)
378 continue;
379
380 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
381 return 1;
382 }
383 }
384 return 0;
385}
386
paul718e3742002-12-13 20:15:29 +0000387/* Inteface link down message processing. */
388int
389rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
390{
391 struct interface *ifp;
392 struct stream *s;
393
394 s = zclient->ibuf;
395
396 /* zebra_interface_state_read() updates interface structure in
397 iflist. */
398 ifp = zebra_interface_state_read(s);
399
400 if (ifp == NULL)
401 return 0;
402
403 rip_if_down(ifp);
404
405 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000406 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000407 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
408
409 return 0;
410}
411
412/* Inteface link up message processing */
413int
414rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
415{
416 struct interface *ifp;
417
418 /* zebra_interface_state_read () updates interface structure in
419 iflist. */
420 ifp = zebra_interface_state_read (zclient->ibuf);
421
422 if (ifp == NULL)
423 return 0;
424
425 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000426 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000427 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
428
429 /* Check if this interface is RIP enabled or not.*/
430 rip_enable_apply (ifp);
431
432 /* Check for a passive interface */
433 rip_passive_interface_apply (ifp);
434
435 /* Apply distribute list to the all interface. */
436 rip_distribute_update_interface (ifp);
437
438 return 0;
439}
440
441/* Inteface addition message from zebra. */
442int
443rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
444{
445 struct interface *ifp;
446
447 ifp = zebra_interface_add_read (zclient->ibuf);
448
449 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000450 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000451 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
452
453 /* Check if this interface is RIP enabled or not.*/
454 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000455
456 /* Check for a passive interface */
457 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000458
459 /* Apply distribute list to the all interface. */
460 rip_distribute_update_interface (ifp);
461
462 /* rip_request_neighbor_all (); */
463
hasso16705132003-05-25 14:49:19 +0000464 /* Check interface routemap. */
465 rip_if_rmap_update_interface (ifp);
466
paul718e3742002-12-13 20:15:29 +0000467 return 0;
468}
469
470int
471rip_interface_delete (int command, struct zclient *zclient,
472 zebra_size_t length)
473{
474 struct interface *ifp;
475 struct stream *s;
476
477
478 s = zclient->ibuf;
479 /* zebra_interface_state_read() updates interface structure in iflist */
480 ifp = zebra_interface_state_read(s);
481
482 if (ifp == NULL)
483 return 0;
484
485 if (if_is_up (ifp)) {
486 rip_if_down(ifp);
487 }
488
489 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
490 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
491
492 /* To support pseudo interface do not free interface structure. */
493 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000494 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000495
496 return 0;
497}
498
499void
pauldc63bfd2005-10-25 23:31:05 +0000500rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000501{
hasso52dc7ee2004-09-23 19:18:23 +0000502 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000503 struct interface *ifp;
504 struct rip_interface *ri;
505
paul1eb8ef22005-04-07 07:30:20 +0000506 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000507 {
paul718e3742002-12-13 20:15:29 +0000508 ri = ifp->info;
509
510 ri->enable_network = 0;
511 ri->enable_interface = 0;
512 ri->running = 0;
513
514 if (ri->t_wakeup)
515 {
516 thread_cancel (ri->t_wakeup);
517 ri->t_wakeup = NULL;
518 }
519 }
520}
521
522void
pauldc63bfd2005-10-25 23:31:05 +0000523rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000524{
hasso52dc7ee2004-09-23 19:18:23 +0000525 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000526 struct interface *ifp;
527 struct rip_interface *ri;
528
paul1eb8ef22005-04-07 07:30:20 +0000529 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000530 {
paul718e3742002-12-13 20:15:29 +0000531 ri = ifp->info;
532
533 ri->enable_network = 0;
534 ri->enable_interface = 0;
535 ri->running = 0;
536
537 ri->ri_send = RI_RIP_UNSPEC;
538 ri->ri_receive = RI_RIP_UNSPEC;
539
paul7755a8c2005-06-02 08:20:53 +0000540 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000541
542 if (ri->auth_str)
543 {
544 free (ri->auth_str);
545 ri->auth_str = NULL;
546 }
547 if (ri->key_chain)
548 {
549 free (ri->key_chain);
550 ri->key_chain = NULL;
551 }
552
hasso16705132003-05-25 14:49:19 +0000553 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
554 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000555
556 ri->list[RIP_FILTER_IN] = NULL;
557 ri->list[RIP_FILTER_OUT] = NULL;
558
559 ri->prefix[RIP_FILTER_IN] = NULL;
560 ri->prefix[RIP_FILTER_OUT] = NULL;
561
562 if (ri->t_wakeup)
563 {
564 thread_cancel (ri->t_wakeup);
565 ri->t_wakeup = NULL;
566 }
567
568 ri->recv_badpackets = 0;
569 ri->recv_badroutes = 0;
570 ri->sent_updates = 0;
571
572 ri->passive = 0;
573 }
574}
575
576int
577rip_if_down(struct interface *ifp)
578{
579 struct route_node *rp;
580 struct rip_info *rinfo;
581 struct rip_interface *ri = NULL;
582 if (rip)
583 {
584 for (rp = route_top (rip->table); rp; rp = route_next (rp))
585 if ((rinfo = rp->info) != NULL)
586 {
587 /* Routes got through this interface. */
588 if (rinfo->ifindex == ifp->ifindex &&
589 rinfo->type == ZEBRA_ROUTE_RIP &&
590 rinfo->sub_type == RIP_ROUTE_RTE)
591 {
592 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
593 &rinfo->nexthop,
594 rinfo->ifindex);
595
596 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
597 (struct prefix_ipv4 *)&rp->p,
598 rinfo->ifindex);
599 }
600 else
601 {
602 /* All redistributed routes but static and system */
603 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000604 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000605 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
606 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
607 (struct prefix_ipv4 *)&rp->p,
608 rinfo->ifindex);
609 }
610 }
611 }
612
613 ri = ifp->info;
614
615 if (ri->running)
616 {
617 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000618 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000619
620 /* Leave from multicast group. */
621 rip_multicast_leave (ifp, rip->sock);
622
623 ri->running = 0;
624 }
625
626 return 0;
627}
628
629/* Needed for stop RIP process. */
630void
631rip_if_down_all ()
632{
633 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000634 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000635
paul1eb8ef22005-04-07 07:30:20 +0000636 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
637 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000638}
639
hasso16705132003-05-25 14:49:19 +0000640static void
pauldc63bfd2005-10-25 23:31:05 +0000641rip_apply_address_add (struct connected *ifc)
642{
hasso16705132003-05-25 14:49:19 +0000643 struct prefix_ipv4 address;
644 struct prefix *p;
645
646 if (!rip)
647 return;
648
649 if (! if_is_up(ifc->ifp))
650 return;
651
652 p = ifc->address;
653
654 memset (&address, 0, sizeof (address));
655 address.family = p->family;
656 address.prefix = p->u.prefix4;
657 address.prefixlen = p->prefixlen;
658 apply_mask_ipv4(&address);
659
660 /* Check if this interface is RIP enabled or not
661 or Check if this address's prefix is RIP enabled */
662 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
663 (rip_enable_network_lookup2(ifc) >= 0))
664 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000665 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000666
667}
668
paul718e3742002-12-13 20:15:29 +0000669int
670rip_interface_address_add (int command, struct zclient *zclient,
671 zebra_size_t length)
672{
673 struct connected *ifc;
674 struct prefix *p;
675
paul0a589352004-05-08 11:48:26 +0000676 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
677 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000678
679 if (ifc == NULL)
680 return 0;
681
682 p = ifc->address;
683
684 if (p->family == AF_INET)
685 {
686 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000687 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000688 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000689
paul878ef2e2003-09-23 23:41:50 +0000690 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000691 /* Check if this prefix needs to be redistributed */
692 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000693
694#ifdef HAVE_SNMP
695 rip_ifaddr_add (ifc->ifp, ifc);
696#endif /* HAVE_SNMP */
697 }
698
699 return 0;
700}
701
hasso16705132003-05-25 14:49:19 +0000702static void
703rip_apply_address_del (struct connected *ifc) {
704 struct prefix_ipv4 address;
705 struct prefix *p;
706
707 if (!rip)
708 return;
709
710 if (! if_is_up(ifc->ifp))
711 return;
712
713 p = ifc->address;
714
715 memset (&address, 0, sizeof (address));
716 address.family = p->family;
717 address.prefix = p->u.prefix4;
718 address.prefixlen = p->prefixlen;
719 apply_mask_ipv4(&address);
720
721 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
722 &address, ifc->ifp->ifindex);
723}
724
paul718e3742002-12-13 20:15:29 +0000725int
726rip_interface_address_delete (int command, struct zclient *zclient,
727 zebra_size_t length)
728{
729 struct connected *ifc;
730 struct prefix *p;
731
paul0a589352004-05-08 11:48:26 +0000732 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
733 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000734
735 if (ifc)
736 {
737 p = ifc->address;
738 if (p->family == AF_INET)
739 {
740 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000741 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000742 inet_ntoa (p->u.prefix4), p->prefixlen);
743
744#ifdef HAVE_SNMP
745 rip_ifaddr_delete (ifc->ifp, ifc);
746#endif /* HAVE_SNMP */
747
hasso16705132003-05-25 14:49:19 +0000748 /* Chech wether this prefix needs to be removed */
749 rip_apply_address_del(ifc);
750
paul718e3742002-12-13 20:15:29 +0000751 }
752
753 connected_free (ifc);
754
755 }
756
757 return 0;
758}
759
760/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000761/* Check wether the interface has at least a connected prefix that
762 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000763static int
hasso16705132003-05-25 14:49:19 +0000764rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000765{
paul1eb8ef22005-04-07 07:30:20 +0000766 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000767 struct connected *connected;
768 struct prefix_ipv4 address;
769
paul1eb8ef22005-04-07 07:30:20 +0000770 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
771 {
772 struct prefix *p;
773 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000774
paul1eb8ef22005-04-07 07:30:20 +0000775 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000776
paul1eb8ef22005-04-07 07:30:20 +0000777 if (p->family == AF_INET)
778 {
779 address.family = AF_INET;
780 address.prefix = p->u.prefix4;
781 address.prefixlen = IPV4_MAX_BITLEN;
782
783 node = route_node_match (rip_enable_network,
784 (struct prefix *)&address);
785 if (node)
786 {
787 route_unlock_node (node);
788 return 1;
789 }
790 }
791 }
paul718e3742002-12-13 20:15:29 +0000792 return -1;
793}
794
hasso16705132003-05-25 14:49:19 +0000795/* Check wether connected is within the ripng_enable_network table. */
796int
797rip_enable_network_lookup2 (struct connected *connected)
798{
799 struct prefix_ipv4 address;
800 struct prefix *p;
801
802 p = connected->address;
803
804 if (p->family == AF_INET) {
805 struct route_node *node;
806
807 address.family = p->family;
808 address.prefix = p->u.prefix4;
809 address.prefixlen = IPV4_MAX_BITLEN;
810
811 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
812 node = route_node_match (rip_enable_network,
813 (struct prefix *)&address);
814
815 if (node) {
816 route_unlock_node (node);
817 return 1;
818 }
819 }
820
821 return -1;
822}
paul718e3742002-12-13 20:15:29 +0000823/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000824static int
paul718e3742002-12-13 20:15:29 +0000825rip_enable_network_add (struct prefix *p)
826{
827 struct route_node *node;
828
829 node = route_node_get (rip_enable_network, p);
830
831 if (node->info)
832 {
833 route_unlock_node (node);
834 return -1;
835 }
836 else
hasso8a676be2004-10-08 06:36:38 +0000837 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000838
hasso16705132003-05-25 14:49:19 +0000839 /* XXX: One should find a better solution than a generic one */
840 rip_enable_apply_all();
841
paul718e3742002-12-13 20:15:29 +0000842 return 1;
843}
844
845/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000846static int
paul718e3742002-12-13 20:15:29 +0000847rip_enable_network_delete (struct prefix *p)
848{
849 struct route_node *node;
850
851 node = route_node_lookup (rip_enable_network, p);
852 if (node)
853 {
854 node->info = NULL;
855
856 /* Unlock info lock. */
857 route_unlock_node (node);
858
859 /* Unlock lookup lock. */
860 route_unlock_node (node);
861
hasso16705132003-05-25 14:49:19 +0000862 /* XXX: One should find a better solution than a generic one */
863 rip_enable_apply_all ();
864
paul718e3742002-12-13 20:15:29 +0000865 return 1;
866 }
867 return -1;
868}
869
870/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000871static int
hasso98b718a2004-10-11 12:57:57 +0000872rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000873{
hasso8a676be2004-10-08 06:36:38 +0000874 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000875 char *str;
876
paul55468c82005-03-14 20:19:01 +0000877 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000878 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
879 if (strcmp (str, ifname) == 0)
880 return i;
881 return -1;
882}
883
884/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000885static int
hasso98b718a2004-10-11 12:57:57 +0000886rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000887{
888 int ret;
889
890 ret = rip_enable_if_lookup (ifname);
891 if (ret >= 0)
892 return -1;
893
894 vector_set (rip_enable_interface, strdup (ifname));
895
hasso16705132003-05-25 14:49:19 +0000896 rip_enable_apply_all(); /* TODOVJ */
897
paul718e3742002-12-13 20:15:29 +0000898 return 1;
899}
900
901/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000902static int
hasso98b718a2004-10-11 12:57:57 +0000903rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000904{
905 int index;
906 char *str;
907
908 index = rip_enable_if_lookup (ifname);
909 if (index < 0)
910 return -1;
911
912 str = vector_slot (rip_enable_interface, index);
913 free (str);
914 vector_unset (rip_enable_interface, index);
915
hasso16705132003-05-25 14:49:19 +0000916 rip_enable_apply_all(); /* TODOVJ */
917
paul718e3742002-12-13 20:15:29 +0000918 return 1;
919}
920
921/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000922static int
paul718e3742002-12-13 20:15:29 +0000923rip_interface_wakeup (struct thread *t)
924{
925 struct interface *ifp;
926 struct rip_interface *ri;
927
928 /* Get interface. */
929 ifp = THREAD_ARG (t);
930
931 ri = ifp->info;
932 ri->t_wakeup = NULL;
933
934 /* Join to multicast group. */
935 if (rip_multicast_join (ifp, rip->sock) < 0)
936 {
937 zlog_err ("multicast join failed, interface %s not running", ifp->name);
938 return 0;
939 }
940
941 /* Set running flag. */
942 ri->running = 1;
943
944 /* Send RIP request to the interface. */
945 rip_request_interface (ifp);
946
947 return 0;
948}
949
950int rip_redistribute_check (int);
951
pauldc63bfd2005-10-25 23:31:05 +0000952static void
paul718e3742002-12-13 20:15:29 +0000953rip_connect_set (struct interface *ifp, int set)
954{
paul1eb8ef22005-04-07 07:30:20 +0000955 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000956 struct connected *connected;
957 struct prefix_ipv4 address;
958
paul1eb8ef22005-04-07 07:30:20 +0000959 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
960 {
961 struct prefix *p;
962 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000963
paul1eb8ef22005-04-07 07:30:20 +0000964 if (p->family != AF_INET)
965 continue;
paul718e3742002-12-13 20:15:29 +0000966
paul1eb8ef22005-04-07 07:30:20 +0000967 address.family = AF_INET;
968 address.prefix = p->u.prefix4;
969 address.prefixlen = p->prefixlen;
970 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000971
paul1eb8ef22005-04-07 07:30:20 +0000972 if (set) {
973 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
974 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
975 (rip_enable_network_lookup2(connected) >= 0))
976 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000977 &address, connected->ifp->ifindex,
978 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000979 } else
980 {
981 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
982 &address, connected->ifp->ifindex);
983 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
984 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000985 &address, connected->ifp->ifindex,
986 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000987 }
988 }
paul718e3742002-12-13 20:15:29 +0000989}
990
991/* Update interface status. */
992void
993rip_enable_apply (struct interface *ifp)
994{
995 int ret;
996 struct rip_interface *ri = NULL;
997
998 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +0000999 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001000 return;
1001
1002 ri = ifp->info;
1003
1004 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001005 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001006
1007 /* If the interface is matched. */
1008 if (ret > 0)
1009 ri->enable_network = 1;
1010 else
1011 ri->enable_network = 0;
1012
1013 /* Check interface name configuration. */
1014 ret = rip_enable_if_lookup (ifp->name);
1015 if (ret >= 0)
1016 ri->enable_interface = 1;
1017 else
1018 ri->enable_interface = 0;
1019
1020 /* any interface MUST have an IPv4 address */
1021 if ( ! rip_if_ipv4_address_check (ifp) )
1022 {
1023 ri->enable_network = 0;
1024 ri->enable_interface = 0;
1025 }
1026
1027 /* Update running status of the interface. */
1028 if (ri->enable_network || ri->enable_interface)
1029 {
paul718e3742002-12-13 20:15:29 +00001030 {
1031 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001032 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001033
1034 /* Add interface wake up thread. */
1035 if (! ri->t_wakeup)
1036 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1037 ifp, 1);
1038 rip_connect_set (ifp, 1);
1039 }
1040 }
1041 else
1042 {
1043 if (ri->running)
1044 {
hasso16705132003-05-25 14:49:19 +00001045 /* Might as well clean up the route table as well
1046 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1047 **/
paul718e3742002-12-13 20:15:29 +00001048 rip_if_down(ifp);
1049
paul718e3742002-12-13 20:15:29 +00001050 rip_connect_set (ifp, 0);
1051 }
1052 }
1053}
1054
1055/* Apply network configuration to all interface. */
1056void
1057rip_enable_apply_all ()
1058{
1059 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001060 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001061
1062 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001063 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1064 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001065}
1066
1067int
1068rip_neighbor_lookup (struct sockaddr_in *from)
1069{
1070 struct prefix_ipv4 p;
1071 struct route_node *node;
1072
1073 memset (&p, 0, sizeof (struct prefix_ipv4));
1074 p.family = AF_INET;
1075 p.prefix = from->sin_addr;
1076 p.prefixlen = IPV4_MAX_BITLEN;
1077
1078 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1079 if (node)
1080 {
1081 route_unlock_node (node);
1082 return 1;
1083 }
1084 return 0;
1085}
1086
1087/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001088static int
paul718e3742002-12-13 20:15:29 +00001089rip_neighbor_add (struct prefix_ipv4 *p)
1090{
1091 struct route_node *node;
1092
1093 node = route_node_get (rip->neighbor, (struct prefix *) p);
1094
1095 if (node->info)
1096 return -1;
1097
1098 node->info = rip->neighbor;
1099
1100 return 0;
1101}
1102
1103/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001104static int
paul718e3742002-12-13 20:15:29 +00001105rip_neighbor_delete (struct prefix_ipv4 *p)
1106{
1107 struct route_node *node;
1108
1109 /* Lock for look up. */
1110 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1111 if (! node)
1112 return -1;
1113
1114 node->info = NULL;
1115
1116 /* Unlock lookup lock. */
1117 route_unlock_node (node);
1118
1119 /* Unlock real neighbor information lock. */
1120 route_unlock_node (node);
1121
1122 return 0;
1123}
1124
1125/* Clear all network and neighbor configuration. */
1126void
1127rip_clean_network ()
1128{
hasso8a676be2004-10-08 06:36:38 +00001129 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001130 char *str;
1131 struct route_node *rn;
1132
1133 /* rip_enable_network. */
1134 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1135 if (rn->info)
1136 {
1137 rn->info = NULL;
1138 route_unlock_node (rn);
1139 }
1140
1141 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001142 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001143 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1144 {
1145 free (str);
1146 vector_slot (rip_enable_interface, i) = NULL;
1147 }
1148}
1149
1150/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001151static int
hasso98b718a2004-10-11 12:57:57 +00001152rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001153{
hasso8a676be2004-10-08 06:36:38 +00001154 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001155 char *str;
1156
paul55468c82005-03-14 20:19:01 +00001157 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001158 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001159 if (strcmp (str, ifname) == 0)
1160 return i;
1161 return -1;
1162}
1163
1164void
1165rip_passive_interface_apply (struct interface *ifp)
1166{
paul718e3742002-12-13 20:15:29 +00001167 struct rip_interface *ri;
1168
1169 ri = ifp->info;
1170
paul4aaff3f2003-06-07 01:04:45 +00001171 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1172 passive_default : !passive_default);
1173
1174 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001175 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001176}
1177
pauldc63bfd2005-10-25 23:31:05 +00001178static void
1179rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001180{
1181 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001182 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001183
paul1eb8ef22005-04-07 07:30:20 +00001184 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1185 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001186}
1187
1188/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001189static int
hasso98b718a2004-10-11 12:57:57 +00001190rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001191{
paul4aaff3f2003-06-07 01:04:45 +00001192 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001193 return CMD_WARNING;
1194
paul4aaff3f2003-06-07 01:04:45 +00001195 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001196
1197 rip_passive_interface_apply_all ();
1198
1199 return CMD_SUCCESS;
1200}
1201
pauldc63bfd2005-10-25 23:31:05 +00001202static int
hasso98b718a2004-10-11 12:57:57 +00001203rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001204{
1205 int i;
1206 char *str;
1207
paul4aaff3f2003-06-07 01:04:45 +00001208 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001209 if (i < 0)
1210 return CMD_WARNING;
1211
paul4aaff3f2003-06-07 01:04:45 +00001212 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001213 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001214 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001215
1216 rip_passive_interface_apply_all ();
1217
1218 return CMD_SUCCESS;
1219}
1220
1221/* Free all configured RIP passive-interface settings. */
1222void
pauldc63bfd2005-10-25 23:31:05 +00001223rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001224{
hasso8a676be2004-10-08 06:36:38 +00001225 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001226 char *str;
1227
paul55468c82005-03-14 20:19:01 +00001228 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001229 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001230 {
1231 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001232 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001233 }
1234 rip_passive_interface_apply_all ();
1235}
1236
1237/* RIP enable network or interface configuration. */
1238DEFUN (rip_network,
1239 rip_network_cmd,
1240 "network (A.B.C.D/M|WORD)",
1241 "Enable routing on an IP network\n"
1242 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1243 "Interface name\n")
1244{
1245 int ret;
1246 struct prefix_ipv4 p;
1247
1248 ret = str2prefix_ipv4 (argv[0], &p);
1249
1250 if (ret)
1251 ret = rip_enable_network_add ((struct prefix *) &p);
1252 else
1253 ret = rip_enable_if_add (argv[0]);
1254
1255 if (ret < 0)
1256 {
1257 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1258 VTY_NEWLINE);
1259 return CMD_WARNING;
1260 }
1261
paul718e3742002-12-13 20:15:29 +00001262 return CMD_SUCCESS;
1263}
1264
1265/* RIP enable network or interface configuration. */
1266DEFUN (no_rip_network,
1267 no_rip_network_cmd,
1268 "no network (A.B.C.D/M|WORD)",
1269 NO_STR
1270 "Enable routing on an IP network\n"
1271 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1272 "Interface name\n")
1273{
1274 int ret;
1275 struct prefix_ipv4 p;
1276
1277 ret = str2prefix_ipv4 (argv[0], &p);
1278
1279 if (ret)
1280 ret = rip_enable_network_delete ((struct prefix *) &p);
1281 else
1282 ret = rip_enable_if_delete (argv[0]);
1283
1284 if (ret < 0)
1285 {
1286 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1287 VTY_NEWLINE);
1288 return CMD_WARNING;
1289 }
1290
paul718e3742002-12-13 20:15:29 +00001291 return CMD_SUCCESS;
1292}
1293
1294/* RIP neighbor configuration set. */
1295DEFUN (rip_neighbor,
1296 rip_neighbor_cmd,
1297 "neighbor A.B.C.D",
1298 "Specify a neighbor router\n"
1299 "Neighbor address\n")
1300{
1301 int ret;
1302 struct prefix_ipv4 p;
1303
1304 ret = str2prefix_ipv4 (argv[0], &p);
1305
1306 if (ret <= 0)
1307 {
1308 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1309 return CMD_WARNING;
1310 }
1311
1312 rip_neighbor_add (&p);
1313
1314 return CMD_SUCCESS;
1315}
1316
1317/* RIP neighbor configuration unset. */
1318DEFUN (no_rip_neighbor,
1319 no_rip_neighbor_cmd,
1320 "no neighbor A.B.C.D",
1321 NO_STR
1322 "Specify a neighbor router\n"
1323 "Neighbor address\n")
1324{
1325 int ret;
1326 struct prefix_ipv4 p;
1327
1328 ret = str2prefix_ipv4 (argv[0], &p);
1329
1330 if (ret <= 0)
1331 {
1332 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1333 return CMD_WARNING;
1334 }
1335
1336 rip_neighbor_delete (&p);
1337
1338 return CMD_SUCCESS;
1339}
1340
1341DEFUN (ip_rip_receive_version,
1342 ip_rip_receive_version_cmd,
1343 "ip rip receive version (1|2)",
1344 IP_STR
1345 "Routing Information Protocol\n"
1346 "Advertisement reception\n"
1347 "Version control\n"
1348 "RIP version 1\n"
1349 "RIP version 2\n")
1350{
1351 struct interface *ifp;
1352 struct rip_interface *ri;
1353
1354 ifp = (struct interface *)vty->index;
1355 ri = ifp->info;
1356
1357 /* Version 1. */
1358 if (atoi (argv[0]) == 1)
1359 {
1360 ri->ri_receive = RI_RIP_VERSION_1;
1361 return CMD_SUCCESS;
1362 }
1363 if (atoi (argv[0]) == 2)
1364 {
1365 ri->ri_receive = RI_RIP_VERSION_2;
1366 return CMD_SUCCESS;
1367 }
1368 return CMD_WARNING;
1369}
1370
1371DEFUN (ip_rip_receive_version_1,
1372 ip_rip_receive_version_1_cmd,
1373 "ip rip receive version 1 2",
1374 IP_STR
1375 "Routing Information Protocol\n"
1376 "Advertisement reception\n"
1377 "Version control\n"
1378 "RIP version 1\n"
1379 "RIP version 2\n")
1380{
1381 struct interface *ifp;
1382 struct rip_interface *ri;
1383
1384 ifp = (struct interface *)vty->index;
1385 ri = ifp->info;
1386
1387 /* Version 1 and 2. */
1388 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1389 return CMD_SUCCESS;
1390}
1391
1392DEFUN (ip_rip_receive_version_2,
1393 ip_rip_receive_version_2_cmd,
1394 "ip rip receive version 2 1",
1395 IP_STR
1396 "Routing Information Protocol\n"
1397 "Advertisement reception\n"
1398 "Version control\n"
1399 "RIP version 2\n"
1400 "RIP version 1\n")
1401{
1402 struct interface *ifp;
1403 struct rip_interface *ri;
1404
1405 ifp = (struct interface *)vty->index;
1406 ri = ifp->info;
1407
1408 /* Version 1 and 2. */
1409 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1410 return CMD_SUCCESS;
1411}
1412
1413DEFUN (no_ip_rip_receive_version,
1414 no_ip_rip_receive_version_cmd,
1415 "no ip rip receive version",
1416 NO_STR
1417 IP_STR
1418 "Routing Information Protocol\n"
1419 "Advertisement reception\n"
1420 "Version control\n")
1421{
1422 struct interface *ifp;
1423 struct rip_interface *ri;
1424
1425 ifp = (struct interface *)vty->index;
1426 ri = ifp->info;
1427
1428 ri->ri_receive = RI_RIP_UNSPEC;
1429 return CMD_SUCCESS;
1430}
1431
1432ALIAS (no_ip_rip_receive_version,
1433 no_ip_rip_receive_version_num_cmd,
1434 "no ip rip receive version (1|2)",
1435 NO_STR
1436 IP_STR
1437 "Routing Information Protocol\n"
1438 "Advertisement reception\n"
1439 "Version control\n"
1440 "Version 1\n"
1441 "Version 2\n")
1442
1443DEFUN (ip_rip_send_version,
1444 ip_rip_send_version_cmd,
1445 "ip rip send version (1|2)",
1446 IP_STR
1447 "Routing Information Protocol\n"
1448 "Advertisement transmission\n"
1449 "Version control\n"
1450 "RIP version 1\n"
1451 "RIP version 2\n")
1452{
1453 struct interface *ifp;
1454 struct rip_interface *ri;
1455
1456 ifp = (struct interface *)vty->index;
1457 ri = ifp->info;
1458
1459 /* Version 1. */
1460 if (atoi (argv[0]) == 1)
1461 {
1462 ri->ri_send = RI_RIP_VERSION_1;
1463 return CMD_SUCCESS;
1464 }
1465 if (atoi (argv[0]) == 2)
1466 {
1467 ri->ri_send = RI_RIP_VERSION_2;
1468 return CMD_SUCCESS;
1469 }
1470 return CMD_WARNING;
1471}
1472
1473DEFUN (ip_rip_send_version_1,
1474 ip_rip_send_version_1_cmd,
1475 "ip rip send version 1 2",
1476 IP_STR
1477 "Routing Information Protocol\n"
1478 "Advertisement transmission\n"
1479 "Version control\n"
1480 "RIP version 1\n"
1481 "RIP version 2\n")
1482{
1483 struct interface *ifp;
1484 struct rip_interface *ri;
1485
1486 ifp = (struct interface *)vty->index;
1487 ri = ifp->info;
1488
1489 /* Version 1 and 2. */
1490 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1491 return CMD_SUCCESS;
1492}
1493
1494DEFUN (ip_rip_send_version_2,
1495 ip_rip_send_version_2_cmd,
1496 "ip rip send version 2 1",
1497 IP_STR
1498 "Routing Information Protocol\n"
1499 "Advertisement transmission\n"
1500 "Version control\n"
1501 "RIP version 2\n"
1502 "RIP version 1\n")
1503{
1504 struct interface *ifp;
1505 struct rip_interface *ri;
1506
1507 ifp = (struct interface *)vty->index;
1508 ri = ifp->info;
1509
1510 /* Version 1 and 2. */
1511 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1512 return CMD_SUCCESS;
1513}
1514
1515DEFUN (no_ip_rip_send_version,
1516 no_ip_rip_send_version_cmd,
1517 "no ip rip send version",
1518 NO_STR
1519 IP_STR
1520 "Routing Information Protocol\n"
1521 "Advertisement transmission\n"
1522 "Version control\n")
1523{
1524 struct interface *ifp;
1525 struct rip_interface *ri;
1526
1527 ifp = (struct interface *)vty->index;
1528 ri = ifp->info;
1529
1530 ri->ri_send = RI_RIP_UNSPEC;
1531 return CMD_SUCCESS;
1532}
1533
1534ALIAS (no_ip_rip_send_version,
1535 no_ip_rip_send_version_num_cmd,
1536 "no ip rip send version (1|2)",
1537 NO_STR
1538 IP_STR
1539 "Routing Information Protocol\n"
1540 "Advertisement transmission\n"
1541 "Version control\n"
1542 "Version 1\n"
1543 "Version 2\n")
1544
1545DEFUN (ip_rip_authentication_mode,
1546 ip_rip_authentication_mode_cmd,
1547 "ip rip authentication mode (md5|text)",
1548 IP_STR
1549 "Routing Information Protocol\n"
1550 "Authentication control\n"
1551 "Authentication mode\n"
1552 "Keyed message digest\n"
1553 "Clear text authentication\n")
1554{
1555 struct interface *ifp;
1556 struct rip_interface *ri;
Paul Jakma15a2b082006-05-04 07:36:34 +00001557 int auth_type;
paul718e3742002-12-13 20:15:29 +00001558
1559 ifp = (struct interface *)vty->index;
1560 ri = ifp->info;
1561
paulca5e5162004-06-06 22:06:33 +00001562 if ( (argc < 1) || (argc > 2) )
1563 {
1564 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1565 return CMD_WARNING;
1566 }
1567
paul718e3742002-12-13 20:15:29 +00001568 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001569 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001570 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001571 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001572 else
1573 {
1574 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1575 return CMD_WARNING;
1576 }
1577
paulca5e5162004-06-06 22:06:33 +00001578 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001579 {
1580 ri->auth_type = auth_type;
1581 return CMD_SUCCESS;
1582 }
paulca5e5162004-06-06 22:06:33 +00001583
Paul Jakma15a2b082006-05-04 07:36:34 +00001584 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001585 {
1586 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1587 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001588 }
paulca5e5162004-06-06 22:06:33 +00001589
1590 if (strncmp ("r", argv[1], 1) == 0)
1591 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1592 else if (strncmp ("o", argv[1], 1) == 0)
1593 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1594 else
1595 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001596
1597 ri->auth_type = auth_type;
1598
paul718e3742002-12-13 20:15:29 +00001599 return CMD_SUCCESS;
1600}
1601
paulca5e5162004-06-06 22:06:33 +00001602ALIAS (ip_rip_authentication_mode,
1603 ip_rip_authentication_mode_authlen_cmd,
1604 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
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 "MD5 authentication data length\n"
1612 "RFC compatible\n"
1613 "Old ripd compatible\n")
1614
paul718e3742002-12-13 20:15:29 +00001615DEFUN (no_ip_rip_authentication_mode,
1616 no_ip_rip_authentication_mode_cmd,
1617 "no ip rip authentication mode",
1618 NO_STR
1619 IP_STR
1620 "Routing Information Protocol\n"
1621 "Authentication control\n"
1622 "Authentication mode\n")
1623{
1624 struct interface *ifp;
1625 struct rip_interface *ri;
1626
1627 ifp = (struct interface *)vty->index;
1628 ri = ifp->info;
1629
paul7755a8c2005-06-02 08:20:53 +00001630 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001631 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001632
1633 return CMD_SUCCESS;
1634}
1635
1636ALIAS (no_ip_rip_authentication_mode,
1637 no_ip_rip_authentication_mode_type_cmd,
1638 "no ip rip authentication mode (md5|text)",
1639 NO_STR
1640 IP_STR
1641 "Routing Information Protocol\n"
1642 "Authentication control\n"
1643 "Authentication mode\n"
1644 "Keyed message digest\n"
1645 "Clear text authentication\n")
1646
paulca5e5162004-06-06 22:06:33 +00001647ALIAS (no_ip_rip_authentication_mode,
1648 no_ip_rip_authentication_mode_type_authlen_cmd,
1649 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1650 NO_STR
1651 IP_STR
1652 "Routing Information Protocol\n"
1653 "Authentication control\n"
1654 "Authentication mode\n"
1655 "Keyed message digest\n"
1656 "Clear text authentication\n"
1657 "MD5 authentication data length\n"
1658 "RFC compatible\n"
1659 "Old ripd compatible\n")
1660
paul718e3742002-12-13 20:15:29 +00001661DEFUN (ip_rip_authentication_string,
1662 ip_rip_authentication_string_cmd,
1663 "ip rip authentication string LINE",
1664 IP_STR
1665 "Routing Information Protocol\n"
1666 "Authentication control\n"
1667 "Authentication string\n"
1668 "Authentication string\n")
1669{
1670 struct interface *ifp;
1671 struct rip_interface *ri;
1672
1673 ifp = (struct interface *)vty->index;
1674 ri = ifp->info;
1675
1676 if (strlen (argv[0]) > 16)
1677 {
1678 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1679 VTY_NEWLINE);
1680 return CMD_WARNING;
1681 }
1682
1683 if (ri->key_chain)
1684 {
1685 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1686 return CMD_WARNING;
1687 }
1688
1689 if (ri->auth_str)
1690 free (ri->auth_str);
1691
1692 ri->auth_str = strdup (argv[0]);
1693
1694 return CMD_SUCCESS;
1695}
1696
1697DEFUN (no_ip_rip_authentication_string,
1698 no_ip_rip_authentication_string_cmd,
1699 "no ip rip authentication string",
1700 NO_STR
1701 IP_STR
1702 "Routing Information Protocol\n"
1703 "Authentication control\n"
1704 "Authentication string\n")
1705{
1706 struct interface *ifp;
1707 struct rip_interface *ri;
1708
1709 ifp = (struct interface *)vty->index;
1710 ri = ifp->info;
1711
1712 if (ri->auth_str)
1713 free (ri->auth_str);
1714
1715 ri->auth_str = NULL;
1716
1717 return CMD_SUCCESS;
1718}
1719
1720ALIAS (no_ip_rip_authentication_string,
1721 no_ip_rip_authentication_string2_cmd,
1722 "no ip rip authentication string LINE",
1723 NO_STR
1724 IP_STR
1725 "Routing Information Protocol\n"
1726 "Authentication control\n"
1727 "Authentication string\n"
1728 "Authentication string\n")
1729
1730DEFUN (ip_rip_authentication_key_chain,
1731 ip_rip_authentication_key_chain_cmd,
1732 "ip rip authentication key-chain LINE",
1733 IP_STR
1734 "Routing Information Protocol\n"
1735 "Authentication control\n"
1736 "Authentication key-chain\n"
1737 "name of key-chain\n")
1738{
1739 struct interface *ifp;
1740 struct rip_interface *ri;
1741
1742 ifp = (struct interface *) vty->index;
1743 ri = ifp->info;
1744
1745 if (ri->auth_str)
1746 {
1747 vty_out (vty, "%% authentication string configuration exists%s",
1748 VTY_NEWLINE);
1749 return CMD_WARNING;
1750 }
1751
1752 if (ri->key_chain)
1753 free (ri->key_chain);
1754
1755 ri->key_chain = strdup (argv[0]);
1756
1757 return CMD_SUCCESS;
1758}
1759
1760DEFUN (no_ip_rip_authentication_key_chain,
1761 no_ip_rip_authentication_key_chain_cmd,
1762 "no ip rip authentication key-chain",
1763 NO_STR
1764 IP_STR
1765 "Routing Information Protocol\n"
1766 "Authentication control\n"
1767 "Authentication key-chain\n")
1768{
1769 struct interface *ifp;
1770 struct rip_interface *ri;
1771
1772 ifp = (struct interface *) vty->index;
1773 ri = ifp->info;
1774
1775 if (ri->key_chain)
1776 free (ri->key_chain);
1777
1778 ri->key_chain = NULL;
1779
1780 return CMD_SUCCESS;
1781}
1782
1783ALIAS (no_ip_rip_authentication_key_chain,
1784 no_ip_rip_authentication_key_chain2_cmd,
1785 "no ip rip authentication key-chain LINE",
1786 NO_STR
1787 IP_STR
1788 "Routing Information Protocol\n"
1789 "Authentication control\n"
1790 "Authentication key-chain\n"
1791 "name of key-chain\n")
1792
hasso16705132003-05-25 14:49:19 +00001793/* CHANGED: ip rip split-horizon
1794 Cisco and Zebra's command is
1795 ip split-horizon
1796 */
1797DEFUN (ip_rip_split_horizon,
1798 ip_rip_split_horizon_cmd,
1799 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001800 IP_STR
hasso16705132003-05-25 14:49:19 +00001801 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001802 "Perform split horizon\n")
1803{
1804 struct interface *ifp;
1805 struct rip_interface *ri;
1806
1807 ifp = vty->index;
1808 ri = ifp->info;
1809
hasso16705132003-05-25 14:49:19 +00001810 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001811 return CMD_SUCCESS;
1812}
1813
hasso16705132003-05-25 14:49:19 +00001814DEFUN (ip_rip_split_horizon_poisoned_reverse,
1815 ip_rip_split_horizon_poisoned_reverse_cmd,
1816 "ip rip split-horizon poisoned-reverse",
1817 IP_STR
1818 "Routing Information Protocol\n"
1819 "Perform split horizon\n"
1820 "With poisoned-reverse\n")
1821{
1822 struct interface *ifp;
1823 struct rip_interface *ri;
1824
1825 ifp = vty->index;
1826 ri = ifp->info;
1827
1828 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1829 return CMD_SUCCESS;
1830}
1831
1832/* CHANGED: no ip rip split-horizon
1833 Cisco and Zebra's command is
1834 no ip split-horizon
1835 */
1836DEFUN (no_ip_rip_split_horizon,
1837 no_ip_rip_split_horizon_cmd,
1838 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001839 NO_STR
1840 IP_STR
hasso16705132003-05-25 14:49:19 +00001841 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001842 "Perform split horizon\n")
1843{
1844 struct interface *ifp;
1845 struct rip_interface *ri;
1846
1847 ifp = vty->index;
1848 ri = ifp->info;
1849
hasso16705132003-05-25 14:49:19 +00001850 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001851 return CMD_SUCCESS;
1852}
1853
vincentfac3e842005-10-06 07:45:43 +00001854DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001855 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1856 "no ip rip split-horizon poisoned-reverse",
1857 NO_STR
1858 IP_STR
1859 "Routing Information Protocol\n"
1860 "Perform split horizon\n"
1861 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001862{
1863 struct interface *ifp;
1864 struct rip_interface *ri;
1865
1866 ifp = vty->index;
1867 ri = ifp->info;
1868
1869 switch( ri->split_horizon )
1870 {
1871 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1872 ri->split_horizon = RIP_SPLIT_HORIZON;
1873 default:
1874 break;
1875 }
1876
1877 return CMD_SUCCESS;
1878}
hasso16705132003-05-25 14:49:19 +00001879
paul718e3742002-12-13 20:15:29 +00001880DEFUN (rip_passive_interface,
1881 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001882 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001883 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001884 "Interface name\n"
1885 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001886{
hasso98b718a2004-10-11 12:57:57 +00001887 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001888
1889 if (!strcmp(ifname,"default")) {
1890 passive_default = 1;
1891 rip_passive_nondefault_clean();
1892 return CMD_SUCCESS;
1893 }
1894 if (passive_default)
1895 return rip_passive_nondefault_unset (vty, ifname);
1896 else
1897 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001898}
1899
1900DEFUN (no_rip_passive_interface,
1901 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001902 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001903 NO_STR
1904 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001905 "Interface name\n"
1906 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001907{
hasso98b718a2004-10-11 12:57:57 +00001908 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001909
1910 if (!strcmp(ifname,"default")) {
1911 passive_default = 0;
1912 rip_passive_nondefault_clean();
1913 return CMD_SUCCESS;
1914 }
1915 if (passive_default)
1916 return rip_passive_nondefault_set (vty, ifname);
1917 else
1918 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001919}
1920
1921/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001922static int
paul718e3742002-12-13 20:15:29 +00001923rip_interface_config_write (struct vty *vty)
1924{
hasso52dc7ee2004-09-23 19:18:23 +00001925 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001926 struct interface *ifp;
1927
paul1eb8ef22005-04-07 07:30:20 +00001928 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001929 {
1930 struct rip_interface *ri;
1931
paul718e3742002-12-13 20:15:29 +00001932 ri = ifp->info;
1933
hasso16705132003-05-25 14:49:19 +00001934 /* Do not display the interface if there is no
1935 * configuration about it.
1936 **/
1937 if ((!ifp->desc) &&
1938 (ri->split_horizon == ri->split_horizon_default) &&
1939 (ri->ri_send == RI_RIP_UNSPEC) &&
1940 (ri->ri_receive == RI_RIP_UNSPEC) &&
1941 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001942 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001943 (!ri->auth_str) &&
1944 (!ri->key_chain) )
1945 continue;
1946
paul718e3742002-12-13 20:15:29 +00001947 vty_out (vty, "interface %s%s", ifp->name,
1948 VTY_NEWLINE);
1949
1950 if (ifp->desc)
1951 vty_out (vty, " description %s%s", ifp->desc,
1952 VTY_NEWLINE);
1953
1954 /* Split horizon. */
1955 if (ri->split_horizon != ri->split_horizon_default)
1956 {
hasso16705132003-05-25 14:49:19 +00001957 switch (ri->split_horizon) {
1958 case RIP_SPLIT_HORIZON:
1959 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1960 break;
1961 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1962 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1963 VTY_NEWLINE);
1964 break;
1965 case RIP_NO_SPLIT_HORIZON:
1966 default:
1967 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1968 break;
1969 }
paul718e3742002-12-13 20:15:29 +00001970 }
1971
1972 /* RIP version setting. */
1973 if (ri->ri_send != RI_RIP_UNSPEC)
1974 vty_out (vty, " ip rip send version %s%s",
1975 lookup (ri_version_msg, ri->ri_send),
1976 VTY_NEWLINE);
1977
1978 if (ri->ri_receive != RI_RIP_UNSPEC)
1979 vty_out (vty, " ip rip receive version %s%s",
1980 lookup (ri_version_msg, ri->ri_receive),
1981 VTY_NEWLINE);
1982
1983 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001984 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1985 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001986
paul718e3742002-12-13 20:15:29 +00001987 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001988 {
1989 vty_out (vty, " ip rip authentication mode md5");
1990 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1991 vty_out (vty, " auth-length old-ripd");
1992 else
1993 vty_out (vty, " auth-length rfc");
1994 vty_out (vty, "%s", VTY_NEWLINE);
1995 }
paul718e3742002-12-13 20:15:29 +00001996
1997 if (ri->auth_str)
1998 vty_out (vty, " ip rip authentication string %s%s",
1999 ri->auth_str, VTY_NEWLINE);
2000
2001 if (ri->key_chain)
2002 vty_out (vty, " ip rip authentication key-chain %s%s",
2003 ri->key_chain, VTY_NEWLINE);
2004
2005 vty_out (vty, "!%s", VTY_NEWLINE);
2006 }
2007 return 0;
2008}
2009
2010int
2011config_write_rip_network (struct vty *vty, int config_mode)
2012{
hasso8a676be2004-10-08 06:36:38 +00002013 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002014 char *ifname;
2015 struct route_node *node;
2016
2017 /* Network type RIP enable interface statement. */
2018 for (node = route_top (rip_enable_network); node; node = route_next (node))
2019 if (node->info)
2020 vty_out (vty, "%s%s/%d%s",
2021 config_mode ? " network " : " ",
2022 inet_ntoa (node->p.u.prefix4),
2023 node->p.prefixlen,
2024 VTY_NEWLINE);
2025
2026 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002027 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002028 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2029 vty_out (vty, "%s%s%s",
2030 config_mode ? " network " : " ",
2031 ifname,
2032 VTY_NEWLINE);
2033
2034 /* RIP neighbors listing. */
2035 for (node = route_top (rip->neighbor); node; node = route_next (node))
2036 if (node->info)
2037 vty_out (vty, "%s%s%s",
2038 config_mode ? " neighbor " : " ",
2039 inet_ntoa (node->p.u.prefix4),
2040 VTY_NEWLINE);
2041
2042 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002043 if (config_mode) {
2044 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002045 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002046 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002047 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2048 vty_out (vty, " %spassive-interface %s%s",
2049 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2050 }
paul718e3742002-12-13 20:15:29 +00002051
2052 return 0;
2053}
2054
2055struct cmd_node interface_node =
2056{
2057 INTERFACE_NODE,
2058 "%s(config-if)# ",
2059 1,
2060};
2061
2062/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002063static int
paul718e3742002-12-13 20:15:29 +00002064rip_interface_new_hook (struct interface *ifp)
2065{
2066 ifp->info = rip_interface_new ();
2067 return 0;
2068}
2069
2070/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002071static int
paul718e3742002-12-13 20:15:29 +00002072rip_interface_delete_hook (struct interface *ifp)
2073{
2074 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002075 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002076 return 0;
2077}
2078
2079/* Allocate and initialize interface vector. */
2080void
pauldc63bfd2005-10-25 23:31:05 +00002081rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002082{
2083 /* Default initial size of interface vector. */
2084 if_init();
2085 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2086 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2087
2088 /* RIP network init. */
2089 rip_enable_interface = vector_init (1);
2090 rip_enable_network = route_table_init ();
2091
2092 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002093 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002094
2095 /* Install interface node. */
2096 install_node (&interface_node, rip_interface_config_write);
2097
2098 /* Install commands. */
2099 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002100 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002101 install_default (INTERFACE_NODE);
2102 install_element (INTERFACE_NODE, &interface_desc_cmd);
2103 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2104 install_element (RIP_NODE, &rip_network_cmd);
2105 install_element (RIP_NODE, &no_rip_network_cmd);
2106 install_element (RIP_NODE, &rip_neighbor_cmd);
2107 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2108
2109 install_element (RIP_NODE, &rip_passive_interface_cmd);
2110 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2111
2112 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2113 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2114 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2115 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2116 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2117
2118 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2119 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2120 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2121 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2122 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2123
2124 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002125 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002126 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2127 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002128 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002129
2130 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2131 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2132 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2133
2134 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2135 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2136 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2137
hasso16705132003-05-25 14:49:19 +00002138 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2139 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2140 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2141 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002142}