blob: da73724a6388a0962b106bc0d0730a8cbc97c820 [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"
43
44void rip_enable_apply (struct interface *);
45void rip_passive_interface_apply (struct interface *);
46int rip_if_down(struct interface *ifp);
hasso98b718a2004-10-11 12:57:57 +000047int rip_enable_if_lookup (const char *ifname);
hasso16705132003-05-25 14:49:19 +000048int rip_enable_network_lookup2 (struct connected *connected);
49void rip_enable_apply_all ();
50
paul718e3742002-12-13 20:15:29 +000051
52struct message ri_version_msg[] =
53{
54 {RI_RIP_VERSION_1, "1"},
55 {RI_RIP_VERSION_2, "2"},
56 {RI_RIP_VERSION_1_AND_2, "1 2"},
57 {0, NULL}
58};
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. */
73int
74ipv4_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. */
95int
96ipv4_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. */
116struct rip_interface *
117rip_interface_new ()
118{
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. */
126 /* ri->auth_type = RIP_NO_AUTH; */
127 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
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{
143 int ret;
paul718e3742002-12-13 20:15:29 +0000144 struct servent *sp;
145 struct sockaddr_in from;
hasso3fb9cd62004-10-19 19:44:43 +0000146 struct in_addr addr;
paulcc1131a2003-10-15 23:20:17 +0000147 struct prefix_ipv4 *p;
paulc49ad8f2004-10-22 10:27:28 +0000148
149 assert (connected != NULL);
150
151 if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected))
152 p = (struct prefix_ipv4 *) connected->destination;
153 else
154 p = (struct prefix_ipv4 *) connected->address;
155
156 addr = p->prefix;
paul718e3742002-12-13 20:15:29 +0000157
paul1a517862004-08-19 04:03:08 +0000158 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
159 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000160 {
161 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
162 "source address %s for interface %s",
163 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000164 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000165 return;
166 }
paul718e3742002-12-13 20:15:29 +0000167
hasso3fb9cd62004-10-19 19:44:43 +0000168 /* Bind myself. */
169 memset (&from, 0, sizeof (struct sockaddr_in));
paul718e3742002-12-13 20:15:29 +0000170
hasso3fb9cd62004-10-19 19:44:43 +0000171 /* Set RIP port. */
172 sp = getservbyname ("router", "udp");
173 if (sp)
174 from.sin_port = sp->s_port;
175 else
176 from.sin_port = htons (RIP_PORT_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000177
paul931cd542004-01-23 15:31:42 +0000178 /* Address should be any address. */
hasso3fb9cd62004-10-19 19:44:43 +0000179 from.sin_family = AF_INET;
paulc49ad8f2004-10-22 10:27:28 +0000180 from.sin_addr = connected->address->u.prefix4;
paul718e3742002-12-13 20:15:29 +0000181#ifdef HAVE_SIN_LEN
hasso3fb9cd62004-10-19 19:44:43 +0000182 from.sin_len = sizeof (struct sockaddr_in);
paul718e3742002-12-13 20:15:29 +0000183#endif /* HAVE_SIN_LEN */
184
hasso3fb9cd62004-10-19 19:44:43 +0000185 if (ripd_privs.change (ZPRIVS_RAISE))
186 zlog_err ("rip_interface_multicast_set: could not raise privs");
pauledd7c242003-06-04 13:59:38 +0000187
paulcc1131a2003-10-15 23:20:17 +0000188 ret = bind (sock, (struct sockaddr *) & from, sizeof (struct sockaddr_in));
hasso3fb9cd62004-10-19 19:44:43 +0000189 if (ret < 0)
190 {
191 zlog_warn ("Can't bind socket fd %d to %s port %d for "
192 "interface %s: %s",
193 sock,inet_ntoa(from.sin_addr),
194 (int)ntohs(from.sin_port),
paulc49ad8f2004-10-22 10:27:28 +0000195 connected->ifp->name,
ajs6099b3b2004-11-20 02:06:59 +0000196 safe_strerror (errno));
hasso3fb9cd62004-10-19 19:44:43 +0000197 }
paul718e3742002-12-13 20:15:29 +0000198
hasso3fb9cd62004-10-19 19:44:43 +0000199 if (ripd_privs.change (ZPRIVS_LOWER))
200 zlog_err ("rip_interface_multicast_set: could not lower privs");
pauledd7c242003-06-04 13:59:38 +0000201
hasso3fb9cd62004-10-19 19:44:43 +0000202 return;
203}
paul718e3742002-12-13 20:15:29 +0000204
205/* Send RIP request packet to specified interface. */
206void
207rip_request_interface_send (struct interface *ifp, u_char version)
208{
209 struct sockaddr_in to;
210
211 /* RIPv2 support multicast. */
212 if (version == RIPv2 && if_is_multicast (ifp))
213 {
214
215 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000216 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000217
paul931cd542004-01-23 15:31:42 +0000218 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000219 return;
220 }
221
222 /* RIPv1 and non multicast interface. */
223 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
224 {
paul1eb8ef22005-04-07 07:30:20 +0000225 struct listnode *cnode, *cnnode;
226 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000227
228 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000229 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000230
paul1eb8ef22005-04-07 07:30:20 +0000231 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000232 {
hasso3fb9cd62004-10-19 19:44:43 +0000233 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000234 {
235 memset (&to, 0, sizeof (struct sockaddr_in));
236 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000237 if (connected->destination)
238 /* use specified broadcast or point-to-point destination addr */
239 to.sin_addr = connected->destination->u.prefix4;
240 else
241 /* calculate the appropriate broadcast address */
242 to.sin_addr.s_addr =
243 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
244 connected->address->prefixlen);
paul718e3742002-12-13 20:15:29 +0000245
paul718e3742002-12-13 20:15:29 +0000246 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000247 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000248
paul931cd542004-01-23 15:31:42 +0000249 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000250 }
251 }
252 }
253}
254
255/* This will be executed when interface goes up. */
256void
257rip_request_interface (struct interface *ifp)
258{
259 struct rip_interface *ri;
260
261 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
262 if (if_is_loopback (ifp))
263 return;
264
265 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000266 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000267 return;
268
269 /* Fetch RIP interface information. */
270 ri = ifp->info;
271
272
273 /* If there is no version configuration in the interface,
274 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000275 {
276 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
277 rip->version_send : ri->ri_send);
278 if (vsend & RIPv1)
279 rip_request_interface_send (ifp, RIPv1);
280 if (vsend & RIPv2)
281 rip_request_interface_send (ifp, RIPv2);
282 }
paul718e3742002-12-13 20:15:29 +0000283}
284
285/* Send RIP request to the neighbor. */
286void
287rip_request_neighbor (struct in_addr addr)
288{
289 struct sockaddr_in to;
290
291 memset (&to, 0, sizeof (struct sockaddr_in));
292 to.sin_port = htons (RIP_PORT_DEFAULT);
293 to.sin_addr = addr;
294
paul931cd542004-01-23 15:31:42 +0000295 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000296}
297
298/* Request routes at all interfaces. */
299void
300rip_request_neighbor_all ()
301{
302 struct route_node *rp;
303
304 if (! rip)
305 return;
306
307 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000308 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000309
310 /* Send request to all neighbor. */
311 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
312 if (rp->info)
313 rip_request_neighbor (rp->p.u.prefix4);
314}
315
316/* Multicast packet receive socket. */
317int
318rip_multicast_join (struct interface *ifp, int sock)
319{
hasso52dc7ee2004-09-23 19:18:23 +0000320 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000321 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000322
paul2e3b2e42002-12-13 21:03:13 +0000323 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000324 {
325 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000326 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000327
paul1eb8ef22005-04-07 07:30:20 +0000328 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000329 {
330 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000331 struct in_addr group;
332
paul1eb8ef22005-04-07 07:30:20 +0000333 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000334
335 if (p->family != AF_INET)
336 continue;
337
338 group.s_addr = htonl (INADDR_RIP_GROUP);
339 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
340 return -1;
341 else
342 return 0;
343 }
344 }
345 return 0;
346}
347
348/* Leave from multicast group. */
349void
350rip_multicast_leave (struct interface *ifp, int sock)
351{
hasso52dc7ee2004-09-23 19:18:23 +0000352 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000353 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000354
355 if (if_is_up (ifp) && if_is_multicast (ifp))
356 {
357 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000358 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000359
paul1eb8ef22005-04-07 07:30:20 +0000360 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000361 {
362 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000363 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000364
paul718e3742002-12-13 20:15:29 +0000365 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000366
paul718e3742002-12-13 20:15:29 +0000367 if (p->family != AF_INET)
368 continue;
369
370 group.s_addr = htonl (INADDR_RIP_GROUP);
371 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
372 return;
373 }
374 }
375}
376
377/* Is there and address on interface that I could use ? */
378int
379rip_if_ipv4_address_check (struct interface *ifp)
380{
381 struct listnode *nn;
382 struct connected *connected;
383 int count = 0;
384
paul1eb8ef22005-04-07 07:30:20 +0000385 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
386 {
387 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000388
paul1eb8ef22005-04-07 07:30:20 +0000389 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000390
paul1eb8ef22005-04-07 07:30:20 +0000391 if (p->family == AF_INET)
392 count++;
393 }
paul718e3742002-12-13 20:15:29 +0000394
395 return count;
396}
paul31a476c2003-09-29 19:54:53 +0000397
398
399
400
401/* Does this address belongs to me ? */
402int
403if_check_address (struct in_addr addr)
404{
hasso52dc7ee2004-09-23 19:18:23 +0000405 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000406 struct interface *ifp;
407
408 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000409 {
hasso52dc7ee2004-09-23 19:18:23 +0000410 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000411 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000412
paul1eb8ef22005-04-07 07:30:20 +0000413 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000414 {
paul31a476c2003-09-29 19:54:53 +0000415 struct prefix_ipv4 *p;
416
paul31a476c2003-09-29 19:54:53 +0000417 p = (struct prefix_ipv4 *) connected->address;
418
419 if (p->family != AF_INET)
420 continue;
421
422 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
423 return 1;
424 }
425 }
426 return 0;
427}
428
429/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
430int
431if_valid_neighbor (struct in_addr addr)
432{
hasso52dc7ee2004-09-23 19:18:23 +0000433 struct listnode *node;
paul31a476c2003-09-29 19:54:53 +0000434 struct connected *connected = NULL;
paul1eb8ef22005-04-07 07:30:20 +0000435 struct interface *ifp;
paul31a476c2003-09-29 19:54:53 +0000436 struct prefix_ipv4 *p;
hasso3fb9cd62004-10-19 19:44:43 +0000437 struct prefix_ipv4 pa;
438
439 pa.family = AF_INET;
440 pa.prefix = addr;
441 pa.prefixlen = IPV4_MAX_PREFIXLEN;
paul31a476c2003-09-29 19:54:53 +0000442
paul1eb8ef22005-04-07 07:30:20 +0000443 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000444 {
hasso52dc7ee2004-09-23 19:18:23 +0000445 struct listnode *cnode;
paul31a476c2003-09-29 19:54:53 +0000446
paul1eb8ef22005-04-07 07:30:20 +0000447 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000448 {
paul31a476c2003-09-29 19:54:53 +0000449 if (if_is_pointopoint (ifp))
450 {
451 p = (struct prefix_ipv4 *) connected->address;
452
453 if (p && p->family == AF_INET)
454 {
455 if (IPV4_ADDR_SAME (&p->prefix, &addr))
456 return 1;
457
458 p = (struct prefix_ipv4 *) connected->destination;
hasso3fb9cd62004-10-19 19:44:43 +0000459 if (p)
460 {
461 if (IPV4_ADDR_SAME (&p->prefix, &addr))
462 return 1;
463 }
464 else
465 {
466 if (prefix_match(connected->address,(struct prefix *)&pa))
467 return 1;
468 }
paul31a476c2003-09-29 19:54:53 +0000469 }
470 }
471 else
472 {
hasso3fb9cd62004-10-19 19:44:43 +0000473 if ((connected->address->family == AF_INET) &&
474 prefix_match(connected->address,(struct prefix *)&pa))
475 return 1;
paul31a476c2003-09-29 19:54:53 +0000476 }
477 }
478 }
479 return 0;
480}
paul718e3742002-12-13 20:15:29 +0000481
482/* Inteface link down message processing. */
483int
484rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
485{
486 struct interface *ifp;
487 struct stream *s;
488
489 s = zclient->ibuf;
490
491 /* zebra_interface_state_read() updates interface structure in
492 iflist. */
493 ifp = zebra_interface_state_read(s);
494
495 if (ifp == NULL)
496 return 0;
497
498 rip_if_down(ifp);
499
500 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000501 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000502 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
503
504 return 0;
505}
506
507/* Inteface link up message processing */
508int
509rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
510{
511 struct interface *ifp;
512
513 /* zebra_interface_state_read () updates interface structure in
514 iflist. */
515 ifp = zebra_interface_state_read (zclient->ibuf);
516
517 if (ifp == NULL)
518 return 0;
519
520 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000521 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000522 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
523
524 /* Check if this interface is RIP enabled or not.*/
525 rip_enable_apply (ifp);
526
527 /* Check for a passive interface */
528 rip_passive_interface_apply (ifp);
529
530 /* Apply distribute list to the all interface. */
531 rip_distribute_update_interface (ifp);
532
533 return 0;
534}
535
536/* Inteface addition message from zebra. */
537int
538rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
539{
540 struct interface *ifp;
541
542 ifp = zebra_interface_add_read (zclient->ibuf);
543
544 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000545 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000546 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
547
548 /* Check if this interface is RIP enabled or not.*/
549 rip_enable_apply (ifp);
550
551 /* Apply distribute list to the all interface. */
552 rip_distribute_update_interface (ifp);
553
554 /* rip_request_neighbor_all (); */
555
hasso16705132003-05-25 14:49:19 +0000556 /* Check interface routemap. */
557 rip_if_rmap_update_interface (ifp);
558
paul718e3742002-12-13 20:15:29 +0000559 return 0;
560}
561
562int
563rip_interface_delete (int command, struct zclient *zclient,
564 zebra_size_t length)
565{
566 struct interface *ifp;
567 struct stream *s;
568
569
570 s = zclient->ibuf;
571 /* zebra_interface_state_read() updates interface structure in iflist */
572 ifp = zebra_interface_state_read(s);
573
574 if (ifp == NULL)
575 return 0;
576
577 if (if_is_up (ifp)) {
578 rip_if_down(ifp);
579 }
580
581 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
582 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
583
584 /* To support pseudo interface do not free interface structure. */
585 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000586 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000587
588 return 0;
589}
590
591void
592rip_interface_clean ()
593{
hasso52dc7ee2004-09-23 19:18:23 +0000594 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000595 struct interface *ifp;
596 struct rip_interface *ri;
597
paul1eb8ef22005-04-07 07:30:20 +0000598 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000599 {
paul718e3742002-12-13 20:15:29 +0000600 ri = ifp->info;
601
602 ri->enable_network = 0;
603 ri->enable_interface = 0;
604 ri->running = 0;
605
606 if (ri->t_wakeup)
607 {
608 thread_cancel (ri->t_wakeup);
609 ri->t_wakeup = NULL;
610 }
611 }
612}
613
614void
615rip_interface_reset ()
616{
hasso52dc7ee2004-09-23 19:18:23 +0000617 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000618 struct interface *ifp;
619 struct rip_interface *ri;
620
paul1eb8ef22005-04-07 07:30:20 +0000621 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000622 {
paul718e3742002-12-13 20:15:29 +0000623 ri = ifp->info;
624
625 ri->enable_network = 0;
626 ri->enable_interface = 0;
627 ri->running = 0;
628
629 ri->ri_send = RI_RIP_UNSPEC;
630 ri->ri_receive = RI_RIP_UNSPEC;
631
632 /* ri->auth_type = RIP_NO_AUTH; */
633 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
634
635 if (ri->auth_str)
636 {
637 free (ri->auth_str);
638 ri->auth_str = NULL;
639 }
640 if (ri->key_chain)
641 {
642 free (ri->key_chain);
643 ri->key_chain = NULL;
644 }
645
hasso16705132003-05-25 14:49:19 +0000646 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
647 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000648
649 ri->list[RIP_FILTER_IN] = NULL;
650 ri->list[RIP_FILTER_OUT] = NULL;
651
652 ri->prefix[RIP_FILTER_IN] = NULL;
653 ri->prefix[RIP_FILTER_OUT] = NULL;
654
655 if (ri->t_wakeup)
656 {
657 thread_cancel (ri->t_wakeup);
658 ri->t_wakeup = NULL;
659 }
660
661 ri->recv_badpackets = 0;
662 ri->recv_badroutes = 0;
663 ri->sent_updates = 0;
664
665 ri->passive = 0;
666 }
667}
668
669int
670rip_if_down(struct interface *ifp)
671{
672 struct route_node *rp;
673 struct rip_info *rinfo;
674 struct rip_interface *ri = NULL;
675 if (rip)
676 {
677 for (rp = route_top (rip->table); rp; rp = route_next (rp))
678 if ((rinfo = rp->info) != NULL)
679 {
680 /* Routes got through this interface. */
681 if (rinfo->ifindex == ifp->ifindex &&
682 rinfo->type == ZEBRA_ROUTE_RIP &&
683 rinfo->sub_type == RIP_ROUTE_RTE)
684 {
685 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
686 &rinfo->nexthop,
687 rinfo->ifindex);
688
689 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
690 (struct prefix_ipv4 *)&rp->p,
691 rinfo->ifindex);
692 }
693 else
694 {
695 /* All redistributed routes but static and system */
696 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000697 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000698 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
699 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
700 (struct prefix_ipv4 *)&rp->p,
701 rinfo->ifindex);
702 }
703 }
704 }
705
706 ri = ifp->info;
707
708 if (ri->running)
709 {
710 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000711 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000712
713 /* Leave from multicast group. */
714 rip_multicast_leave (ifp, rip->sock);
715
716 ri->running = 0;
717 }
718
719 return 0;
720}
721
722/* Needed for stop RIP process. */
723void
724rip_if_down_all ()
725{
726 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000727 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000728
paul1eb8ef22005-04-07 07:30:20 +0000729 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
730 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000731}
732
hasso16705132003-05-25 14:49:19 +0000733static void
734rip_apply_address_add (struct connected *ifc) {
735 struct prefix_ipv4 address;
736 struct prefix *p;
737
738 if (!rip)
739 return;
740
741 if (! if_is_up(ifc->ifp))
742 return;
743
744 p = ifc->address;
745
746 memset (&address, 0, sizeof (address));
747 address.family = p->family;
748 address.prefix = p->u.prefix4;
749 address.prefixlen = p->prefixlen;
750 apply_mask_ipv4(&address);
751
752 /* Check if this interface is RIP enabled or not
753 or Check if this address's prefix is RIP enabled */
754 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
755 (rip_enable_network_lookup2(ifc) >= 0))
756 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
757 &address, ifc->ifp->ifindex, NULL);
758
759}
760
paul718e3742002-12-13 20:15:29 +0000761int
762rip_interface_address_add (int command, struct zclient *zclient,
763 zebra_size_t length)
764{
765 struct connected *ifc;
766 struct prefix *p;
767
paul0a589352004-05-08 11:48:26 +0000768 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
769 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000770
771 if (ifc == NULL)
772 return 0;
773
774 p = ifc->address;
775
776 if (p->family == AF_INET)
777 {
778 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000779 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000780 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000781
paul878ef2e2003-09-23 23:41:50 +0000782 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000783 /* Check if this prefix needs to be redistributed */
784 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000785
786#ifdef HAVE_SNMP
787 rip_ifaddr_add (ifc->ifp, ifc);
788#endif /* HAVE_SNMP */
789 }
790
791 return 0;
792}
793
hasso16705132003-05-25 14:49:19 +0000794static void
795rip_apply_address_del (struct connected *ifc) {
796 struct prefix_ipv4 address;
797 struct prefix *p;
798
799 if (!rip)
800 return;
801
802 if (! if_is_up(ifc->ifp))
803 return;
804
805 p = ifc->address;
806
807 memset (&address, 0, sizeof (address));
808 address.family = p->family;
809 address.prefix = p->u.prefix4;
810 address.prefixlen = p->prefixlen;
811 apply_mask_ipv4(&address);
812
813 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
814 &address, ifc->ifp->ifindex);
815}
816
paul718e3742002-12-13 20:15:29 +0000817int
818rip_interface_address_delete (int command, struct zclient *zclient,
819 zebra_size_t length)
820{
821 struct connected *ifc;
822 struct prefix *p;
823
paul0a589352004-05-08 11:48:26 +0000824 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
825 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000826
827 if (ifc)
828 {
829 p = ifc->address;
830 if (p->family == AF_INET)
831 {
832 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000833 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000834 inet_ntoa (p->u.prefix4), p->prefixlen);
835
836#ifdef HAVE_SNMP
837 rip_ifaddr_delete (ifc->ifp, ifc);
838#endif /* HAVE_SNMP */
839
hasso16705132003-05-25 14:49:19 +0000840 /* Chech wether this prefix needs to be removed */
841 rip_apply_address_del(ifc);
842
paul718e3742002-12-13 20:15:29 +0000843 }
844
845 connected_free (ifc);
846
847 }
848
849 return 0;
850}
851
852/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000853/* Check wether the interface has at least a connected prefix that
854 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000855int
hasso16705132003-05-25 14:49:19 +0000856rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000857{
paul1eb8ef22005-04-07 07:30:20 +0000858 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000859 struct connected *connected;
860 struct prefix_ipv4 address;
861
paul1eb8ef22005-04-07 07:30:20 +0000862 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
863 {
864 struct prefix *p;
865 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000866
paul1eb8ef22005-04-07 07:30:20 +0000867 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000868
paul1eb8ef22005-04-07 07:30:20 +0000869 if (p->family == AF_INET)
870 {
871 address.family = AF_INET;
872 address.prefix = p->u.prefix4;
873 address.prefixlen = IPV4_MAX_BITLEN;
874
875 node = route_node_match (rip_enable_network,
876 (struct prefix *)&address);
877 if (node)
878 {
879 route_unlock_node (node);
880 return 1;
881 }
882 }
883 }
paul718e3742002-12-13 20:15:29 +0000884 return -1;
885}
886
hasso16705132003-05-25 14:49:19 +0000887/* Check wether connected is within the ripng_enable_network table. */
888int
889rip_enable_network_lookup2 (struct connected *connected)
890{
891 struct prefix_ipv4 address;
892 struct prefix *p;
893
894 p = connected->address;
895
896 if (p->family == AF_INET) {
897 struct route_node *node;
898
899 address.family = p->family;
900 address.prefix = p->u.prefix4;
901 address.prefixlen = IPV4_MAX_BITLEN;
902
903 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
904 node = route_node_match (rip_enable_network,
905 (struct prefix *)&address);
906
907 if (node) {
908 route_unlock_node (node);
909 return 1;
910 }
911 }
912
913 return -1;
914}
paul718e3742002-12-13 20:15:29 +0000915/* Add RIP enable network. */
916int
917rip_enable_network_add (struct prefix *p)
918{
919 struct route_node *node;
920
921 node = route_node_get (rip_enable_network, p);
922
923 if (node->info)
924 {
925 route_unlock_node (node);
926 return -1;
927 }
928 else
hasso8a676be2004-10-08 06:36:38 +0000929 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000930
hasso16705132003-05-25 14:49:19 +0000931 /* XXX: One should find a better solution than a generic one */
932 rip_enable_apply_all();
933
paul718e3742002-12-13 20:15:29 +0000934 return 1;
935}
936
937/* Delete RIP enable network. */
938int
939rip_enable_network_delete (struct prefix *p)
940{
941 struct route_node *node;
942
943 node = route_node_lookup (rip_enable_network, p);
944 if (node)
945 {
946 node->info = NULL;
947
948 /* Unlock info lock. */
949 route_unlock_node (node);
950
951 /* Unlock lookup lock. */
952 route_unlock_node (node);
953
hasso16705132003-05-25 14:49:19 +0000954 /* XXX: One should find a better solution than a generic one */
955 rip_enable_apply_all ();
956
paul718e3742002-12-13 20:15:29 +0000957 return 1;
958 }
959 return -1;
960}
961
962/* Check interface is enabled by ifname statement. */
963int
hasso98b718a2004-10-11 12:57:57 +0000964rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000965{
hasso8a676be2004-10-08 06:36:38 +0000966 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000967 char *str;
968
paul55468c82005-03-14 20:19:01 +0000969 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000970 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
971 if (strcmp (str, ifname) == 0)
972 return i;
973 return -1;
974}
975
976/* Add interface to rip_enable_if. */
977int
hasso98b718a2004-10-11 12:57:57 +0000978rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000979{
980 int ret;
981
982 ret = rip_enable_if_lookup (ifname);
983 if (ret >= 0)
984 return -1;
985
986 vector_set (rip_enable_interface, strdup (ifname));
987
hasso16705132003-05-25 14:49:19 +0000988 rip_enable_apply_all(); /* TODOVJ */
989
paul718e3742002-12-13 20:15:29 +0000990 return 1;
991}
992
993/* Delete interface from rip_enable_if. */
994int
hasso98b718a2004-10-11 12:57:57 +0000995rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000996{
997 int index;
998 char *str;
999
1000 index = rip_enable_if_lookup (ifname);
1001 if (index < 0)
1002 return -1;
1003
1004 str = vector_slot (rip_enable_interface, index);
1005 free (str);
1006 vector_unset (rip_enable_interface, index);
1007
hasso16705132003-05-25 14:49:19 +00001008 rip_enable_apply_all(); /* TODOVJ */
1009
paul718e3742002-12-13 20:15:29 +00001010 return 1;
1011}
1012
1013/* Join to multicast group and send request to the interface. */
1014int
1015rip_interface_wakeup (struct thread *t)
1016{
1017 struct interface *ifp;
1018 struct rip_interface *ri;
1019
1020 /* Get interface. */
1021 ifp = THREAD_ARG (t);
1022
1023 ri = ifp->info;
1024 ri->t_wakeup = NULL;
1025
1026 /* Join to multicast group. */
1027 if (rip_multicast_join (ifp, rip->sock) < 0)
1028 {
1029 zlog_err ("multicast join failed, interface %s not running", ifp->name);
1030 return 0;
1031 }
1032
1033 /* Set running flag. */
1034 ri->running = 1;
1035
1036 /* Send RIP request to the interface. */
1037 rip_request_interface (ifp);
1038
1039 return 0;
1040}
1041
1042int rip_redistribute_check (int);
1043
1044void
1045rip_connect_set (struct interface *ifp, int set)
1046{
paul1eb8ef22005-04-07 07:30:20 +00001047 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001048 struct connected *connected;
1049 struct prefix_ipv4 address;
1050
paul1eb8ef22005-04-07 07:30:20 +00001051 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
1052 {
1053 struct prefix *p;
1054 p = connected->address;
paul718e3742002-12-13 20:15:29 +00001055
paul1eb8ef22005-04-07 07:30:20 +00001056 if (p->family != AF_INET)
1057 continue;
paul718e3742002-12-13 20:15:29 +00001058
paul1eb8ef22005-04-07 07:30:20 +00001059 address.family = AF_INET;
1060 address.prefix = p->u.prefix4;
1061 address.prefixlen = p->prefixlen;
1062 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +00001063
paul1eb8ef22005-04-07 07:30:20 +00001064 if (set) {
1065 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1066 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1067 (rip_enable_network_lookup2(connected) >= 0))
1068 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1069 &address, connected->ifp->ifindex, NULL);
1070 } else
1071 {
1072 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1073 &address, connected->ifp->ifindex);
1074 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1075 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1076 &address, connected->ifp->ifindex, NULL);
1077 }
1078 }
paul718e3742002-12-13 20:15:29 +00001079}
1080
1081/* Update interface status. */
1082void
1083rip_enable_apply (struct interface *ifp)
1084{
1085 int ret;
1086 struct rip_interface *ri = NULL;
1087
1088 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001089 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001090 return;
1091
1092 ri = ifp->info;
1093
1094 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001095 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001096
1097 /* If the interface is matched. */
1098 if (ret > 0)
1099 ri->enable_network = 1;
1100 else
1101 ri->enable_network = 0;
1102
1103 /* Check interface name configuration. */
1104 ret = rip_enable_if_lookup (ifp->name);
1105 if (ret >= 0)
1106 ri->enable_interface = 1;
1107 else
1108 ri->enable_interface = 0;
1109
1110 /* any interface MUST have an IPv4 address */
1111 if ( ! rip_if_ipv4_address_check (ifp) )
1112 {
1113 ri->enable_network = 0;
1114 ri->enable_interface = 0;
1115 }
1116
1117 /* Update running status of the interface. */
1118 if (ri->enable_network || ri->enable_interface)
1119 {
paul718e3742002-12-13 20:15:29 +00001120 {
1121 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001122 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001123
1124 /* Add interface wake up thread. */
1125 if (! ri->t_wakeup)
1126 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1127 ifp, 1);
1128 rip_connect_set (ifp, 1);
1129 }
1130 }
1131 else
1132 {
1133 if (ri->running)
1134 {
hasso16705132003-05-25 14:49:19 +00001135 /* Might as well clean up the route table as well
1136 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1137 **/
paul718e3742002-12-13 20:15:29 +00001138 rip_if_down(ifp);
1139
paul718e3742002-12-13 20:15:29 +00001140 rip_connect_set (ifp, 0);
1141 }
1142 }
1143}
1144
1145/* Apply network configuration to all interface. */
1146void
1147rip_enable_apply_all ()
1148{
1149 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001150 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001151
1152 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001153 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1154 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001155}
1156
1157int
1158rip_neighbor_lookup (struct sockaddr_in *from)
1159{
1160 struct prefix_ipv4 p;
1161 struct route_node *node;
1162
1163 memset (&p, 0, sizeof (struct prefix_ipv4));
1164 p.family = AF_INET;
1165 p.prefix = from->sin_addr;
1166 p.prefixlen = IPV4_MAX_BITLEN;
1167
1168 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1169 if (node)
1170 {
1171 route_unlock_node (node);
1172 return 1;
1173 }
1174 return 0;
1175}
1176
1177/* Add new RIP neighbor to the neighbor tree. */
1178int
1179rip_neighbor_add (struct prefix_ipv4 *p)
1180{
1181 struct route_node *node;
1182
1183 node = route_node_get (rip->neighbor, (struct prefix *) p);
1184
1185 if (node->info)
1186 return -1;
1187
1188 node->info = rip->neighbor;
1189
1190 return 0;
1191}
1192
1193/* Delete RIP neighbor from the neighbor tree. */
1194int
1195rip_neighbor_delete (struct prefix_ipv4 *p)
1196{
1197 struct route_node *node;
1198
1199 /* Lock for look up. */
1200 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1201 if (! node)
1202 return -1;
1203
1204 node->info = NULL;
1205
1206 /* Unlock lookup lock. */
1207 route_unlock_node (node);
1208
1209 /* Unlock real neighbor information lock. */
1210 route_unlock_node (node);
1211
1212 return 0;
1213}
1214
1215/* Clear all network and neighbor configuration. */
1216void
1217rip_clean_network ()
1218{
hasso8a676be2004-10-08 06:36:38 +00001219 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001220 char *str;
1221 struct route_node *rn;
1222
1223 /* rip_enable_network. */
1224 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1225 if (rn->info)
1226 {
1227 rn->info = NULL;
1228 route_unlock_node (rn);
1229 }
1230
1231 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001232 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001233 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1234 {
1235 free (str);
1236 vector_slot (rip_enable_interface, i) = NULL;
1237 }
1238}
1239
1240/* Utility function for looking up passive interface settings. */
1241int
hasso98b718a2004-10-11 12:57:57 +00001242rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001243{
hasso8a676be2004-10-08 06:36:38 +00001244 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001245 char *str;
1246
paul55468c82005-03-14 20:19:01 +00001247 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001248 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001249 if (strcmp (str, ifname) == 0)
1250 return i;
1251 return -1;
1252}
1253
1254void
1255rip_passive_interface_apply (struct interface *ifp)
1256{
paul718e3742002-12-13 20:15:29 +00001257 struct rip_interface *ri;
1258
1259 ri = ifp->info;
1260
paul4aaff3f2003-06-07 01:04:45 +00001261 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1262 passive_default : !passive_default);
1263
1264 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001265 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001266}
1267
1268void
1269rip_passive_interface_apply_all ()
1270{
1271 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001272 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001273
paul1eb8ef22005-04-07 07:30:20 +00001274 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1275 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001276}
1277
1278/* Passive interface. */
1279int
hasso98b718a2004-10-11 12:57:57 +00001280rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001281{
paul4aaff3f2003-06-07 01:04:45 +00001282 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001283 return CMD_WARNING;
1284
paul4aaff3f2003-06-07 01:04:45 +00001285 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001286
1287 rip_passive_interface_apply_all ();
1288
1289 return CMD_SUCCESS;
1290}
1291
1292int
hasso98b718a2004-10-11 12:57:57 +00001293rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001294{
1295 int i;
1296 char *str;
1297
paul4aaff3f2003-06-07 01:04:45 +00001298 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001299 if (i < 0)
1300 return CMD_WARNING;
1301
paul4aaff3f2003-06-07 01:04:45 +00001302 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001303 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001304 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001305
1306 rip_passive_interface_apply_all ();
1307
1308 return CMD_SUCCESS;
1309}
1310
1311/* Free all configured RIP passive-interface settings. */
1312void
paul4aaff3f2003-06-07 01:04:45 +00001313rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001314{
hasso8a676be2004-10-08 06:36:38 +00001315 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001316 char *str;
1317
paul55468c82005-03-14 20:19:01 +00001318 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001319 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001320 {
1321 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001322 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001323 }
1324 rip_passive_interface_apply_all ();
1325}
1326
1327/* RIP enable network or interface configuration. */
1328DEFUN (rip_network,
1329 rip_network_cmd,
1330 "network (A.B.C.D/M|WORD)",
1331 "Enable routing on an IP network\n"
1332 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1333 "Interface name\n")
1334{
1335 int ret;
1336 struct prefix_ipv4 p;
1337
1338 ret = str2prefix_ipv4 (argv[0], &p);
1339
1340 if (ret)
1341 ret = rip_enable_network_add ((struct prefix *) &p);
1342 else
1343 ret = rip_enable_if_add (argv[0]);
1344
1345 if (ret < 0)
1346 {
1347 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1348 VTY_NEWLINE);
1349 return CMD_WARNING;
1350 }
1351
paul718e3742002-12-13 20:15:29 +00001352 return CMD_SUCCESS;
1353}
1354
1355/* RIP enable network or interface configuration. */
1356DEFUN (no_rip_network,
1357 no_rip_network_cmd,
1358 "no network (A.B.C.D/M|WORD)",
1359 NO_STR
1360 "Enable routing on an IP network\n"
1361 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1362 "Interface name\n")
1363{
1364 int ret;
1365 struct prefix_ipv4 p;
1366
1367 ret = str2prefix_ipv4 (argv[0], &p);
1368
1369 if (ret)
1370 ret = rip_enable_network_delete ((struct prefix *) &p);
1371 else
1372 ret = rip_enable_if_delete (argv[0]);
1373
1374 if (ret < 0)
1375 {
1376 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1377 VTY_NEWLINE);
1378 return CMD_WARNING;
1379 }
1380
paul718e3742002-12-13 20:15:29 +00001381 return CMD_SUCCESS;
1382}
1383
1384/* RIP neighbor configuration set. */
1385DEFUN (rip_neighbor,
1386 rip_neighbor_cmd,
1387 "neighbor A.B.C.D",
1388 "Specify a neighbor router\n"
1389 "Neighbor address\n")
1390{
1391 int ret;
1392 struct prefix_ipv4 p;
1393
1394 ret = str2prefix_ipv4 (argv[0], &p);
1395
1396 if (ret <= 0)
1397 {
1398 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1399 return CMD_WARNING;
1400 }
1401
1402 rip_neighbor_add (&p);
1403
1404 return CMD_SUCCESS;
1405}
1406
1407/* RIP neighbor configuration unset. */
1408DEFUN (no_rip_neighbor,
1409 no_rip_neighbor_cmd,
1410 "no neighbor A.B.C.D",
1411 NO_STR
1412 "Specify a neighbor router\n"
1413 "Neighbor address\n")
1414{
1415 int ret;
1416 struct prefix_ipv4 p;
1417
1418 ret = str2prefix_ipv4 (argv[0], &p);
1419
1420 if (ret <= 0)
1421 {
1422 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1423 return CMD_WARNING;
1424 }
1425
1426 rip_neighbor_delete (&p);
1427
1428 return CMD_SUCCESS;
1429}
1430
1431DEFUN (ip_rip_receive_version,
1432 ip_rip_receive_version_cmd,
1433 "ip rip receive version (1|2)",
1434 IP_STR
1435 "Routing Information Protocol\n"
1436 "Advertisement reception\n"
1437 "Version control\n"
1438 "RIP version 1\n"
1439 "RIP version 2\n")
1440{
1441 struct interface *ifp;
1442 struct rip_interface *ri;
1443
1444 ifp = (struct interface *)vty->index;
1445 ri = ifp->info;
1446
1447 /* Version 1. */
1448 if (atoi (argv[0]) == 1)
1449 {
1450 ri->ri_receive = RI_RIP_VERSION_1;
1451 return CMD_SUCCESS;
1452 }
1453 if (atoi (argv[0]) == 2)
1454 {
1455 ri->ri_receive = RI_RIP_VERSION_2;
1456 return CMD_SUCCESS;
1457 }
1458 return CMD_WARNING;
1459}
1460
1461DEFUN (ip_rip_receive_version_1,
1462 ip_rip_receive_version_1_cmd,
1463 "ip rip receive version 1 2",
1464 IP_STR
1465 "Routing Information Protocol\n"
1466 "Advertisement reception\n"
1467 "Version control\n"
1468 "RIP version 1\n"
1469 "RIP version 2\n")
1470{
1471 struct interface *ifp;
1472 struct rip_interface *ri;
1473
1474 ifp = (struct interface *)vty->index;
1475 ri = ifp->info;
1476
1477 /* Version 1 and 2. */
1478 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1479 return CMD_SUCCESS;
1480}
1481
1482DEFUN (ip_rip_receive_version_2,
1483 ip_rip_receive_version_2_cmd,
1484 "ip rip receive version 2 1",
1485 IP_STR
1486 "Routing Information Protocol\n"
1487 "Advertisement reception\n"
1488 "Version control\n"
1489 "RIP version 2\n"
1490 "RIP version 1\n")
1491{
1492 struct interface *ifp;
1493 struct rip_interface *ri;
1494
1495 ifp = (struct interface *)vty->index;
1496 ri = ifp->info;
1497
1498 /* Version 1 and 2. */
1499 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1500 return CMD_SUCCESS;
1501}
1502
1503DEFUN (no_ip_rip_receive_version,
1504 no_ip_rip_receive_version_cmd,
1505 "no ip rip receive version",
1506 NO_STR
1507 IP_STR
1508 "Routing Information Protocol\n"
1509 "Advertisement reception\n"
1510 "Version control\n")
1511{
1512 struct interface *ifp;
1513 struct rip_interface *ri;
1514
1515 ifp = (struct interface *)vty->index;
1516 ri = ifp->info;
1517
1518 ri->ri_receive = RI_RIP_UNSPEC;
1519 return CMD_SUCCESS;
1520}
1521
1522ALIAS (no_ip_rip_receive_version,
1523 no_ip_rip_receive_version_num_cmd,
1524 "no ip rip receive version (1|2)",
1525 NO_STR
1526 IP_STR
1527 "Routing Information Protocol\n"
1528 "Advertisement reception\n"
1529 "Version control\n"
1530 "Version 1\n"
1531 "Version 2\n")
1532
1533DEFUN (ip_rip_send_version,
1534 ip_rip_send_version_cmd,
1535 "ip rip send version (1|2)",
1536 IP_STR
1537 "Routing Information Protocol\n"
1538 "Advertisement transmission\n"
1539 "Version control\n"
1540 "RIP version 1\n"
1541 "RIP version 2\n")
1542{
1543 struct interface *ifp;
1544 struct rip_interface *ri;
1545
1546 ifp = (struct interface *)vty->index;
1547 ri = ifp->info;
1548
1549 /* Version 1. */
1550 if (atoi (argv[0]) == 1)
1551 {
1552 ri->ri_send = RI_RIP_VERSION_1;
1553 return CMD_SUCCESS;
1554 }
1555 if (atoi (argv[0]) == 2)
1556 {
1557 ri->ri_send = RI_RIP_VERSION_2;
1558 return CMD_SUCCESS;
1559 }
1560 return CMD_WARNING;
1561}
1562
1563DEFUN (ip_rip_send_version_1,
1564 ip_rip_send_version_1_cmd,
1565 "ip rip send version 1 2",
1566 IP_STR
1567 "Routing Information Protocol\n"
1568 "Advertisement transmission\n"
1569 "Version control\n"
1570 "RIP version 1\n"
1571 "RIP version 2\n")
1572{
1573 struct interface *ifp;
1574 struct rip_interface *ri;
1575
1576 ifp = (struct interface *)vty->index;
1577 ri = ifp->info;
1578
1579 /* Version 1 and 2. */
1580 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1581 return CMD_SUCCESS;
1582}
1583
1584DEFUN (ip_rip_send_version_2,
1585 ip_rip_send_version_2_cmd,
1586 "ip rip send version 2 1",
1587 IP_STR
1588 "Routing Information Protocol\n"
1589 "Advertisement transmission\n"
1590 "Version control\n"
1591 "RIP version 2\n"
1592 "RIP version 1\n")
1593{
1594 struct interface *ifp;
1595 struct rip_interface *ri;
1596
1597 ifp = (struct interface *)vty->index;
1598 ri = ifp->info;
1599
1600 /* Version 1 and 2. */
1601 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1602 return CMD_SUCCESS;
1603}
1604
1605DEFUN (no_ip_rip_send_version,
1606 no_ip_rip_send_version_cmd,
1607 "no ip rip send version",
1608 NO_STR
1609 IP_STR
1610 "Routing Information Protocol\n"
1611 "Advertisement transmission\n"
1612 "Version control\n")
1613{
1614 struct interface *ifp;
1615 struct rip_interface *ri;
1616
1617 ifp = (struct interface *)vty->index;
1618 ri = ifp->info;
1619
1620 ri->ri_send = RI_RIP_UNSPEC;
1621 return CMD_SUCCESS;
1622}
1623
1624ALIAS (no_ip_rip_send_version,
1625 no_ip_rip_send_version_num_cmd,
1626 "no ip rip send version (1|2)",
1627 NO_STR
1628 IP_STR
1629 "Routing Information Protocol\n"
1630 "Advertisement transmission\n"
1631 "Version control\n"
1632 "Version 1\n"
1633 "Version 2\n")
1634
1635DEFUN (ip_rip_authentication_mode,
1636 ip_rip_authentication_mode_cmd,
1637 "ip rip authentication mode (md5|text)",
1638 IP_STR
1639 "Routing Information Protocol\n"
1640 "Authentication control\n"
1641 "Authentication mode\n"
1642 "Keyed message digest\n"
1643 "Clear text authentication\n")
1644{
1645 struct interface *ifp;
1646 struct rip_interface *ri;
1647
1648 ifp = (struct interface *)vty->index;
1649 ri = ifp->info;
1650
paulca5e5162004-06-06 22:06:33 +00001651 if ( (argc < 1) || (argc > 2) )
1652 {
1653 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1654 return CMD_WARNING;
1655 }
1656
paul718e3742002-12-13 20:15:29 +00001657 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1658 ri->auth_type = RIP_AUTH_MD5;
1659 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1660 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1661 else
1662 {
1663 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1664 return CMD_WARNING;
1665 }
1666
paulca5e5162004-06-06 22:06:33 +00001667 if (argc == 1)
1668 return CMD_SUCCESS;
1669
1670 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1671 {
1672 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1673 return CMD_WARNING;
1674}
1675
1676 if (strncmp ("r", argv[1], 1) == 0)
1677 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1678 else if (strncmp ("o", argv[1], 1) == 0)
1679 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1680 else
1681 return CMD_WARNING;
1682
paul718e3742002-12-13 20:15:29 +00001683 return CMD_SUCCESS;
1684}
1685
paulca5e5162004-06-06 22:06:33 +00001686ALIAS (ip_rip_authentication_mode,
1687 ip_rip_authentication_mode_authlen_cmd,
1688 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1689 IP_STR
1690 "Routing Information Protocol\n"
1691 "Authentication control\n"
1692 "Authentication mode\n"
1693 "Keyed message digest\n"
1694 "Clear text authentication\n"
1695 "MD5 authentication data length\n"
1696 "RFC compatible\n"
1697 "Old ripd compatible\n")
1698
paul718e3742002-12-13 20:15:29 +00001699DEFUN (no_ip_rip_authentication_mode,
1700 no_ip_rip_authentication_mode_cmd,
1701 "no ip rip authentication mode",
1702 NO_STR
1703 IP_STR
1704 "Routing Information Protocol\n"
1705 "Authentication control\n"
1706 "Authentication mode\n")
1707{
1708 struct interface *ifp;
1709 struct rip_interface *ri;
1710
1711 ifp = (struct interface *)vty->index;
1712 ri = ifp->info;
1713
1714 /* ri->auth_type = RIP_NO_AUTH; */
1715 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paulca5e5162004-06-06 22:06:33 +00001716 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001717
1718 return CMD_SUCCESS;
1719}
1720
1721ALIAS (no_ip_rip_authentication_mode,
1722 no_ip_rip_authentication_mode_type_cmd,
1723 "no ip rip authentication mode (md5|text)",
1724 NO_STR
1725 IP_STR
1726 "Routing Information Protocol\n"
1727 "Authentication control\n"
1728 "Authentication mode\n"
1729 "Keyed message digest\n"
1730 "Clear text authentication\n")
1731
paulca5e5162004-06-06 22:06:33 +00001732ALIAS (no_ip_rip_authentication_mode,
1733 no_ip_rip_authentication_mode_type_authlen_cmd,
1734 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1735 NO_STR
1736 IP_STR
1737 "Routing Information Protocol\n"
1738 "Authentication control\n"
1739 "Authentication mode\n"
1740 "Keyed message digest\n"
1741 "Clear text authentication\n"
1742 "MD5 authentication data length\n"
1743 "RFC compatible\n"
1744 "Old ripd compatible\n")
1745
paul718e3742002-12-13 20:15:29 +00001746DEFUN (ip_rip_authentication_string,
1747 ip_rip_authentication_string_cmd,
1748 "ip rip authentication string LINE",
1749 IP_STR
1750 "Routing Information Protocol\n"
1751 "Authentication control\n"
1752 "Authentication string\n"
1753 "Authentication string\n")
1754{
1755 struct interface *ifp;
1756 struct rip_interface *ri;
1757
1758 ifp = (struct interface *)vty->index;
1759 ri = ifp->info;
1760
1761 if (strlen (argv[0]) > 16)
1762 {
1763 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1764 VTY_NEWLINE);
1765 return CMD_WARNING;
1766 }
1767
1768 if (ri->key_chain)
1769 {
1770 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1771 return CMD_WARNING;
1772 }
1773
1774 if (ri->auth_str)
1775 free (ri->auth_str);
1776
1777 ri->auth_str = strdup (argv[0]);
1778
1779 return CMD_SUCCESS;
1780}
1781
1782DEFUN (no_ip_rip_authentication_string,
1783 no_ip_rip_authentication_string_cmd,
1784 "no ip rip authentication string",
1785 NO_STR
1786 IP_STR
1787 "Routing Information Protocol\n"
1788 "Authentication control\n"
1789 "Authentication string\n")
1790{
1791 struct interface *ifp;
1792 struct rip_interface *ri;
1793
1794 ifp = (struct interface *)vty->index;
1795 ri = ifp->info;
1796
1797 if (ri->auth_str)
1798 free (ri->auth_str);
1799
1800 ri->auth_str = NULL;
1801
1802 return CMD_SUCCESS;
1803}
1804
1805ALIAS (no_ip_rip_authentication_string,
1806 no_ip_rip_authentication_string2_cmd,
1807 "no ip rip authentication string LINE",
1808 NO_STR
1809 IP_STR
1810 "Routing Information Protocol\n"
1811 "Authentication control\n"
1812 "Authentication string\n"
1813 "Authentication string\n")
1814
1815DEFUN (ip_rip_authentication_key_chain,
1816 ip_rip_authentication_key_chain_cmd,
1817 "ip rip authentication key-chain LINE",
1818 IP_STR
1819 "Routing Information Protocol\n"
1820 "Authentication control\n"
1821 "Authentication key-chain\n"
1822 "name of key-chain\n")
1823{
1824 struct interface *ifp;
1825 struct rip_interface *ri;
1826
1827 ifp = (struct interface *) vty->index;
1828 ri = ifp->info;
1829
1830 if (ri->auth_str)
1831 {
1832 vty_out (vty, "%% authentication string configuration exists%s",
1833 VTY_NEWLINE);
1834 return CMD_WARNING;
1835 }
1836
1837 if (ri->key_chain)
1838 free (ri->key_chain);
1839
1840 ri->key_chain = strdup (argv[0]);
1841
1842 return CMD_SUCCESS;
1843}
1844
1845DEFUN (no_ip_rip_authentication_key_chain,
1846 no_ip_rip_authentication_key_chain_cmd,
1847 "no ip rip authentication key-chain",
1848 NO_STR
1849 IP_STR
1850 "Routing Information Protocol\n"
1851 "Authentication control\n"
1852 "Authentication key-chain\n")
1853{
1854 struct interface *ifp;
1855 struct rip_interface *ri;
1856
1857 ifp = (struct interface *) vty->index;
1858 ri = ifp->info;
1859
1860 if (ri->key_chain)
1861 free (ri->key_chain);
1862
1863 ri->key_chain = NULL;
1864
1865 return CMD_SUCCESS;
1866}
1867
1868ALIAS (no_ip_rip_authentication_key_chain,
1869 no_ip_rip_authentication_key_chain2_cmd,
1870 "no ip rip authentication key-chain LINE",
1871 NO_STR
1872 IP_STR
1873 "Routing Information Protocol\n"
1874 "Authentication control\n"
1875 "Authentication key-chain\n"
1876 "name of key-chain\n")
1877
hasso16705132003-05-25 14:49:19 +00001878/* CHANGED: ip rip split-horizon
1879 Cisco and Zebra's command is
1880 ip split-horizon
1881 */
1882DEFUN (ip_rip_split_horizon,
1883 ip_rip_split_horizon_cmd,
1884 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001885 IP_STR
hasso16705132003-05-25 14:49:19 +00001886 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001887 "Perform split horizon\n")
1888{
1889 struct interface *ifp;
1890 struct rip_interface *ri;
1891
1892 ifp = vty->index;
1893 ri = ifp->info;
1894
hasso16705132003-05-25 14:49:19 +00001895 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001896 return CMD_SUCCESS;
1897}
1898
hasso16705132003-05-25 14:49:19 +00001899DEFUN (ip_rip_split_horizon_poisoned_reverse,
1900 ip_rip_split_horizon_poisoned_reverse_cmd,
1901 "ip rip split-horizon poisoned-reverse",
1902 IP_STR
1903 "Routing Information Protocol\n"
1904 "Perform split horizon\n"
1905 "With poisoned-reverse\n")
1906{
1907 struct interface *ifp;
1908 struct rip_interface *ri;
1909
1910 ifp = vty->index;
1911 ri = ifp->info;
1912
1913 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1914 return CMD_SUCCESS;
1915}
1916
1917/* CHANGED: no ip rip split-horizon
1918 Cisco and Zebra's command is
1919 no ip split-horizon
1920 */
1921DEFUN (no_ip_rip_split_horizon,
1922 no_ip_rip_split_horizon_cmd,
1923 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001924 NO_STR
1925 IP_STR
hasso16705132003-05-25 14:49:19 +00001926 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001927 "Perform split horizon\n")
1928{
1929 struct interface *ifp;
1930 struct rip_interface *ri;
1931
1932 ifp = vty->index;
1933 ri = ifp->info;
1934
hasso16705132003-05-25 14:49:19 +00001935 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001936 return CMD_SUCCESS;
1937}
1938
hasso16705132003-05-25 14:49:19 +00001939ALIAS (no_ip_rip_split_horizon,
1940 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1941 "no ip rip split-horizon poisoned-reverse",
1942 NO_STR
1943 IP_STR
1944 "Routing Information Protocol\n"
1945 "Perform split horizon\n"
1946 "With poisoned-reverse\n")
1947
paul718e3742002-12-13 20:15:29 +00001948DEFUN (rip_passive_interface,
1949 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001950 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001951 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001952 "Interface name\n"
1953 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001954{
hasso98b718a2004-10-11 12:57:57 +00001955 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001956
1957 if (!strcmp(ifname,"default")) {
1958 passive_default = 1;
1959 rip_passive_nondefault_clean();
1960 return CMD_SUCCESS;
1961 }
1962 if (passive_default)
1963 return rip_passive_nondefault_unset (vty, ifname);
1964 else
1965 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001966}
1967
1968DEFUN (no_rip_passive_interface,
1969 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001970 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001971 NO_STR
1972 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001973 "Interface name\n"
1974 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001975{
hasso98b718a2004-10-11 12:57:57 +00001976 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001977
1978 if (!strcmp(ifname,"default")) {
1979 passive_default = 0;
1980 rip_passive_nondefault_clean();
1981 return CMD_SUCCESS;
1982 }
1983 if (passive_default)
1984 return rip_passive_nondefault_set (vty, ifname);
1985 else
1986 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001987}
1988
1989/* Write rip configuration of each interface. */
1990int
1991rip_interface_config_write (struct vty *vty)
1992{
hasso52dc7ee2004-09-23 19:18:23 +00001993 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001994 struct interface *ifp;
1995
paul1eb8ef22005-04-07 07:30:20 +00001996 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001997 {
1998 struct rip_interface *ri;
1999
paul718e3742002-12-13 20:15:29 +00002000 ri = ifp->info;
2001
hasso16705132003-05-25 14:49:19 +00002002 /* Do not display the interface if there is no
2003 * configuration about it.
2004 **/
2005 if ((!ifp->desc) &&
2006 (ri->split_horizon == ri->split_horizon_default) &&
2007 (ri->ri_send == RI_RIP_UNSPEC) &&
2008 (ri->ri_receive == RI_RIP_UNSPEC) &&
2009 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00002010 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00002011 (!ri->auth_str) &&
2012 (!ri->key_chain) )
2013 continue;
2014
paul718e3742002-12-13 20:15:29 +00002015 vty_out (vty, "interface %s%s", ifp->name,
2016 VTY_NEWLINE);
2017
2018 if (ifp->desc)
2019 vty_out (vty, " description %s%s", ifp->desc,
2020 VTY_NEWLINE);
2021
2022 /* Split horizon. */
2023 if (ri->split_horizon != ri->split_horizon_default)
2024 {
hasso16705132003-05-25 14:49:19 +00002025 switch (ri->split_horizon) {
2026 case RIP_SPLIT_HORIZON:
2027 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
2028 break;
2029 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
2030 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
2031 VTY_NEWLINE);
2032 break;
2033 case RIP_NO_SPLIT_HORIZON:
2034 default:
2035 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2036 break;
2037 }
paul718e3742002-12-13 20:15:29 +00002038 }
2039
2040 /* RIP version setting. */
2041 if (ri->ri_send != RI_RIP_UNSPEC)
2042 vty_out (vty, " ip rip send version %s%s",
2043 lookup (ri_version_msg, ri->ri_send),
2044 VTY_NEWLINE);
2045
2046 if (ri->ri_receive != RI_RIP_UNSPEC)
2047 vty_out (vty, " ip rip receive version %s%s",
2048 lookup (ri_version_msg, ri->ri_receive),
2049 VTY_NEWLINE);
2050
2051 /* RIP authentication. */
2052#if 0
2053 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
2054 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2055 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
2056#endif /* 0 */
paulca5e5162004-06-06 22:06:33 +00002057
paul718e3742002-12-13 20:15:29 +00002058 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002059 {
2060 vty_out (vty, " ip rip authentication mode md5");
2061 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2062 vty_out (vty, " auth-length old-ripd");
2063 else
2064 vty_out (vty, " auth-length rfc");
2065 vty_out (vty, "%s", VTY_NEWLINE);
2066 }
paul718e3742002-12-13 20:15:29 +00002067
2068 if (ri->auth_str)
2069 vty_out (vty, " ip rip authentication string %s%s",
2070 ri->auth_str, VTY_NEWLINE);
2071
2072 if (ri->key_chain)
2073 vty_out (vty, " ip rip authentication key-chain %s%s",
2074 ri->key_chain, VTY_NEWLINE);
2075
2076 vty_out (vty, "!%s", VTY_NEWLINE);
2077 }
2078 return 0;
2079}
2080
2081int
2082config_write_rip_network (struct vty *vty, int config_mode)
2083{
hasso8a676be2004-10-08 06:36:38 +00002084 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002085 char *ifname;
2086 struct route_node *node;
2087
2088 /* Network type RIP enable interface statement. */
2089 for (node = route_top (rip_enable_network); node; node = route_next (node))
2090 if (node->info)
2091 vty_out (vty, "%s%s/%d%s",
2092 config_mode ? " network " : " ",
2093 inet_ntoa (node->p.u.prefix4),
2094 node->p.prefixlen,
2095 VTY_NEWLINE);
2096
2097 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002098 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002099 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2100 vty_out (vty, "%s%s%s",
2101 config_mode ? " network " : " ",
2102 ifname,
2103 VTY_NEWLINE);
2104
2105 /* RIP neighbors listing. */
2106 for (node = route_top (rip->neighbor); node; node = route_next (node))
2107 if (node->info)
2108 vty_out (vty, "%s%s%s",
2109 config_mode ? " neighbor " : " ",
2110 inet_ntoa (node->p.u.prefix4),
2111 VTY_NEWLINE);
2112
2113 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002114 if (config_mode) {
2115 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002116 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002117 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002118 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2119 vty_out (vty, " %spassive-interface %s%s",
2120 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2121 }
paul718e3742002-12-13 20:15:29 +00002122
2123 return 0;
2124}
2125
2126struct cmd_node interface_node =
2127{
2128 INTERFACE_NODE,
2129 "%s(config-if)# ",
2130 1,
2131};
2132
2133/* Called when interface structure allocated. */
2134int
2135rip_interface_new_hook (struct interface *ifp)
2136{
2137 ifp->info = rip_interface_new ();
2138 return 0;
2139}
2140
2141/* Called when interface structure deleted. */
2142int
2143rip_interface_delete_hook (struct interface *ifp)
2144{
2145 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002146 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002147 return 0;
2148}
2149
2150/* Allocate and initialize interface vector. */
2151void
2152rip_if_init ()
2153{
2154 /* Default initial size of interface vector. */
2155 if_init();
2156 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2157 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2158
2159 /* RIP network init. */
2160 rip_enable_interface = vector_init (1);
2161 rip_enable_network = route_table_init ();
2162
2163 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002164 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002165
2166 /* Install interface node. */
2167 install_node (&interface_node, rip_interface_config_write);
2168
2169 /* Install commands. */
2170 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002171 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002172 install_default (INTERFACE_NODE);
2173 install_element (INTERFACE_NODE, &interface_desc_cmd);
2174 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2175 install_element (RIP_NODE, &rip_network_cmd);
2176 install_element (RIP_NODE, &no_rip_network_cmd);
2177 install_element (RIP_NODE, &rip_neighbor_cmd);
2178 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2179
2180 install_element (RIP_NODE, &rip_passive_interface_cmd);
2181 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2182
2183 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2184 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2185 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2186 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2187 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2188
2189 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2190 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2191 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2192 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2193 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2194
2195 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002196 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002197 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2198 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002199 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002200
2201 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2202 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2203 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2204
2205 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2206 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2207 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2208
hasso16705132003-05-25 14:49:19 +00002209 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2210 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2211 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2212 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002213}