blob: 0e267f98badecc4064f40887cad9d9b4f0d759a2 [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);
ajsd4e47282005-05-11 15:56:21 +0000550
551 /* Check for a passive interface */
552 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000553
554 /* Apply distribute list to the all interface. */
555 rip_distribute_update_interface (ifp);
556
557 /* rip_request_neighbor_all (); */
558
hasso16705132003-05-25 14:49:19 +0000559 /* Check interface routemap. */
560 rip_if_rmap_update_interface (ifp);
561
paul718e3742002-12-13 20:15:29 +0000562 return 0;
563}
564
565int
566rip_interface_delete (int command, struct zclient *zclient,
567 zebra_size_t length)
568{
569 struct interface *ifp;
570 struct stream *s;
571
572
573 s = zclient->ibuf;
574 /* zebra_interface_state_read() updates interface structure in iflist */
575 ifp = zebra_interface_state_read(s);
576
577 if (ifp == NULL)
578 return 0;
579
580 if (if_is_up (ifp)) {
581 rip_if_down(ifp);
582 }
583
584 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
585 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
586
587 /* To support pseudo interface do not free interface structure. */
588 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000589 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000590
591 return 0;
592}
593
594void
595rip_interface_clean ()
596{
hasso52dc7ee2004-09-23 19:18:23 +0000597 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000598 struct interface *ifp;
599 struct rip_interface *ri;
600
paul1eb8ef22005-04-07 07:30:20 +0000601 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000602 {
paul718e3742002-12-13 20:15:29 +0000603 ri = ifp->info;
604
605 ri->enable_network = 0;
606 ri->enable_interface = 0;
607 ri->running = 0;
608
609 if (ri->t_wakeup)
610 {
611 thread_cancel (ri->t_wakeup);
612 ri->t_wakeup = NULL;
613 }
614 }
615}
616
617void
618rip_interface_reset ()
619{
hasso52dc7ee2004-09-23 19:18:23 +0000620 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000621 struct interface *ifp;
622 struct rip_interface *ri;
623
paul1eb8ef22005-04-07 07:30:20 +0000624 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000625 {
paul718e3742002-12-13 20:15:29 +0000626 ri = ifp->info;
627
628 ri->enable_network = 0;
629 ri->enable_interface = 0;
630 ri->running = 0;
631
632 ri->ri_send = RI_RIP_UNSPEC;
633 ri->ri_receive = RI_RIP_UNSPEC;
634
635 /* ri->auth_type = RIP_NO_AUTH; */
636 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
637
638 if (ri->auth_str)
639 {
640 free (ri->auth_str);
641 ri->auth_str = NULL;
642 }
643 if (ri->key_chain)
644 {
645 free (ri->key_chain);
646 ri->key_chain = NULL;
647 }
648
hasso16705132003-05-25 14:49:19 +0000649 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
650 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000651
652 ri->list[RIP_FILTER_IN] = NULL;
653 ri->list[RIP_FILTER_OUT] = NULL;
654
655 ri->prefix[RIP_FILTER_IN] = NULL;
656 ri->prefix[RIP_FILTER_OUT] = NULL;
657
658 if (ri->t_wakeup)
659 {
660 thread_cancel (ri->t_wakeup);
661 ri->t_wakeup = NULL;
662 }
663
664 ri->recv_badpackets = 0;
665 ri->recv_badroutes = 0;
666 ri->sent_updates = 0;
667
668 ri->passive = 0;
669 }
670}
671
672int
673rip_if_down(struct interface *ifp)
674{
675 struct route_node *rp;
676 struct rip_info *rinfo;
677 struct rip_interface *ri = NULL;
678 if (rip)
679 {
680 for (rp = route_top (rip->table); rp; rp = route_next (rp))
681 if ((rinfo = rp->info) != NULL)
682 {
683 /* Routes got through this interface. */
684 if (rinfo->ifindex == ifp->ifindex &&
685 rinfo->type == ZEBRA_ROUTE_RIP &&
686 rinfo->sub_type == RIP_ROUTE_RTE)
687 {
688 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
689 &rinfo->nexthop,
690 rinfo->ifindex);
691
692 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
693 (struct prefix_ipv4 *)&rp->p,
694 rinfo->ifindex);
695 }
696 else
697 {
698 /* All redistributed routes but static and system */
699 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000700 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000701 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
702 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
703 (struct prefix_ipv4 *)&rp->p,
704 rinfo->ifindex);
705 }
706 }
707 }
708
709 ri = ifp->info;
710
711 if (ri->running)
712 {
713 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000714 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000715
716 /* Leave from multicast group. */
717 rip_multicast_leave (ifp, rip->sock);
718
719 ri->running = 0;
720 }
721
722 return 0;
723}
724
725/* Needed for stop RIP process. */
726void
727rip_if_down_all ()
728{
729 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000730 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000731
paul1eb8ef22005-04-07 07:30:20 +0000732 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
733 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000734}
735
hasso16705132003-05-25 14:49:19 +0000736static void
737rip_apply_address_add (struct connected *ifc) {
738 struct prefix_ipv4 address;
739 struct prefix *p;
740
741 if (!rip)
742 return;
743
744 if (! if_is_up(ifc->ifp))
745 return;
746
747 p = ifc->address;
748
749 memset (&address, 0, sizeof (address));
750 address.family = p->family;
751 address.prefix = p->u.prefix4;
752 address.prefixlen = p->prefixlen;
753 apply_mask_ipv4(&address);
754
755 /* Check if this interface is RIP enabled or not
756 or Check if this address's prefix is RIP enabled */
757 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
758 (rip_enable_network_lookup2(ifc) >= 0))
759 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
760 &address, ifc->ifp->ifindex, NULL);
761
762}
763
paul718e3742002-12-13 20:15:29 +0000764int
765rip_interface_address_add (int command, struct zclient *zclient,
766 zebra_size_t length)
767{
768 struct connected *ifc;
769 struct prefix *p;
770
paul0a589352004-05-08 11:48:26 +0000771 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
772 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000773
774 if (ifc == NULL)
775 return 0;
776
777 p = ifc->address;
778
779 if (p->family == AF_INET)
780 {
781 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000782 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000783 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000784
paul878ef2e2003-09-23 23:41:50 +0000785 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000786 /* Check if this prefix needs to be redistributed */
787 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000788
789#ifdef HAVE_SNMP
790 rip_ifaddr_add (ifc->ifp, ifc);
791#endif /* HAVE_SNMP */
792 }
793
794 return 0;
795}
796
hasso16705132003-05-25 14:49:19 +0000797static void
798rip_apply_address_del (struct connected *ifc) {
799 struct prefix_ipv4 address;
800 struct prefix *p;
801
802 if (!rip)
803 return;
804
805 if (! if_is_up(ifc->ifp))
806 return;
807
808 p = ifc->address;
809
810 memset (&address, 0, sizeof (address));
811 address.family = p->family;
812 address.prefix = p->u.prefix4;
813 address.prefixlen = p->prefixlen;
814 apply_mask_ipv4(&address);
815
816 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
817 &address, ifc->ifp->ifindex);
818}
819
paul718e3742002-12-13 20:15:29 +0000820int
821rip_interface_address_delete (int command, struct zclient *zclient,
822 zebra_size_t length)
823{
824 struct connected *ifc;
825 struct prefix *p;
826
paul0a589352004-05-08 11:48:26 +0000827 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
828 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000829
830 if (ifc)
831 {
832 p = ifc->address;
833 if (p->family == AF_INET)
834 {
835 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000836 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000837 inet_ntoa (p->u.prefix4), p->prefixlen);
838
839#ifdef HAVE_SNMP
840 rip_ifaddr_delete (ifc->ifp, ifc);
841#endif /* HAVE_SNMP */
842
hasso16705132003-05-25 14:49:19 +0000843 /* Chech wether this prefix needs to be removed */
844 rip_apply_address_del(ifc);
845
paul718e3742002-12-13 20:15:29 +0000846 }
847
848 connected_free (ifc);
849
850 }
851
852 return 0;
853}
854
855/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000856/* Check wether the interface has at least a connected prefix that
857 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000858int
hasso16705132003-05-25 14:49:19 +0000859rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000860{
paul1eb8ef22005-04-07 07:30:20 +0000861 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000862 struct connected *connected;
863 struct prefix_ipv4 address;
864
paul1eb8ef22005-04-07 07:30:20 +0000865 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
866 {
867 struct prefix *p;
868 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000869
paul1eb8ef22005-04-07 07:30:20 +0000870 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000871
paul1eb8ef22005-04-07 07:30:20 +0000872 if (p->family == AF_INET)
873 {
874 address.family = AF_INET;
875 address.prefix = p->u.prefix4;
876 address.prefixlen = IPV4_MAX_BITLEN;
877
878 node = route_node_match (rip_enable_network,
879 (struct prefix *)&address);
880 if (node)
881 {
882 route_unlock_node (node);
883 return 1;
884 }
885 }
886 }
paul718e3742002-12-13 20:15:29 +0000887 return -1;
888}
889
hasso16705132003-05-25 14:49:19 +0000890/* Check wether connected is within the ripng_enable_network table. */
891int
892rip_enable_network_lookup2 (struct connected *connected)
893{
894 struct prefix_ipv4 address;
895 struct prefix *p;
896
897 p = connected->address;
898
899 if (p->family == AF_INET) {
900 struct route_node *node;
901
902 address.family = p->family;
903 address.prefix = p->u.prefix4;
904 address.prefixlen = IPV4_MAX_BITLEN;
905
906 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
907 node = route_node_match (rip_enable_network,
908 (struct prefix *)&address);
909
910 if (node) {
911 route_unlock_node (node);
912 return 1;
913 }
914 }
915
916 return -1;
917}
paul718e3742002-12-13 20:15:29 +0000918/* Add RIP enable network. */
919int
920rip_enable_network_add (struct prefix *p)
921{
922 struct route_node *node;
923
924 node = route_node_get (rip_enable_network, p);
925
926 if (node->info)
927 {
928 route_unlock_node (node);
929 return -1;
930 }
931 else
hasso8a676be2004-10-08 06:36:38 +0000932 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000933
hasso16705132003-05-25 14:49:19 +0000934 /* XXX: One should find a better solution than a generic one */
935 rip_enable_apply_all();
936
paul718e3742002-12-13 20:15:29 +0000937 return 1;
938}
939
940/* Delete RIP enable network. */
941int
942rip_enable_network_delete (struct prefix *p)
943{
944 struct route_node *node;
945
946 node = route_node_lookup (rip_enable_network, p);
947 if (node)
948 {
949 node->info = NULL;
950
951 /* Unlock info lock. */
952 route_unlock_node (node);
953
954 /* Unlock lookup lock. */
955 route_unlock_node (node);
956
hasso16705132003-05-25 14:49:19 +0000957 /* XXX: One should find a better solution than a generic one */
958 rip_enable_apply_all ();
959
paul718e3742002-12-13 20:15:29 +0000960 return 1;
961 }
962 return -1;
963}
964
965/* Check interface is enabled by ifname statement. */
966int
hasso98b718a2004-10-11 12:57:57 +0000967rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000968{
hasso8a676be2004-10-08 06:36:38 +0000969 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000970 char *str;
971
paul55468c82005-03-14 20:19:01 +0000972 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000973 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
974 if (strcmp (str, ifname) == 0)
975 return i;
976 return -1;
977}
978
979/* Add interface to rip_enable_if. */
980int
hasso98b718a2004-10-11 12:57:57 +0000981rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000982{
983 int ret;
984
985 ret = rip_enable_if_lookup (ifname);
986 if (ret >= 0)
987 return -1;
988
989 vector_set (rip_enable_interface, strdup (ifname));
990
hasso16705132003-05-25 14:49:19 +0000991 rip_enable_apply_all(); /* TODOVJ */
992
paul718e3742002-12-13 20:15:29 +0000993 return 1;
994}
995
996/* Delete interface from rip_enable_if. */
997int
hasso98b718a2004-10-11 12:57:57 +0000998rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000999{
1000 int index;
1001 char *str;
1002
1003 index = rip_enable_if_lookup (ifname);
1004 if (index < 0)
1005 return -1;
1006
1007 str = vector_slot (rip_enable_interface, index);
1008 free (str);
1009 vector_unset (rip_enable_interface, index);
1010
hasso16705132003-05-25 14:49:19 +00001011 rip_enable_apply_all(); /* TODOVJ */
1012
paul718e3742002-12-13 20:15:29 +00001013 return 1;
1014}
1015
1016/* Join to multicast group and send request to the interface. */
1017int
1018rip_interface_wakeup (struct thread *t)
1019{
1020 struct interface *ifp;
1021 struct rip_interface *ri;
1022
1023 /* Get interface. */
1024 ifp = THREAD_ARG (t);
1025
1026 ri = ifp->info;
1027 ri->t_wakeup = NULL;
1028
1029 /* Join to multicast group. */
1030 if (rip_multicast_join (ifp, rip->sock) < 0)
1031 {
1032 zlog_err ("multicast join failed, interface %s not running", ifp->name);
1033 return 0;
1034 }
1035
1036 /* Set running flag. */
1037 ri->running = 1;
1038
1039 /* Send RIP request to the interface. */
1040 rip_request_interface (ifp);
1041
1042 return 0;
1043}
1044
1045int rip_redistribute_check (int);
1046
1047void
1048rip_connect_set (struct interface *ifp, int set)
1049{
paul1eb8ef22005-04-07 07:30:20 +00001050 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001051 struct connected *connected;
1052 struct prefix_ipv4 address;
1053
paul1eb8ef22005-04-07 07:30:20 +00001054 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
1055 {
1056 struct prefix *p;
1057 p = connected->address;
paul718e3742002-12-13 20:15:29 +00001058
paul1eb8ef22005-04-07 07:30:20 +00001059 if (p->family != AF_INET)
1060 continue;
paul718e3742002-12-13 20:15:29 +00001061
paul1eb8ef22005-04-07 07:30:20 +00001062 address.family = AF_INET;
1063 address.prefix = p->u.prefix4;
1064 address.prefixlen = p->prefixlen;
1065 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +00001066
paul1eb8ef22005-04-07 07:30:20 +00001067 if (set) {
1068 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1069 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1070 (rip_enable_network_lookup2(connected) >= 0))
1071 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1072 &address, connected->ifp->ifindex, NULL);
1073 } else
1074 {
1075 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1076 &address, connected->ifp->ifindex);
1077 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1078 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1079 &address, connected->ifp->ifindex, NULL);
1080 }
1081 }
paul718e3742002-12-13 20:15:29 +00001082}
1083
1084/* Update interface status. */
1085void
1086rip_enable_apply (struct interface *ifp)
1087{
1088 int ret;
1089 struct rip_interface *ri = NULL;
1090
1091 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001092 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001093 return;
1094
1095 ri = ifp->info;
1096
1097 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001098 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001099
1100 /* If the interface is matched. */
1101 if (ret > 0)
1102 ri->enable_network = 1;
1103 else
1104 ri->enable_network = 0;
1105
1106 /* Check interface name configuration. */
1107 ret = rip_enable_if_lookup (ifp->name);
1108 if (ret >= 0)
1109 ri->enable_interface = 1;
1110 else
1111 ri->enable_interface = 0;
1112
1113 /* any interface MUST have an IPv4 address */
1114 if ( ! rip_if_ipv4_address_check (ifp) )
1115 {
1116 ri->enable_network = 0;
1117 ri->enable_interface = 0;
1118 }
1119
1120 /* Update running status of the interface. */
1121 if (ri->enable_network || ri->enable_interface)
1122 {
paul718e3742002-12-13 20:15:29 +00001123 {
1124 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001125 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001126
1127 /* Add interface wake up thread. */
1128 if (! ri->t_wakeup)
1129 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1130 ifp, 1);
1131 rip_connect_set (ifp, 1);
1132 }
1133 }
1134 else
1135 {
1136 if (ri->running)
1137 {
hasso16705132003-05-25 14:49:19 +00001138 /* Might as well clean up the route table as well
1139 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1140 **/
paul718e3742002-12-13 20:15:29 +00001141 rip_if_down(ifp);
1142
paul718e3742002-12-13 20:15:29 +00001143 rip_connect_set (ifp, 0);
1144 }
1145 }
1146}
1147
1148/* Apply network configuration to all interface. */
1149void
1150rip_enable_apply_all ()
1151{
1152 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001153 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001154
1155 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001156 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1157 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001158}
1159
1160int
1161rip_neighbor_lookup (struct sockaddr_in *from)
1162{
1163 struct prefix_ipv4 p;
1164 struct route_node *node;
1165
1166 memset (&p, 0, sizeof (struct prefix_ipv4));
1167 p.family = AF_INET;
1168 p.prefix = from->sin_addr;
1169 p.prefixlen = IPV4_MAX_BITLEN;
1170
1171 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1172 if (node)
1173 {
1174 route_unlock_node (node);
1175 return 1;
1176 }
1177 return 0;
1178}
1179
1180/* Add new RIP neighbor to the neighbor tree. */
1181int
1182rip_neighbor_add (struct prefix_ipv4 *p)
1183{
1184 struct route_node *node;
1185
1186 node = route_node_get (rip->neighbor, (struct prefix *) p);
1187
1188 if (node->info)
1189 return -1;
1190
1191 node->info = rip->neighbor;
1192
1193 return 0;
1194}
1195
1196/* Delete RIP neighbor from the neighbor tree. */
1197int
1198rip_neighbor_delete (struct prefix_ipv4 *p)
1199{
1200 struct route_node *node;
1201
1202 /* Lock for look up. */
1203 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1204 if (! node)
1205 return -1;
1206
1207 node->info = NULL;
1208
1209 /* Unlock lookup lock. */
1210 route_unlock_node (node);
1211
1212 /* Unlock real neighbor information lock. */
1213 route_unlock_node (node);
1214
1215 return 0;
1216}
1217
1218/* Clear all network and neighbor configuration. */
1219void
1220rip_clean_network ()
1221{
hasso8a676be2004-10-08 06:36:38 +00001222 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001223 char *str;
1224 struct route_node *rn;
1225
1226 /* rip_enable_network. */
1227 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1228 if (rn->info)
1229 {
1230 rn->info = NULL;
1231 route_unlock_node (rn);
1232 }
1233
1234 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001235 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001236 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1237 {
1238 free (str);
1239 vector_slot (rip_enable_interface, i) = NULL;
1240 }
1241}
1242
1243/* Utility function for looking up passive interface settings. */
1244int
hasso98b718a2004-10-11 12:57:57 +00001245rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001246{
hasso8a676be2004-10-08 06:36:38 +00001247 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001248 char *str;
1249
paul55468c82005-03-14 20:19:01 +00001250 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001251 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001252 if (strcmp (str, ifname) == 0)
1253 return i;
1254 return -1;
1255}
1256
1257void
1258rip_passive_interface_apply (struct interface *ifp)
1259{
paul718e3742002-12-13 20:15:29 +00001260 struct rip_interface *ri;
1261
1262 ri = ifp->info;
1263
paul4aaff3f2003-06-07 01:04:45 +00001264 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1265 passive_default : !passive_default);
1266
1267 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001268 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001269}
1270
1271void
1272rip_passive_interface_apply_all ()
1273{
1274 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001275 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001276
paul1eb8ef22005-04-07 07:30:20 +00001277 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1278 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001279}
1280
1281/* Passive interface. */
1282int
hasso98b718a2004-10-11 12:57:57 +00001283rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001284{
paul4aaff3f2003-06-07 01:04:45 +00001285 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001286 return CMD_WARNING;
1287
paul4aaff3f2003-06-07 01:04:45 +00001288 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001289
1290 rip_passive_interface_apply_all ();
1291
1292 return CMD_SUCCESS;
1293}
1294
1295int
hasso98b718a2004-10-11 12:57:57 +00001296rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001297{
1298 int i;
1299 char *str;
1300
paul4aaff3f2003-06-07 01:04:45 +00001301 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001302 if (i < 0)
1303 return CMD_WARNING;
1304
paul4aaff3f2003-06-07 01:04:45 +00001305 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001306 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001307 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001308
1309 rip_passive_interface_apply_all ();
1310
1311 return CMD_SUCCESS;
1312}
1313
1314/* Free all configured RIP passive-interface settings. */
1315void
paul4aaff3f2003-06-07 01:04:45 +00001316rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001317{
hasso8a676be2004-10-08 06:36:38 +00001318 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001319 char *str;
1320
paul55468c82005-03-14 20:19:01 +00001321 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001322 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001323 {
1324 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001325 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001326 }
1327 rip_passive_interface_apply_all ();
1328}
1329
1330/* RIP enable network or interface configuration. */
1331DEFUN (rip_network,
1332 rip_network_cmd,
1333 "network (A.B.C.D/M|WORD)",
1334 "Enable routing on an IP network\n"
1335 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1336 "Interface name\n")
1337{
1338 int ret;
1339 struct prefix_ipv4 p;
1340
1341 ret = str2prefix_ipv4 (argv[0], &p);
1342
1343 if (ret)
1344 ret = rip_enable_network_add ((struct prefix *) &p);
1345 else
1346 ret = rip_enable_if_add (argv[0]);
1347
1348 if (ret < 0)
1349 {
1350 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1351 VTY_NEWLINE);
1352 return CMD_WARNING;
1353 }
1354
paul718e3742002-12-13 20:15:29 +00001355 return CMD_SUCCESS;
1356}
1357
1358/* RIP enable network or interface configuration. */
1359DEFUN (no_rip_network,
1360 no_rip_network_cmd,
1361 "no network (A.B.C.D/M|WORD)",
1362 NO_STR
1363 "Enable routing on an IP network\n"
1364 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1365 "Interface name\n")
1366{
1367 int ret;
1368 struct prefix_ipv4 p;
1369
1370 ret = str2prefix_ipv4 (argv[0], &p);
1371
1372 if (ret)
1373 ret = rip_enable_network_delete ((struct prefix *) &p);
1374 else
1375 ret = rip_enable_if_delete (argv[0]);
1376
1377 if (ret < 0)
1378 {
1379 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1380 VTY_NEWLINE);
1381 return CMD_WARNING;
1382 }
1383
paul718e3742002-12-13 20:15:29 +00001384 return CMD_SUCCESS;
1385}
1386
1387/* RIP neighbor configuration set. */
1388DEFUN (rip_neighbor,
1389 rip_neighbor_cmd,
1390 "neighbor A.B.C.D",
1391 "Specify a neighbor router\n"
1392 "Neighbor address\n")
1393{
1394 int ret;
1395 struct prefix_ipv4 p;
1396
1397 ret = str2prefix_ipv4 (argv[0], &p);
1398
1399 if (ret <= 0)
1400 {
1401 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1402 return CMD_WARNING;
1403 }
1404
1405 rip_neighbor_add (&p);
1406
1407 return CMD_SUCCESS;
1408}
1409
1410/* RIP neighbor configuration unset. */
1411DEFUN (no_rip_neighbor,
1412 no_rip_neighbor_cmd,
1413 "no neighbor A.B.C.D",
1414 NO_STR
1415 "Specify a neighbor router\n"
1416 "Neighbor address\n")
1417{
1418 int ret;
1419 struct prefix_ipv4 p;
1420
1421 ret = str2prefix_ipv4 (argv[0], &p);
1422
1423 if (ret <= 0)
1424 {
1425 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1426 return CMD_WARNING;
1427 }
1428
1429 rip_neighbor_delete (&p);
1430
1431 return CMD_SUCCESS;
1432}
1433
1434DEFUN (ip_rip_receive_version,
1435 ip_rip_receive_version_cmd,
1436 "ip rip receive version (1|2)",
1437 IP_STR
1438 "Routing Information Protocol\n"
1439 "Advertisement reception\n"
1440 "Version control\n"
1441 "RIP version 1\n"
1442 "RIP version 2\n")
1443{
1444 struct interface *ifp;
1445 struct rip_interface *ri;
1446
1447 ifp = (struct interface *)vty->index;
1448 ri = ifp->info;
1449
1450 /* Version 1. */
1451 if (atoi (argv[0]) == 1)
1452 {
1453 ri->ri_receive = RI_RIP_VERSION_1;
1454 return CMD_SUCCESS;
1455 }
1456 if (atoi (argv[0]) == 2)
1457 {
1458 ri->ri_receive = RI_RIP_VERSION_2;
1459 return CMD_SUCCESS;
1460 }
1461 return CMD_WARNING;
1462}
1463
1464DEFUN (ip_rip_receive_version_1,
1465 ip_rip_receive_version_1_cmd,
1466 "ip rip receive version 1 2",
1467 IP_STR
1468 "Routing Information Protocol\n"
1469 "Advertisement reception\n"
1470 "Version control\n"
1471 "RIP version 1\n"
1472 "RIP version 2\n")
1473{
1474 struct interface *ifp;
1475 struct rip_interface *ri;
1476
1477 ifp = (struct interface *)vty->index;
1478 ri = ifp->info;
1479
1480 /* Version 1 and 2. */
1481 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1482 return CMD_SUCCESS;
1483}
1484
1485DEFUN (ip_rip_receive_version_2,
1486 ip_rip_receive_version_2_cmd,
1487 "ip rip receive version 2 1",
1488 IP_STR
1489 "Routing Information Protocol\n"
1490 "Advertisement reception\n"
1491 "Version control\n"
1492 "RIP version 2\n"
1493 "RIP version 1\n")
1494{
1495 struct interface *ifp;
1496 struct rip_interface *ri;
1497
1498 ifp = (struct interface *)vty->index;
1499 ri = ifp->info;
1500
1501 /* Version 1 and 2. */
1502 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1503 return CMD_SUCCESS;
1504}
1505
1506DEFUN (no_ip_rip_receive_version,
1507 no_ip_rip_receive_version_cmd,
1508 "no ip rip receive version",
1509 NO_STR
1510 IP_STR
1511 "Routing Information Protocol\n"
1512 "Advertisement reception\n"
1513 "Version control\n")
1514{
1515 struct interface *ifp;
1516 struct rip_interface *ri;
1517
1518 ifp = (struct interface *)vty->index;
1519 ri = ifp->info;
1520
1521 ri->ri_receive = RI_RIP_UNSPEC;
1522 return CMD_SUCCESS;
1523}
1524
1525ALIAS (no_ip_rip_receive_version,
1526 no_ip_rip_receive_version_num_cmd,
1527 "no ip rip receive version (1|2)",
1528 NO_STR
1529 IP_STR
1530 "Routing Information Protocol\n"
1531 "Advertisement reception\n"
1532 "Version control\n"
1533 "Version 1\n"
1534 "Version 2\n")
1535
1536DEFUN (ip_rip_send_version,
1537 ip_rip_send_version_cmd,
1538 "ip rip send version (1|2)",
1539 IP_STR
1540 "Routing Information Protocol\n"
1541 "Advertisement transmission\n"
1542 "Version control\n"
1543 "RIP version 1\n"
1544 "RIP version 2\n")
1545{
1546 struct interface *ifp;
1547 struct rip_interface *ri;
1548
1549 ifp = (struct interface *)vty->index;
1550 ri = ifp->info;
1551
1552 /* Version 1. */
1553 if (atoi (argv[0]) == 1)
1554 {
1555 ri->ri_send = RI_RIP_VERSION_1;
1556 return CMD_SUCCESS;
1557 }
1558 if (atoi (argv[0]) == 2)
1559 {
1560 ri->ri_send = RI_RIP_VERSION_2;
1561 return CMD_SUCCESS;
1562 }
1563 return CMD_WARNING;
1564}
1565
1566DEFUN (ip_rip_send_version_1,
1567 ip_rip_send_version_1_cmd,
1568 "ip rip send version 1 2",
1569 IP_STR
1570 "Routing Information Protocol\n"
1571 "Advertisement transmission\n"
1572 "Version control\n"
1573 "RIP version 1\n"
1574 "RIP version 2\n")
1575{
1576 struct interface *ifp;
1577 struct rip_interface *ri;
1578
1579 ifp = (struct interface *)vty->index;
1580 ri = ifp->info;
1581
1582 /* Version 1 and 2. */
1583 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1584 return CMD_SUCCESS;
1585}
1586
1587DEFUN (ip_rip_send_version_2,
1588 ip_rip_send_version_2_cmd,
1589 "ip rip send version 2 1",
1590 IP_STR
1591 "Routing Information Protocol\n"
1592 "Advertisement transmission\n"
1593 "Version control\n"
1594 "RIP version 2\n"
1595 "RIP version 1\n")
1596{
1597 struct interface *ifp;
1598 struct rip_interface *ri;
1599
1600 ifp = (struct interface *)vty->index;
1601 ri = ifp->info;
1602
1603 /* Version 1 and 2. */
1604 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1605 return CMD_SUCCESS;
1606}
1607
1608DEFUN (no_ip_rip_send_version,
1609 no_ip_rip_send_version_cmd,
1610 "no ip rip send version",
1611 NO_STR
1612 IP_STR
1613 "Routing Information Protocol\n"
1614 "Advertisement transmission\n"
1615 "Version control\n")
1616{
1617 struct interface *ifp;
1618 struct rip_interface *ri;
1619
1620 ifp = (struct interface *)vty->index;
1621 ri = ifp->info;
1622
1623 ri->ri_send = RI_RIP_UNSPEC;
1624 return CMD_SUCCESS;
1625}
1626
1627ALIAS (no_ip_rip_send_version,
1628 no_ip_rip_send_version_num_cmd,
1629 "no ip rip send version (1|2)",
1630 NO_STR
1631 IP_STR
1632 "Routing Information Protocol\n"
1633 "Advertisement transmission\n"
1634 "Version control\n"
1635 "Version 1\n"
1636 "Version 2\n")
1637
1638DEFUN (ip_rip_authentication_mode,
1639 ip_rip_authentication_mode_cmd,
1640 "ip rip authentication mode (md5|text)",
1641 IP_STR
1642 "Routing Information Protocol\n"
1643 "Authentication control\n"
1644 "Authentication mode\n"
1645 "Keyed message digest\n"
1646 "Clear text authentication\n")
1647{
1648 struct interface *ifp;
1649 struct rip_interface *ri;
1650
1651 ifp = (struct interface *)vty->index;
1652 ri = ifp->info;
1653
paulca5e5162004-06-06 22:06:33 +00001654 if ( (argc < 1) || (argc > 2) )
1655 {
1656 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1657 return CMD_WARNING;
1658 }
1659
paul718e3742002-12-13 20:15:29 +00001660 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1661 ri->auth_type = RIP_AUTH_MD5;
1662 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1663 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1664 else
1665 {
1666 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1667 return CMD_WARNING;
1668 }
1669
paulca5e5162004-06-06 22:06:33 +00001670 if (argc == 1)
1671 return CMD_SUCCESS;
1672
1673 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1674 {
1675 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1676 return CMD_WARNING;
1677}
1678
1679 if (strncmp ("r", argv[1], 1) == 0)
1680 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1681 else if (strncmp ("o", argv[1], 1) == 0)
1682 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1683 else
1684 return CMD_WARNING;
1685
paul718e3742002-12-13 20:15:29 +00001686 return CMD_SUCCESS;
1687}
1688
paulca5e5162004-06-06 22:06:33 +00001689ALIAS (ip_rip_authentication_mode,
1690 ip_rip_authentication_mode_authlen_cmd,
1691 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1692 IP_STR
1693 "Routing Information Protocol\n"
1694 "Authentication control\n"
1695 "Authentication mode\n"
1696 "Keyed message digest\n"
1697 "Clear text authentication\n"
1698 "MD5 authentication data length\n"
1699 "RFC compatible\n"
1700 "Old ripd compatible\n")
1701
paul718e3742002-12-13 20:15:29 +00001702DEFUN (no_ip_rip_authentication_mode,
1703 no_ip_rip_authentication_mode_cmd,
1704 "no ip rip authentication mode",
1705 NO_STR
1706 IP_STR
1707 "Routing Information Protocol\n"
1708 "Authentication control\n"
1709 "Authentication mode\n")
1710{
1711 struct interface *ifp;
1712 struct rip_interface *ri;
1713
1714 ifp = (struct interface *)vty->index;
1715 ri = ifp->info;
1716
1717 /* ri->auth_type = RIP_NO_AUTH; */
1718 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paulca5e5162004-06-06 22:06:33 +00001719 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001720
1721 return CMD_SUCCESS;
1722}
1723
1724ALIAS (no_ip_rip_authentication_mode,
1725 no_ip_rip_authentication_mode_type_cmd,
1726 "no ip rip authentication mode (md5|text)",
1727 NO_STR
1728 IP_STR
1729 "Routing Information Protocol\n"
1730 "Authentication control\n"
1731 "Authentication mode\n"
1732 "Keyed message digest\n"
1733 "Clear text authentication\n")
1734
paulca5e5162004-06-06 22:06:33 +00001735ALIAS (no_ip_rip_authentication_mode,
1736 no_ip_rip_authentication_mode_type_authlen_cmd,
1737 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1738 NO_STR
1739 IP_STR
1740 "Routing Information Protocol\n"
1741 "Authentication control\n"
1742 "Authentication mode\n"
1743 "Keyed message digest\n"
1744 "Clear text authentication\n"
1745 "MD5 authentication data length\n"
1746 "RFC compatible\n"
1747 "Old ripd compatible\n")
1748
paul718e3742002-12-13 20:15:29 +00001749DEFUN (ip_rip_authentication_string,
1750 ip_rip_authentication_string_cmd,
1751 "ip rip authentication string LINE",
1752 IP_STR
1753 "Routing Information Protocol\n"
1754 "Authentication control\n"
1755 "Authentication string\n"
1756 "Authentication string\n")
1757{
1758 struct interface *ifp;
1759 struct rip_interface *ri;
1760
1761 ifp = (struct interface *)vty->index;
1762 ri = ifp->info;
1763
1764 if (strlen (argv[0]) > 16)
1765 {
1766 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1767 VTY_NEWLINE);
1768 return CMD_WARNING;
1769 }
1770
1771 if (ri->key_chain)
1772 {
1773 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1774 return CMD_WARNING;
1775 }
1776
1777 if (ri->auth_str)
1778 free (ri->auth_str);
1779
1780 ri->auth_str = strdup (argv[0]);
1781
1782 return CMD_SUCCESS;
1783}
1784
1785DEFUN (no_ip_rip_authentication_string,
1786 no_ip_rip_authentication_string_cmd,
1787 "no ip rip authentication string",
1788 NO_STR
1789 IP_STR
1790 "Routing Information Protocol\n"
1791 "Authentication control\n"
1792 "Authentication string\n")
1793{
1794 struct interface *ifp;
1795 struct rip_interface *ri;
1796
1797 ifp = (struct interface *)vty->index;
1798 ri = ifp->info;
1799
1800 if (ri->auth_str)
1801 free (ri->auth_str);
1802
1803 ri->auth_str = NULL;
1804
1805 return CMD_SUCCESS;
1806}
1807
1808ALIAS (no_ip_rip_authentication_string,
1809 no_ip_rip_authentication_string2_cmd,
1810 "no ip rip authentication string LINE",
1811 NO_STR
1812 IP_STR
1813 "Routing Information Protocol\n"
1814 "Authentication control\n"
1815 "Authentication string\n"
1816 "Authentication string\n")
1817
1818DEFUN (ip_rip_authentication_key_chain,
1819 ip_rip_authentication_key_chain_cmd,
1820 "ip rip authentication key-chain LINE",
1821 IP_STR
1822 "Routing Information Protocol\n"
1823 "Authentication control\n"
1824 "Authentication key-chain\n"
1825 "name of key-chain\n")
1826{
1827 struct interface *ifp;
1828 struct rip_interface *ri;
1829
1830 ifp = (struct interface *) vty->index;
1831 ri = ifp->info;
1832
1833 if (ri->auth_str)
1834 {
1835 vty_out (vty, "%% authentication string configuration exists%s",
1836 VTY_NEWLINE);
1837 return CMD_WARNING;
1838 }
1839
1840 if (ri->key_chain)
1841 free (ri->key_chain);
1842
1843 ri->key_chain = strdup (argv[0]);
1844
1845 return CMD_SUCCESS;
1846}
1847
1848DEFUN (no_ip_rip_authentication_key_chain,
1849 no_ip_rip_authentication_key_chain_cmd,
1850 "no ip rip authentication key-chain",
1851 NO_STR
1852 IP_STR
1853 "Routing Information Protocol\n"
1854 "Authentication control\n"
1855 "Authentication key-chain\n")
1856{
1857 struct interface *ifp;
1858 struct rip_interface *ri;
1859
1860 ifp = (struct interface *) vty->index;
1861 ri = ifp->info;
1862
1863 if (ri->key_chain)
1864 free (ri->key_chain);
1865
1866 ri->key_chain = NULL;
1867
1868 return CMD_SUCCESS;
1869}
1870
1871ALIAS (no_ip_rip_authentication_key_chain,
1872 no_ip_rip_authentication_key_chain2_cmd,
1873 "no ip rip authentication key-chain LINE",
1874 NO_STR
1875 IP_STR
1876 "Routing Information Protocol\n"
1877 "Authentication control\n"
1878 "Authentication key-chain\n"
1879 "name of key-chain\n")
1880
hasso16705132003-05-25 14:49:19 +00001881/* CHANGED: ip rip split-horizon
1882 Cisco and Zebra's command is
1883 ip split-horizon
1884 */
1885DEFUN (ip_rip_split_horizon,
1886 ip_rip_split_horizon_cmd,
1887 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001888 IP_STR
hasso16705132003-05-25 14:49:19 +00001889 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001890 "Perform split horizon\n")
1891{
1892 struct interface *ifp;
1893 struct rip_interface *ri;
1894
1895 ifp = vty->index;
1896 ri = ifp->info;
1897
hasso16705132003-05-25 14:49:19 +00001898 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001899 return CMD_SUCCESS;
1900}
1901
hasso16705132003-05-25 14:49:19 +00001902DEFUN (ip_rip_split_horizon_poisoned_reverse,
1903 ip_rip_split_horizon_poisoned_reverse_cmd,
1904 "ip rip split-horizon poisoned-reverse",
1905 IP_STR
1906 "Routing Information Protocol\n"
1907 "Perform split horizon\n"
1908 "With poisoned-reverse\n")
1909{
1910 struct interface *ifp;
1911 struct rip_interface *ri;
1912
1913 ifp = vty->index;
1914 ri = ifp->info;
1915
1916 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1917 return CMD_SUCCESS;
1918}
1919
1920/* CHANGED: no ip rip split-horizon
1921 Cisco and Zebra's command is
1922 no ip split-horizon
1923 */
1924DEFUN (no_ip_rip_split_horizon,
1925 no_ip_rip_split_horizon_cmd,
1926 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001927 NO_STR
1928 IP_STR
hasso16705132003-05-25 14:49:19 +00001929 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001930 "Perform split horizon\n")
1931{
1932 struct interface *ifp;
1933 struct rip_interface *ri;
1934
1935 ifp = vty->index;
1936 ri = ifp->info;
1937
hasso16705132003-05-25 14:49:19 +00001938 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001939 return CMD_SUCCESS;
1940}
1941
hasso16705132003-05-25 14:49:19 +00001942ALIAS (no_ip_rip_split_horizon,
1943 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1944 "no ip rip split-horizon poisoned-reverse",
1945 NO_STR
1946 IP_STR
1947 "Routing Information Protocol\n"
1948 "Perform split horizon\n"
1949 "With poisoned-reverse\n")
1950
paul718e3742002-12-13 20:15:29 +00001951DEFUN (rip_passive_interface,
1952 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001953 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001954 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001955 "Interface name\n"
1956 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001957{
hasso98b718a2004-10-11 12:57:57 +00001958 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001959
1960 if (!strcmp(ifname,"default")) {
1961 passive_default = 1;
1962 rip_passive_nondefault_clean();
1963 return CMD_SUCCESS;
1964 }
1965 if (passive_default)
1966 return rip_passive_nondefault_unset (vty, ifname);
1967 else
1968 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001969}
1970
1971DEFUN (no_rip_passive_interface,
1972 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001973 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001974 NO_STR
1975 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001976 "Interface name\n"
1977 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001978{
hasso98b718a2004-10-11 12:57:57 +00001979 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001980
1981 if (!strcmp(ifname,"default")) {
1982 passive_default = 0;
1983 rip_passive_nondefault_clean();
1984 return CMD_SUCCESS;
1985 }
1986 if (passive_default)
1987 return rip_passive_nondefault_set (vty, ifname);
1988 else
1989 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001990}
1991
1992/* Write rip configuration of each interface. */
1993int
1994rip_interface_config_write (struct vty *vty)
1995{
hasso52dc7ee2004-09-23 19:18:23 +00001996 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001997 struct interface *ifp;
1998
paul1eb8ef22005-04-07 07:30:20 +00001999 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00002000 {
2001 struct rip_interface *ri;
2002
paul718e3742002-12-13 20:15:29 +00002003 ri = ifp->info;
2004
hasso16705132003-05-25 14:49:19 +00002005 /* Do not display the interface if there is no
2006 * configuration about it.
2007 **/
2008 if ((!ifp->desc) &&
2009 (ri->split_horizon == ri->split_horizon_default) &&
2010 (ri->ri_send == RI_RIP_UNSPEC) &&
2011 (ri->ri_receive == RI_RIP_UNSPEC) &&
2012 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00002013 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00002014 (!ri->auth_str) &&
2015 (!ri->key_chain) )
2016 continue;
2017
paul718e3742002-12-13 20:15:29 +00002018 vty_out (vty, "interface %s%s", ifp->name,
2019 VTY_NEWLINE);
2020
2021 if (ifp->desc)
2022 vty_out (vty, " description %s%s", ifp->desc,
2023 VTY_NEWLINE);
2024
2025 /* Split horizon. */
2026 if (ri->split_horizon != ri->split_horizon_default)
2027 {
hasso16705132003-05-25 14:49:19 +00002028 switch (ri->split_horizon) {
2029 case RIP_SPLIT_HORIZON:
2030 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
2031 break;
2032 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
2033 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
2034 VTY_NEWLINE);
2035 break;
2036 case RIP_NO_SPLIT_HORIZON:
2037 default:
2038 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2039 break;
2040 }
paul718e3742002-12-13 20:15:29 +00002041 }
2042
2043 /* RIP version setting. */
2044 if (ri->ri_send != RI_RIP_UNSPEC)
2045 vty_out (vty, " ip rip send version %s%s",
2046 lookup (ri_version_msg, ri->ri_send),
2047 VTY_NEWLINE);
2048
2049 if (ri->ri_receive != RI_RIP_UNSPEC)
2050 vty_out (vty, " ip rip receive version %s%s",
2051 lookup (ri_version_msg, ri->ri_receive),
2052 VTY_NEWLINE);
2053
2054 /* RIP authentication. */
2055#if 0
2056 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
2057 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2058 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
2059#endif /* 0 */
paulca5e5162004-06-06 22:06:33 +00002060
paul718e3742002-12-13 20:15:29 +00002061 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002062 {
2063 vty_out (vty, " ip rip authentication mode md5");
2064 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2065 vty_out (vty, " auth-length old-ripd");
2066 else
2067 vty_out (vty, " auth-length rfc");
2068 vty_out (vty, "%s", VTY_NEWLINE);
2069 }
paul718e3742002-12-13 20:15:29 +00002070
2071 if (ri->auth_str)
2072 vty_out (vty, " ip rip authentication string %s%s",
2073 ri->auth_str, VTY_NEWLINE);
2074
2075 if (ri->key_chain)
2076 vty_out (vty, " ip rip authentication key-chain %s%s",
2077 ri->key_chain, VTY_NEWLINE);
2078
2079 vty_out (vty, "!%s", VTY_NEWLINE);
2080 }
2081 return 0;
2082}
2083
2084int
2085config_write_rip_network (struct vty *vty, int config_mode)
2086{
hasso8a676be2004-10-08 06:36:38 +00002087 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002088 char *ifname;
2089 struct route_node *node;
2090
2091 /* Network type RIP enable interface statement. */
2092 for (node = route_top (rip_enable_network); node; node = route_next (node))
2093 if (node->info)
2094 vty_out (vty, "%s%s/%d%s",
2095 config_mode ? " network " : " ",
2096 inet_ntoa (node->p.u.prefix4),
2097 node->p.prefixlen,
2098 VTY_NEWLINE);
2099
2100 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002101 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002102 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2103 vty_out (vty, "%s%s%s",
2104 config_mode ? " network " : " ",
2105 ifname,
2106 VTY_NEWLINE);
2107
2108 /* RIP neighbors listing. */
2109 for (node = route_top (rip->neighbor); node; node = route_next (node))
2110 if (node->info)
2111 vty_out (vty, "%s%s%s",
2112 config_mode ? " neighbor " : " ",
2113 inet_ntoa (node->p.u.prefix4),
2114 VTY_NEWLINE);
2115
2116 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002117 if (config_mode) {
2118 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002119 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002120 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002121 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2122 vty_out (vty, " %spassive-interface %s%s",
2123 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2124 }
paul718e3742002-12-13 20:15:29 +00002125
2126 return 0;
2127}
2128
2129struct cmd_node interface_node =
2130{
2131 INTERFACE_NODE,
2132 "%s(config-if)# ",
2133 1,
2134};
2135
2136/* Called when interface structure allocated. */
2137int
2138rip_interface_new_hook (struct interface *ifp)
2139{
2140 ifp->info = rip_interface_new ();
2141 return 0;
2142}
2143
2144/* Called when interface structure deleted. */
2145int
2146rip_interface_delete_hook (struct interface *ifp)
2147{
2148 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002149 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002150 return 0;
2151}
2152
2153/* Allocate and initialize interface vector. */
2154void
2155rip_if_init ()
2156{
2157 /* Default initial size of interface vector. */
2158 if_init();
2159 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2160 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2161
2162 /* RIP network init. */
2163 rip_enable_interface = vector_init (1);
2164 rip_enable_network = route_table_init ();
2165
2166 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002167 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002168
2169 /* Install interface node. */
2170 install_node (&interface_node, rip_interface_config_write);
2171
2172 /* Install commands. */
2173 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002174 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002175 install_default (INTERFACE_NODE);
2176 install_element (INTERFACE_NODE, &interface_desc_cmd);
2177 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2178 install_element (RIP_NODE, &rip_network_cmd);
2179 install_element (RIP_NODE, &no_rip_network_cmd);
2180 install_element (RIP_NODE, &rip_neighbor_cmd);
2181 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2182
2183 install_element (RIP_NODE, &rip_passive_interface_cmd);
2184 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2185
2186 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2187 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2188 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2189 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2190 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2191
2192 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2193 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2194 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2195 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2196 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2197
2198 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002199 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002200 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2201 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002202 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002203
2204 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2205 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2206 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2207
2208 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2209 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2210 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2211
hasso16705132003-05-25 14:49:19 +00002212 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2213 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2214 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2215 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002216}