blob: 4a6f78e2e69a5905c47edf6aeabeec9de554fe94 [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. */
paul7755a8c2005-06-02 08:20:53 +0000126 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +0000127 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +0000128
129 /* Set default split-horizon behavior. If the interface is Frame
130 Relay or SMDS is enabled, the default value for split-horizon is
131 off. But currently Zebra does detect Frame Relay or SMDS
132 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000133 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000134 ri->split_horizon = ri->split_horizon_default;
135
136 return ri;
137}
138
139void
paul1a517862004-08-19 04:03:08 +0000140rip_interface_multicast_set (int sock, struct connected *connected)
paul718e3742002-12-13 20:15:29 +0000141{
142 int ret;
paul718e3742002-12-13 20:15:29 +0000143 struct servent *sp;
144 struct sockaddr_in from;
hasso3fb9cd62004-10-19 19:44:43 +0000145 struct in_addr addr;
paulcc1131a2003-10-15 23:20:17 +0000146 struct prefix_ipv4 *p;
paulc49ad8f2004-10-22 10:27:28 +0000147
148 assert (connected != NULL);
149
150 if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected))
151 p = (struct prefix_ipv4 *) connected->destination;
152 else
153 p = (struct prefix_ipv4 *) connected->address;
154
155 addr = p->prefix;
paul718e3742002-12-13 20:15:29 +0000156
paul1a517862004-08-19 04:03:08 +0000157 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
158 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000159 {
160 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
161 "source address %s for interface %s",
162 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000163 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000164 return;
165 }
paul718e3742002-12-13 20:15:29 +0000166
hasso3fb9cd62004-10-19 19:44:43 +0000167 /* Bind myself. */
168 memset (&from, 0, sizeof (struct sockaddr_in));
paul718e3742002-12-13 20:15:29 +0000169
hasso3fb9cd62004-10-19 19:44:43 +0000170 /* Set RIP port. */
171 sp = getservbyname ("router", "udp");
172 if (sp)
173 from.sin_port = sp->s_port;
174 else
175 from.sin_port = htons (RIP_PORT_DEFAULT);
paul718e3742002-12-13 20:15:29 +0000176
paul931cd542004-01-23 15:31:42 +0000177 /* Address should be any address. */
hasso3fb9cd62004-10-19 19:44:43 +0000178 from.sin_family = AF_INET;
paulc49ad8f2004-10-22 10:27:28 +0000179 from.sin_addr = connected->address->u.prefix4;
paul718e3742002-12-13 20:15:29 +0000180#ifdef HAVE_SIN_LEN
hasso3fb9cd62004-10-19 19:44:43 +0000181 from.sin_len = sizeof (struct sockaddr_in);
paul718e3742002-12-13 20:15:29 +0000182#endif /* HAVE_SIN_LEN */
183
hasso3fb9cd62004-10-19 19:44:43 +0000184 if (ripd_privs.change (ZPRIVS_RAISE))
185 zlog_err ("rip_interface_multicast_set: could not raise privs");
pauledd7c242003-06-04 13:59:38 +0000186
paulcc1131a2003-10-15 23:20:17 +0000187 ret = bind (sock, (struct sockaddr *) & from, sizeof (struct sockaddr_in));
hasso3fb9cd62004-10-19 19:44:43 +0000188 if (ret < 0)
189 {
190 zlog_warn ("Can't bind socket fd %d to %s port %d for "
191 "interface %s: %s",
192 sock,inet_ntoa(from.sin_addr),
193 (int)ntohs(from.sin_port),
paulc49ad8f2004-10-22 10:27:28 +0000194 connected->ifp->name,
ajs6099b3b2004-11-20 02:06:59 +0000195 safe_strerror (errno));
hasso3fb9cd62004-10-19 19:44:43 +0000196 }
paul718e3742002-12-13 20:15:29 +0000197
hasso3fb9cd62004-10-19 19:44:43 +0000198 if (ripd_privs.change (ZPRIVS_LOWER))
199 zlog_err ("rip_interface_multicast_set: could not lower privs");
pauledd7c242003-06-04 13:59:38 +0000200
hasso3fb9cd62004-10-19 19:44:43 +0000201 return;
202}
paul718e3742002-12-13 20:15:29 +0000203
204/* Send RIP request packet to specified interface. */
205void
206rip_request_interface_send (struct interface *ifp, u_char version)
207{
208 struct sockaddr_in to;
209
210 /* RIPv2 support multicast. */
211 if (version == RIPv2 && if_is_multicast (ifp))
212 {
213
214 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000215 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000216
paul931cd542004-01-23 15:31:42 +0000217 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000218 return;
219 }
220
221 /* RIPv1 and non multicast interface. */
222 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
223 {
paul1eb8ef22005-04-07 07:30:20 +0000224 struct listnode *cnode, *cnnode;
225 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000226
227 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000228 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000229
paul1eb8ef22005-04-07 07:30:20 +0000230 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000231 {
hasso3fb9cd62004-10-19 19:44:43 +0000232 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000233 {
234 memset (&to, 0, sizeof (struct sockaddr_in));
235 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000236 if (connected->destination)
237 /* use specified broadcast or point-to-point destination addr */
238 to.sin_addr = connected->destination->u.prefix4;
239 else
240 /* calculate the appropriate broadcast address */
241 to.sin_addr.s_addr =
242 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
243 connected->address->prefixlen);
paul718e3742002-12-13 20:15:29 +0000244
paul718e3742002-12-13 20:15:29 +0000245 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000246 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000247
paul931cd542004-01-23 15:31:42 +0000248 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000249 }
250 }
251 }
252}
253
254/* This will be executed when interface goes up. */
255void
256rip_request_interface (struct interface *ifp)
257{
258 struct rip_interface *ri;
259
260 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
261 if (if_is_loopback (ifp))
262 return;
263
264 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000265 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000266 return;
267
268 /* Fetch RIP interface information. */
269 ri = ifp->info;
270
271
272 /* If there is no version configuration in the interface,
273 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000274 {
275 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
276 rip->version_send : ri->ri_send);
277 if (vsend & RIPv1)
278 rip_request_interface_send (ifp, RIPv1);
279 if (vsend & RIPv2)
280 rip_request_interface_send (ifp, RIPv2);
281 }
paul718e3742002-12-13 20:15:29 +0000282}
283
284/* Send RIP request to the neighbor. */
285void
286rip_request_neighbor (struct in_addr addr)
287{
288 struct sockaddr_in to;
289
290 memset (&to, 0, sizeof (struct sockaddr_in));
291 to.sin_port = htons (RIP_PORT_DEFAULT);
292 to.sin_addr = addr;
293
paul931cd542004-01-23 15:31:42 +0000294 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000295}
296
297/* Request routes at all interfaces. */
298void
299rip_request_neighbor_all ()
300{
301 struct route_node *rp;
302
303 if (! rip)
304 return;
305
306 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000307 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000308
309 /* Send request to all neighbor. */
310 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
311 if (rp->info)
312 rip_request_neighbor (rp->p.u.prefix4);
313}
314
315/* Multicast packet receive socket. */
316int
317rip_multicast_join (struct interface *ifp, int sock)
318{
hasso52dc7ee2004-09-23 19:18:23 +0000319 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000320 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000321
paul2e3b2e42002-12-13 21:03:13 +0000322 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000323 {
324 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000325 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000326
paul1eb8ef22005-04-07 07:30:20 +0000327 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000328 {
329 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000330 struct in_addr group;
331
paul1eb8ef22005-04-07 07:30:20 +0000332 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000333
334 if (p->family != AF_INET)
335 continue;
336
337 group.s_addr = htonl (INADDR_RIP_GROUP);
338 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
339 return -1;
340 else
341 return 0;
342 }
343 }
344 return 0;
345}
346
347/* Leave from multicast group. */
348void
349rip_multicast_leave (struct interface *ifp, int sock)
350{
hasso52dc7ee2004-09-23 19:18:23 +0000351 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000352 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000353
354 if (if_is_up (ifp) && if_is_multicast (ifp))
355 {
356 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000357 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000358
paul1eb8ef22005-04-07 07:30:20 +0000359 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000360 {
361 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000362 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000363
paul718e3742002-12-13 20:15:29 +0000364 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000365
paul718e3742002-12-13 20:15:29 +0000366 if (p->family != AF_INET)
367 continue;
368
369 group.s_addr = htonl (INADDR_RIP_GROUP);
370 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
371 return;
372 }
373 }
374}
375
376/* Is there and address on interface that I could use ? */
377int
378rip_if_ipv4_address_check (struct interface *ifp)
379{
380 struct listnode *nn;
381 struct connected *connected;
382 int count = 0;
383
paul1eb8ef22005-04-07 07:30:20 +0000384 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
385 {
386 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000387
paul1eb8ef22005-04-07 07:30:20 +0000388 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000389
paul1eb8ef22005-04-07 07:30:20 +0000390 if (p->family == AF_INET)
391 count++;
392 }
paul718e3742002-12-13 20:15:29 +0000393
394 return count;
395}
paul31a476c2003-09-29 19:54:53 +0000396
397
398
399
400/* Does this address belongs to me ? */
401int
402if_check_address (struct in_addr addr)
403{
hasso52dc7ee2004-09-23 19:18:23 +0000404 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000405 struct interface *ifp;
406
407 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000408 {
hasso52dc7ee2004-09-23 19:18:23 +0000409 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000410 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000411
paul1eb8ef22005-04-07 07:30:20 +0000412 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000413 {
paul31a476c2003-09-29 19:54:53 +0000414 struct prefix_ipv4 *p;
415
paul31a476c2003-09-29 19:54:53 +0000416 p = (struct prefix_ipv4 *) connected->address;
417
418 if (p->family != AF_INET)
419 continue;
420
421 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
422 return 1;
423 }
424 }
425 return 0;
426}
427
428/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
429int
430if_valid_neighbor (struct in_addr addr)
431{
hasso52dc7ee2004-09-23 19:18:23 +0000432 struct listnode *node;
paul31a476c2003-09-29 19:54:53 +0000433 struct connected *connected = NULL;
paul1eb8ef22005-04-07 07:30:20 +0000434 struct interface *ifp;
paul31a476c2003-09-29 19:54:53 +0000435 struct prefix_ipv4 *p;
hasso3fb9cd62004-10-19 19:44:43 +0000436 struct prefix_ipv4 pa;
437
438 pa.family = AF_INET;
439 pa.prefix = addr;
440 pa.prefixlen = IPV4_MAX_PREFIXLEN;
paul31a476c2003-09-29 19:54:53 +0000441
paul1eb8ef22005-04-07 07:30:20 +0000442 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000443 {
hasso52dc7ee2004-09-23 19:18:23 +0000444 struct listnode *cnode;
paul31a476c2003-09-29 19:54:53 +0000445
paul1eb8ef22005-04-07 07:30:20 +0000446 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000447 {
paul31a476c2003-09-29 19:54:53 +0000448 if (if_is_pointopoint (ifp))
449 {
450 p = (struct prefix_ipv4 *) connected->address;
451
452 if (p && p->family == AF_INET)
453 {
454 if (IPV4_ADDR_SAME (&p->prefix, &addr))
455 return 1;
456
457 p = (struct prefix_ipv4 *) connected->destination;
hasso3fb9cd62004-10-19 19:44:43 +0000458 if (p)
459 {
460 if (IPV4_ADDR_SAME (&p->prefix, &addr))
461 return 1;
462 }
463 else
464 {
465 if (prefix_match(connected->address,(struct prefix *)&pa))
466 return 1;
467 }
paul31a476c2003-09-29 19:54:53 +0000468 }
469 }
470 else
471 {
hasso3fb9cd62004-10-19 19:44:43 +0000472 if ((connected->address->family == AF_INET) &&
473 prefix_match(connected->address,(struct prefix *)&pa))
474 return 1;
paul31a476c2003-09-29 19:54:53 +0000475 }
476 }
477 }
478 return 0;
479}
paul718e3742002-12-13 20:15:29 +0000480
481/* Inteface link down message processing. */
482int
483rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
484{
485 struct interface *ifp;
486 struct stream *s;
487
488 s = zclient->ibuf;
489
490 /* zebra_interface_state_read() updates interface structure in
491 iflist. */
492 ifp = zebra_interface_state_read(s);
493
494 if (ifp == NULL)
495 return 0;
496
497 rip_if_down(ifp);
498
499 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000500 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000501 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
502
503 return 0;
504}
505
506/* Inteface link up message processing */
507int
508rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
509{
510 struct interface *ifp;
511
512 /* zebra_interface_state_read () updates interface structure in
513 iflist. */
514 ifp = zebra_interface_state_read (zclient->ibuf);
515
516 if (ifp == NULL)
517 return 0;
518
519 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000520 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000521 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
522
523 /* Check if this interface is RIP enabled or not.*/
524 rip_enable_apply (ifp);
525
526 /* Check for a passive interface */
527 rip_passive_interface_apply (ifp);
528
529 /* Apply distribute list to the all interface. */
530 rip_distribute_update_interface (ifp);
531
532 return 0;
533}
534
535/* Inteface addition message from zebra. */
536int
537rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
538{
539 struct interface *ifp;
540
541 ifp = zebra_interface_add_read (zclient->ibuf);
542
543 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000544 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000545 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
546
547 /* Check if this interface is RIP enabled or not.*/
548 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000549
550 /* Check for a passive interface */
551 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000552
553 /* Apply distribute list to the all interface. */
554 rip_distribute_update_interface (ifp);
555
556 /* rip_request_neighbor_all (); */
557
hasso16705132003-05-25 14:49:19 +0000558 /* Check interface routemap. */
559 rip_if_rmap_update_interface (ifp);
560
paul718e3742002-12-13 20:15:29 +0000561 return 0;
562}
563
564int
565rip_interface_delete (int command, struct zclient *zclient,
566 zebra_size_t length)
567{
568 struct interface *ifp;
569 struct stream *s;
570
571
572 s = zclient->ibuf;
573 /* zebra_interface_state_read() updates interface structure in iflist */
574 ifp = zebra_interface_state_read(s);
575
576 if (ifp == NULL)
577 return 0;
578
579 if (if_is_up (ifp)) {
580 rip_if_down(ifp);
581 }
582
583 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
584 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
585
586 /* To support pseudo interface do not free interface structure. */
587 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000588 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000589
590 return 0;
591}
592
593void
594rip_interface_clean ()
595{
hasso52dc7ee2004-09-23 19:18:23 +0000596 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000597 struct interface *ifp;
598 struct rip_interface *ri;
599
paul1eb8ef22005-04-07 07:30:20 +0000600 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000601 {
paul718e3742002-12-13 20:15:29 +0000602 ri = ifp->info;
603
604 ri->enable_network = 0;
605 ri->enable_interface = 0;
606 ri->running = 0;
607
608 if (ri->t_wakeup)
609 {
610 thread_cancel (ri->t_wakeup);
611 ri->t_wakeup = NULL;
612 }
613 }
614}
615
616void
617rip_interface_reset ()
618{
hasso52dc7ee2004-09-23 19:18:23 +0000619 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000620 struct interface *ifp;
621 struct rip_interface *ri;
622
paul1eb8ef22005-04-07 07:30:20 +0000623 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000624 {
paul718e3742002-12-13 20:15:29 +0000625 ri = ifp->info;
626
627 ri->enable_network = 0;
628 ri->enable_interface = 0;
629 ri->running = 0;
630
631 ri->ri_send = RI_RIP_UNSPEC;
632 ri->ri_receive = RI_RIP_UNSPEC;
633
paul7755a8c2005-06-02 08:20:53 +0000634 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000635
636 if (ri->auth_str)
637 {
638 free (ri->auth_str);
639 ri->auth_str = NULL;
640 }
641 if (ri->key_chain)
642 {
643 free (ri->key_chain);
644 ri->key_chain = NULL;
645 }
646
hasso16705132003-05-25 14:49:19 +0000647 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
648 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000649
650 ri->list[RIP_FILTER_IN] = NULL;
651 ri->list[RIP_FILTER_OUT] = NULL;
652
653 ri->prefix[RIP_FILTER_IN] = NULL;
654 ri->prefix[RIP_FILTER_OUT] = NULL;
655
656 if (ri->t_wakeup)
657 {
658 thread_cancel (ri->t_wakeup);
659 ri->t_wakeup = NULL;
660 }
661
662 ri->recv_badpackets = 0;
663 ri->recv_badroutes = 0;
664 ri->sent_updates = 0;
665
666 ri->passive = 0;
667 }
668}
669
670int
671rip_if_down(struct interface *ifp)
672{
673 struct route_node *rp;
674 struct rip_info *rinfo;
675 struct rip_interface *ri = NULL;
676 if (rip)
677 {
678 for (rp = route_top (rip->table); rp; rp = route_next (rp))
679 if ((rinfo = rp->info) != NULL)
680 {
681 /* Routes got through this interface. */
682 if (rinfo->ifindex == ifp->ifindex &&
683 rinfo->type == ZEBRA_ROUTE_RIP &&
684 rinfo->sub_type == RIP_ROUTE_RTE)
685 {
686 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
687 &rinfo->nexthop,
688 rinfo->ifindex);
689
690 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
691 (struct prefix_ipv4 *)&rp->p,
692 rinfo->ifindex);
693 }
694 else
695 {
696 /* All redistributed routes but static and system */
697 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000698 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000699 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
700 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
701 (struct prefix_ipv4 *)&rp->p,
702 rinfo->ifindex);
703 }
704 }
705 }
706
707 ri = ifp->info;
708
709 if (ri->running)
710 {
711 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000712 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000713
714 /* Leave from multicast group. */
715 rip_multicast_leave (ifp, rip->sock);
716
717 ri->running = 0;
718 }
719
720 return 0;
721}
722
723/* Needed for stop RIP process. */
724void
725rip_if_down_all ()
726{
727 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000728 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000729
paul1eb8ef22005-04-07 07:30:20 +0000730 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
731 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000732}
733
hasso16705132003-05-25 14:49:19 +0000734static void
735rip_apply_address_add (struct connected *ifc) {
736 struct prefix_ipv4 address;
737 struct prefix *p;
738
739 if (!rip)
740 return;
741
742 if (! if_is_up(ifc->ifp))
743 return;
744
745 p = ifc->address;
746
747 memset (&address, 0, sizeof (address));
748 address.family = p->family;
749 address.prefix = p->u.prefix4;
750 address.prefixlen = p->prefixlen;
751 apply_mask_ipv4(&address);
752
753 /* Check if this interface is RIP enabled or not
754 or Check if this address's prefix is RIP enabled */
755 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
756 (rip_enable_network_lookup2(ifc) >= 0))
757 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
758 &address, ifc->ifp->ifindex, NULL);
759
760}
761
paul718e3742002-12-13 20:15:29 +0000762int
763rip_interface_address_add (int command, struct zclient *zclient,
764 zebra_size_t length)
765{
766 struct connected *ifc;
767 struct prefix *p;
768
paul0a589352004-05-08 11:48:26 +0000769 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
770 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000771
772 if (ifc == NULL)
773 return 0;
774
775 p = ifc->address;
776
777 if (p->family == AF_INET)
778 {
779 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000780 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000781 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000782
paul878ef2e2003-09-23 23:41:50 +0000783 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000784 /* Check if this prefix needs to be redistributed */
785 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000786
787#ifdef HAVE_SNMP
788 rip_ifaddr_add (ifc->ifp, ifc);
789#endif /* HAVE_SNMP */
790 }
791
792 return 0;
793}
794
hasso16705132003-05-25 14:49:19 +0000795static void
796rip_apply_address_del (struct connected *ifc) {
797 struct prefix_ipv4 address;
798 struct prefix *p;
799
800 if (!rip)
801 return;
802
803 if (! if_is_up(ifc->ifp))
804 return;
805
806 p = ifc->address;
807
808 memset (&address, 0, sizeof (address));
809 address.family = p->family;
810 address.prefix = p->u.prefix4;
811 address.prefixlen = p->prefixlen;
812 apply_mask_ipv4(&address);
813
814 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
815 &address, ifc->ifp->ifindex);
816}
817
paul718e3742002-12-13 20:15:29 +0000818int
819rip_interface_address_delete (int command, struct zclient *zclient,
820 zebra_size_t length)
821{
822 struct connected *ifc;
823 struct prefix *p;
824
paul0a589352004-05-08 11:48:26 +0000825 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
826 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000827
828 if (ifc)
829 {
830 p = ifc->address;
831 if (p->family == AF_INET)
832 {
833 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000834 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000835 inet_ntoa (p->u.prefix4), p->prefixlen);
836
837#ifdef HAVE_SNMP
838 rip_ifaddr_delete (ifc->ifp, ifc);
839#endif /* HAVE_SNMP */
840
hasso16705132003-05-25 14:49:19 +0000841 /* Chech wether this prefix needs to be removed */
842 rip_apply_address_del(ifc);
843
paul718e3742002-12-13 20:15:29 +0000844 }
845
846 connected_free (ifc);
847
848 }
849
850 return 0;
851}
852
853/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000854/* Check wether the interface has at least a connected prefix that
855 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000856int
hasso16705132003-05-25 14:49:19 +0000857rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000858{
paul1eb8ef22005-04-07 07:30:20 +0000859 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000860 struct connected *connected;
861 struct prefix_ipv4 address;
862
paul1eb8ef22005-04-07 07:30:20 +0000863 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
864 {
865 struct prefix *p;
866 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000867
paul1eb8ef22005-04-07 07:30:20 +0000868 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000869
paul1eb8ef22005-04-07 07:30:20 +0000870 if (p->family == AF_INET)
871 {
872 address.family = AF_INET;
873 address.prefix = p->u.prefix4;
874 address.prefixlen = IPV4_MAX_BITLEN;
875
876 node = route_node_match (rip_enable_network,
877 (struct prefix *)&address);
878 if (node)
879 {
880 route_unlock_node (node);
881 return 1;
882 }
883 }
884 }
paul718e3742002-12-13 20:15:29 +0000885 return -1;
886}
887
hasso16705132003-05-25 14:49:19 +0000888/* Check wether connected is within the ripng_enable_network table. */
889int
890rip_enable_network_lookup2 (struct connected *connected)
891{
892 struct prefix_ipv4 address;
893 struct prefix *p;
894
895 p = connected->address;
896
897 if (p->family == AF_INET) {
898 struct route_node *node;
899
900 address.family = p->family;
901 address.prefix = p->u.prefix4;
902 address.prefixlen = IPV4_MAX_BITLEN;
903
904 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
905 node = route_node_match (rip_enable_network,
906 (struct prefix *)&address);
907
908 if (node) {
909 route_unlock_node (node);
910 return 1;
911 }
912 }
913
914 return -1;
915}
paul718e3742002-12-13 20:15:29 +0000916/* Add RIP enable network. */
917int
918rip_enable_network_add (struct prefix *p)
919{
920 struct route_node *node;
921
922 node = route_node_get (rip_enable_network, p);
923
924 if (node->info)
925 {
926 route_unlock_node (node);
927 return -1;
928 }
929 else
hasso8a676be2004-10-08 06:36:38 +0000930 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000931
hasso16705132003-05-25 14:49:19 +0000932 /* XXX: One should find a better solution than a generic one */
933 rip_enable_apply_all();
934
paul718e3742002-12-13 20:15:29 +0000935 return 1;
936}
937
938/* Delete RIP enable network. */
939int
940rip_enable_network_delete (struct prefix *p)
941{
942 struct route_node *node;
943
944 node = route_node_lookup (rip_enable_network, p);
945 if (node)
946 {
947 node->info = NULL;
948
949 /* Unlock info lock. */
950 route_unlock_node (node);
951
952 /* Unlock lookup lock. */
953 route_unlock_node (node);
954
hasso16705132003-05-25 14:49:19 +0000955 /* XXX: One should find a better solution than a generic one */
956 rip_enable_apply_all ();
957
paul718e3742002-12-13 20:15:29 +0000958 return 1;
959 }
960 return -1;
961}
962
963/* Check interface is enabled by ifname statement. */
964int
hasso98b718a2004-10-11 12:57:57 +0000965rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000966{
hasso8a676be2004-10-08 06:36:38 +0000967 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000968 char *str;
969
paul55468c82005-03-14 20:19:01 +0000970 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000971 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
972 if (strcmp (str, ifname) == 0)
973 return i;
974 return -1;
975}
976
977/* Add interface to rip_enable_if. */
978int
hasso98b718a2004-10-11 12:57:57 +0000979rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000980{
981 int ret;
982
983 ret = rip_enable_if_lookup (ifname);
984 if (ret >= 0)
985 return -1;
986
987 vector_set (rip_enable_interface, strdup (ifname));
988
hasso16705132003-05-25 14:49:19 +0000989 rip_enable_apply_all(); /* TODOVJ */
990
paul718e3742002-12-13 20:15:29 +0000991 return 1;
992}
993
994/* Delete interface from rip_enable_if. */
995int
hasso98b718a2004-10-11 12:57:57 +0000996rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000997{
998 int index;
999 char *str;
1000
1001 index = rip_enable_if_lookup (ifname);
1002 if (index < 0)
1003 return -1;
1004
1005 str = vector_slot (rip_enable_interface, index);
1006 free (str);
1007 vector_unset (rip_enable_interface, index);
1008
hasso16705132003-05-25 14:49:19 +00001009 rip_enable_apply_all(); /* TODOVJ */
1010
paul718e3742002-12-13 20:15:29 +00001011 return 1;
1012}
1013
1014/* Join to multicast group and send request to the interface. */
1015int
1016rip_interface_wakeup (struct thread *t)
1017{
1018 struct interface *ifp;
1019 struct rip_interface *ri;
1020
1021 /* Get interface. */
1022 ifp = THREAD_ARG (t);
1023
1024 ri = ifp->info;
1025 ri->t_wakeup = NULL;
1026
1027 /* Join to multicast group. */
1028 if (rip_multicast_join (ifp, rip->sock) < 0)
1029 {
1030 zlog_err ("multicast join failed, interface %s not running", ifp->name);
1031 return 0;
1032 }
1033
1034 /* Set running flag. */
1035 ri->running = 1;
1036
1037 /* Send RIP request to the interface. */
1038 rip_request_interface (ifp);
1039
1040 return 0;
1041}
1042
1043int rip_redistribute_check (int);
1044
1045void
1046rip_connect_set (struct interface *ifp, int set)
1047{
paul1eb8ef22005-04-07 07:30:20 +00001048 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001049 struct connected *connected;
1050 struct prefix_ipv4 address;
1051
paul1eb8ef22005-04-07 07:30:20 +00001052 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
1053 {
1054 struct prefix *p;
1055 p = connected->address;
paul718e3742002-12-13 20:15:29 +00001056
paul1eb8ef22005-04-07 07:30:20 +00001057 if (p->family != AF_INET)
1058 continue;
paul718e3742002-12-13 20:15:29 +00001059
paul1eb8ef22005-04-07 07:30:20 +00001060 address.family = AF_INET;
1061 address.prefix = p->u.prefix4;
1062 address.prefixlen = p->prefixlen;
1063 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +00001064
paul1eb8ef22005-04-07 07:30:20 +00001065 if (set) {
1066 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1067 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1068 (rip_enable_network_lookup2(connected) >= 0))
1069 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1070 &address, connected->ifp->ifindex, NULL);
1071 } else
1072 {
1073 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1074 &address, connected->ifp->ifindex);
1075 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1076 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1077 &address, connected->ifp->ifindex, NULL);
1078 }
1079 }
paul718e3742002-12-13 20:15:29 +00001080}
1081
1082/* Update interface status. */
1083void
1084rip_enable_apply (struct interface *ifp)
1085{
1086 int ret;
1087 struct rip_interface *ri = NULL;
1088
1089 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001090 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001091 return;
1092
1093 ri = ifp->info;
1094
1095 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001096 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001097
1098 /* If the interface is matched. */
1099 if (ret > 0)
1100 ri->enable_network = 1;
1101 else
1102 ri->enable_network = 0;
1103
1104 /* Check interface name configuration. */
1105 ret = rip_enable_if_lookup (ifp->name);
1106 if (ret >= 0)
1107 ri->enable_interface = 1;
1108 else
1109 ri->enable_interface = 0;
1110
1111 /* any interface MUST have an IPv4 address */
1112 if ( ! rip_if_ipv4_address_check (ifp) )
1113 {
1114 ri->enable_network = 0;
1115 ri->enable_interface = 0;
1116 }
1117
1118 /* Update running status of the interface. */
1119 if (ri->enable_network || ri->enable_interface)
1120 {
paul718e3742002-12-13 20:15:29 +00001121 {
1122 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001123 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001124
1125 /* Add interface wake up thread. */
1126 if (! ri->t_wakeup)
1127 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1128 ifp, 1);
1129 rip_connect_set (ifp, 1);
1130 }
1131 }
1132 else
1133 {
1134 if (ri->running)
1135 {
hasso16705132003-05-25 14:49:19 +00001136 /* Might as well clean up the route table as well
1137 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1138 **/
paul718e3742002-12-13 20:15:29 +00001139 rip_if_down(ifp);
1140
paul718e3742002-12-13 20:15:29 +00001141 rip_connect_set (ifp, 0);
1142 }
1143 }
1144}
1145
1146/* Apply network configuration to all interface. */
1147void
1148rip_enable_apply_all ()
1149{
1150 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001151 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001152
1153 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001154 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1155 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001156}
1157
1158int
1159rip_neighbor_lookup (struct sockaddr_in *from)
1160{
1161 struct prefix_ipv4 p;
1162 struct route_node *node;
1163
1164 memset (&p, 0, sizeof (struct prefix_ipv4));
1165 p.family = AF_INET;
1166 p.prefix = from->sin_addr;
1167 p.prefixlen = IPV4_MAX_BITLEN;
1168
1169 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1170 if (node)
1171 {
1172 route_unlock_node (node);
1173 return 1;
1174 }
1175 return 0;
1176}
1177
1178/* Add new RIP neighbor to the neighbor tree. */
1179int
1180rip_neighbor_add (struct prefix_ipv4 *p)
1181{
1182 struct route_node *node;
1183
1184 node = route_node_get (rip->neighbor, (struct prefix *) p);
1185
1186 if (node->info)
1187 return -1;
1188
1189 node->info = rip->neighbor;
1190
1191 return 0;
1192}
1193
1194/* Delete RIP neighbor from the neighbor tree. */
1195int
1196rip_neighbor_delete (struct prefix_ipv4 *p)
1197{
1198 struct route_node *node;
1199
1200 /* Lock for look up. */
1201 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1202 if (! node)
1203 return -1;
1204
1205 node->info = NULL;
1206
1207 /* Unlock lookup lock. */
1208 route_unlock_node (node);
1209
1210 /* Unlock real neighbor information lock. */
1211 route_unlock_node (node);
1212
1213 return 0;
1214}
1215
1216/* Clear all network and neighbor configuration. */
1217void
1218rip_clean_network ()
1219{
hasso8a676be2004-10-08 06:36:38 +00001220 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001221 char *str;
1222 struct route_node *rn;
1223
1224 /* rip_enable_network. */
1225 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1226 if (rn->info)
1227 {
1228 rn->info = NULL;
1229 route_unlock_node (rn);
1230 }
1231
1232 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001233 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001234 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1235 {
1236 free (str);
1237 vector_slot (rip_enable_interface, i) = NULL;
1238 }
1239}
1240
1241/* Utility function for looking up passive interface settings. */
1242int
hasso98b718a2004-10-11 12:57:57 +00001243rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001244{
hasso8a676be2004-10-08 06:36:38 +00001245 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001246 char *str;
1247
paul55468c82005-03-14 20:19:01 +00001248 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001249 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001250 if (strcmp (str, ifname) == 0)
1251 return i;
1252 return -1;
1253}
1254
1255void
1256rip_passive_interface_apply (struct interface *ifp)
1257{
paul718e3742002-12-13 20:15:29 +00001258 struct rip_interface *ri;
1259
1260 ri = ifp->info;
1261
paul4aaff3f2003-06-07 01:04:45 +00001262 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1263 passive_default : !passive_default);
1264
1265 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001266 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001267}
1268
1269void
1270rip_passive_interface_apply_all ()
1271{
1272 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001273 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001274
paul1eb8ef22005-04-07 07:30:20 +00001275 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1276 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001277}
1278
1279/* Passive interface. */
1280int
hasso98b718a2004-10-11 12:57:57 +00001281rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001282{
paul4aaff3f2003-06-07 01:04:45 +00001283 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001284 return CMD_WARNING;
1285
paul4aaff3f2003-06-07 01:04:45 +00001286 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001287
1288 rip_passive_interface_apply_all ();
1289
1290 return CMD_SUCCESS;
1291}
1292
1293int
hasso98b718a2004-10-11 12:57:57 +00001294rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001295{
1296 int i;
1297 char *str;
1298
paul4aaff3f2003-06-07 01:04:45 +00001299 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001300 if (i < 0)
1301 return CMD_WARNING;
1302
paul4aaff3f2003-06-07 01:04:45 +00001303 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001304 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001305 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001306
1307 rip_passive_interface_apply_all ();
1308
1309 return CMD_SUCCESS;
1310}
1311
1312/* Free all configured RIP passive-interface settings. */
1313void
paul4aaff3f2003-06-07 01:04:45 +00001314rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001315{
hasso8a676be2004-10-08 06:36:38 +00001316 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001317 char *str;
1318
paul55468c82005-03-14 20:19:01 +00001319 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001320 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001321 {
1322 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001323 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001324 }
1325 rip_passive_interface_apply_all ();
1326}
1327
1328/* RIP enable network or interface configuration. */
1329DEFUN (rip_network,
1330 rip_network_cmd,
1331 "network (A.B.C.D/M|WORD)",
1332 "Enable routing on an IP network\n"
1333 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1334 "Interface name\n")
1335{
1336 int ret;
1337 struct prefix_ipv4 p;
1338
1339 ret = str2prefix_ipv4 (argv[0], &p);
1340
1341 if (ret)
1342 ret = rip_enable_network_add ((struct prefix *) &p);
1343 else
1344 ret = rip_enable_if_add (argv[0]);
1345
1346 if (ret < 0)
1347 {
1348 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1349 VTY_NEWLINE);
1350 return CMD_WARNING;
1351 }
1352
paul718e3742002-12-13 20:15:29 +00001353 return CMD_SUCCESS;
1354}
1355
1356/* RIP enable network or interface configuration. */
1357DEFUN (no_rip_network,
1358 no_rip_network_cmd,
1359 "no network (A.B.C.D/M|WORD)",
1360 NO_STR
1361 "Enable routing on an IP network\n"
1362 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1363 "Interface name\n")
1364{
1365 int ret;
1366 struct prefix_ipv4 p;
1367
1368 ret = str2prefix_ipv4 (argv[0], &p);
1369
1370 if (ret)
1371 ret = rip_enable_network_delete ((struct prefix *) &p);
1372 else
1373 ret = rip_enable_if_delete (argv[0]);
1374
1375 if (ret < 0)
1376 {
1377 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1378 VTY_NEWLINE);
1379 return CMD_WARNING;
1380 }
1381
paul718e3742002-12-13 20:15:29 +00001382 return CMD_SUCCESS;
1383}
1384
1385/* RIP neighbor configuration set. */
1386DEFUN (rip_neighbor,
1387 rip_neighbor_cmd,
1388 "neighbor A.B.C.D",
1389 "Specify a neighbor router\n"
1390 "Neighbor address\n")
1391{
1392 int ret;
1393 struct prefix_ipv4 p;
1394
1395 ret = str2prefix_ipv4 (argv[0], &p);
1396
1397 if (ret <= 0)
1398 {
1399 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1400 return CMD_WARNING;
1401 }
1402
1403 rip_neighbor_add (&p);
1404
1405 return CMD_SUCCESS;
1406}
1407
1408/* RIP neighbor configuration unset. */
1409DEFUN (no_rip_neighbor,
1410 no_rip_neighbor_cmd,
1411 "no neighbor A.B.C.D",
1412 NO_STR
1413 "Specify a neighbor router\n"
1414 "Neighbor address\n")
1415{
1416 int ret;
1417 struct prefix_ipv4 p;
1418
1419 ret = str2prefix_ipv4 (argv[0], &p);
1420
1421 if (ret <= 0)
1422 {
1423 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1424 return CMD_WARNING;
1425 }
1426
1427 rip_neighbor_delete (&p);
1428
1429 return CMD_SUCCESS;
1430}
1431
1432DEFUN (ip_rip_receive_version,
1433 ip_rip_receive_version_cmd,
1434 "ip rip receive version (1|2)",
1435 IP_STR
1436 "Routing Information Protocol\n"
1437 "Advertisement reception\n"
1438 "Version control\n"
1439 "RIP version 1\n"
1440 "RIP version 2\n")
1441{
1442 struct interface *ifp;
1443 struct rip_interface *ri;
1444
1445 ifp = (struct interface *)vty->index;
1446 ri = ifp->info;
1447
1448 /* Version 1. */
1449 if (atoi (argv[0]) == 1)
1450 {
1451 ri->ri_receive = RI_RIP_VERSION_1;
1452 return CMD_SUCCESS;
1453 }
1454 if (atoi (argv[0]) == 2)
1455 {
1456 ri->ri_receive = RI_RIP_VERSION_2;
1457 return CMD_SUCCESS;
1458 }
1459 return CMD_WARNING;
1460}
1461
1462DEFUN (ip_rip_receive_version_1,
1463 ip_rip_receive_version_1_cmd,
1464 "ip rip receive version 1 2",
1465 IP_STR
1466 "Routing Information Protocol\n"
1467 "Advertisement reception\n"
1468 "Version control\n"
1469 "RIP version 1\n"
1470 "RIP version 2\n")
1471{
1472 struct interface *ifp;
1473 struct rip_interface *ri;
1474
1475 ifp = (struct interface *)vty->index;
1476 ri = ifp->info;
1477
1478 /* Version 1 and 2. */
1479 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1480 return CMD_SUCCESS;
1481}
1482
1483DEFUN (ip_rip_receive_version_2,
1484 ip_rip_receive_version_2_cmd,
1485 "ip rip receive version 2 1",
1486 IP_STR
1487 "Routing Information Protocol\n"
1488 "Advertisement reception\n"
1489 "Version control\n"
1490 "RIP version 2\n"
1491 "RIP version 1\n")
1492{
1493 struct interface *ifp;
1494 struct rip_interface *ri;
1495
1496 ifp = (struct interface *)vty->index;
1497 ri = ifp->info;
1498
1499 /* Version 1 and 2. */
1500 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1501 return CMD_SUCCESS;
1502}
1503
1504DEFUN (no_ip_rip_receive_version,
1505 no_ip_rip_receive_version_cmd,
1506 "no ip rip receive version",
1507 NO_STR
1508 IP_STR
1509 "Routing Information Protocol\n"
1510 "Advertisement reception\n"
1511 "Version control\n")
1512{
1513 struct interface *ifp;
1514 struct rip_interface *ri;
1515
1516 ifp = (struct interface *)vty->index;
1517 ri = ifp->info;
1518
1519 ri->ri_receive = RI_RIP_UNSPEC;
1520 return CMD_SUCCESS;
1521}
1522
1523ALIAS (no_ip_rip_receive_version,
1524 no_ip_rip_receive_version_num_cmd,
1525 "no ip rip receive version (1|2)",
1526 NO_STR
1527 IP_STR
1528 "Routing Information Protocol\n"
1529 "Advertisement reception\n"
1530 "Version control\n"
1531 "Version 1\n"
1532 "Version 2\n")
1533
1534DEFUN (ip_rip_send_version,
1535 ip_rip_send_version_cmd,
1536 "ip rip send version (1|2)",
1537 IP_STR
1538 "Routing Information Protocol\n"
1539 "Advertisement transmission\n"
1540 "Version control\n"
1541 "RIP version 1\n"
1542 "RIP version 2\n")
1543{
1544 struct interface *ifp;
1545 struct rip_interface *ri;
1546
1547 ifp = (struct interface *)vty->index;
1548 ri = ifp->info;
1549
1550 /* Version 1. */
1551 if (atoi (argv[0]) == 1)
1552 {
1553 ri->ri_send = RI_RIP_VERSION_1;
1554 return CMD_SUCCESS;
1555 }
1556 if (atoi (argv[0]) == 2)
1557 {
1558 ri->ri_send = RI_RIP_VERSION_2;
1559 return CMD_SUCCESS;
1560 }
1561 return CMD_WARNING;
1562}
1563
1564DEFUN (ip_rip_send_version_1,
1565 ip_rip_send_version_1_cmd,
1566 "ip rip send version 1 2",
1567 IP_STR
1568 "Routing Information Protocol\n"
1569 "Advertisement transmission\n"
1570 "Version control\n"
1571 "RIP version 1\n"
1572 "RIP version 2\n")
1573{
1574 struct interface *ifp;
1575 struct rip_interface *ri;
1576
1577 ifp = (struct interface *)vty->index;
1578 ri = ifp->info;
1579
1580 /* Version 1 and 2. */
1581 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1582 return CMD_SUCCESS;
1583}
1584
1585DEFUN (ip_rip_send_version_2,
1586 ip_rip_send_version_2_cmd,
1587 "ip rip send version 2 1",
1588 IP_STR
1589 "Routing Information Protocol\n"
1590 "Advertisement transmission\n"
1591 "Version control\n"
1592 "RIP version 2\n"
1593 "RIP version 1\n")
1594{
1595 struct interface *ifp;
1596 struct rip_interface *ri;
1597
1598 ifp = (struct interface *)vty->index;
1599 ri = ifp->info;
1600
1601 /* Version 1 and 2. */
1602 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1603 return CMD_SUCCESS;
1604}
1605
1606DEFUN (no_ip_rip_send_version,
1607 no_ip_rip_send_version_cmd,
1608 "no ip rip send version",
1609 NO_STR
1610 IP_STR
1611 "Routing Information Protocol\n"
1612 "Advertisement transmission\n"
1613 "Version control\n")
1614{
1615 struct interface *ifp;
1616 struct rip_interface *ri;
1617
1618 ifp = (struct interface *)vty->index;
1619 ri = ifp->info;
1620
1621 ri->ri_send = RI_RIP_UNSPEC;
1622 return CMD_SUCCESS;
1623}
1624
1625ALIAS (no_ip_rip_send_version,
1626 no_ip_rip_send_version_num_cmd,
1627 "no ip rip send version (1|2)",
1628 NO_STR
1629 IP_STR
1630 "Routing Information Protocol\n"
1631 "Advertisement transmission\n"
1632 "Version control\n"
1633 "Version 1\n"
1634 "Version 2\n")
1635
1636DEFUN (ip_rip_authentication_mode,
1637 ip_rip_authentication_mode_cmd,
1638 "ip rip authentication mode (md5|text)",
1639 IP_STR
1640 "Routing Information Protocol\n"
1641 "Authentication control\n"
1642 "Authentication mode\n"
1643 "Keyed message digest\n"
1644 "Clear text authentication\n")
1645{
1646 struct interface *ifp;
1647 struct rip_interface *ri;
1648
1649 ifp = (struct interface *)vty->index;
1650 ri = ifp->info;
1651
paulca5e5162004-06-06 22:06:33 +00001652 if ( (argc < 1) || (argc > 2) )
1653 {
1654 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1655 return CMD_WARNING;
1656 }
1657
paul718e3742002-12-13 20:15:29 +00001658 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1659 ri->auth_type = RIP_AUTH_MD5;
1660 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1661 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1662 else
1663 {
1664 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1665 return CMD_WARNING;
1666 }
1667
paulca5e5162004-06-06 22:06:33 +00001668 if (argc == 1)
1669 return CMD_SUCCESS;
1670
1671 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1672 {
1673 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1674 return CMD_WARNING;
1675}
1676
1677 if (strncmp ("r", argv[1], 1) == 0)
1678 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1679 else if (strncmp ("o", argv[1], 1) == 0)
1680 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1681 else
1682 return CMD_WARNING;
1683
paul718e3742002-12-13 20:15:29 +00001684 return CMD_SUCCESS;
1685}
1686
paulca5e5162004-06-06 22:06:33 +00001687ALIAS (ip_rip_authentication_mode,
1688 ip_rip_authentication_mode_authlen_cmd,
1689 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1690 IP_STR
1691 "Routing Information Protocol\n"
1692 "Authentication control\n"
1693 "Authentication mode\n"
1694 "Keyed message digest\n"
1695 "Clear text authentication\n"
1696 "MD5 authentication data length\n"
1697 "RFC compatible\n"
1698 "Old ripd compatible\n")
1699
paul718e3742002-12-13 20:15:29 +00001700DEFUN (no_ip_rip_authentication_mode,
1701 no_ip_rip_authentication_mode_cmd,
1702 "no ip rip authentication mode",
1703 NO_STR
1704 IP_STR
1705 "Routing Information Protocol\n"
1706 "Authentication control\n"
1707 "Authentication mode\n")
1708{
1709 struct interface *ifp;
1710 struct rip_interface *ri;
1711
1712 ifp = (struct interface *)vty->index;
1713 ri = ifp->info;
1714
paul7755a8c2005-06-02 08:20:53 +00001715 ri->auth_type = RIP_NO_AUTH;
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. */
paul718e3742002-12-13 20:15:29 +00002052 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2053 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00002054
paul718e3742002-12-13 20:15:29 +00002055 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002056 {
2057 vty_out (vty, " ip rip authentication mode md5");
2058 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2059 vty_out (vty, " auth-length old-ripd");
2060 else
2061 vty_out (vty, " auth-length rfc");
2062 vty_out (vty, "%s", VTY_NEWLINE);
2063 }
paul718e3742002-12-13 20:15:29 +00002064
2065 if (ri->auth_str)
2066 vty_out (vty, " ip rip authentication string %s%s",
2067 ri->auth_str, VTY_NEWLINE);
2068
2069 if (ri->key_chain)
2070 vty_out (vty, " ip rip authentication key-chain %s%s",
2071 ri->key_chain, VTY_NEWLINE);
2072
2073 vty_out (vty, "!%s", VTY_NEWLINE);
2074 }
2075 return 0;
2076}
2077
2078int
2079config_write_rip_network (struct vty *vty, int config_mode)
2080{
hasso8a676be2004-10-08 06:36:38 +00002081 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002082 char *ifname;
2083 struct route_node *node;
2084
2085 /* Network type RIP enable interface statement. */
2086 for (node = route_top (rip_enable_network); node; node = route_next (node))
2087 if (node->info)
2088 vty_out (vty, "%s%s/%d%s",
2089 config_mode ? " network " : " ",
2090 inet_ntoa (node->p.u.prefix4),
2091 node->p.prefixlen,
2092 VTY_NEWLINE);
2093
2094 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002095 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002096 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2097 vty_out (vty, "%s%s%s",
2098 config_mode ? " network " : " ",
2099 ifname,
2100 VTY_NEWLINE);
2101
2102 /* RIP neighbors listing. */
2103 for (node = route_top (rip->neighbor); node; node = route_next (node))
2104 if (node->info)
2105 vty_out (vty, "%s%s%s",
2106 config_mode ? " neighbor " : " ",
2107 inet_ntoa (node->p.u.prefix4),
2108 VTY_NEWLINE);
2109
2110 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002111 if (config_mode) {
2112 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002113 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002114 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002115 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2116 vty_out (vty, " %spassive-interface %s%s",
2117 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2118 }
paul718e3742002-12-13 20:15:29 +00002119
2120 return 0;
2121}
2122
2123struct cmd_node interface_node =
2124{
2125 INTERFACE_NODE,
2126 "%s(config-if)# ",
2127 1,
2128};
2129
2130/* Called when interface structure allocated. */
2131int
2132rip_interface_new_hook (struct interface *ifp)
2133{
2134 ifp->info = rip_interface_new ();
2135 return 0;
2136}
2137
2138/* Called when interface structure deleted. */
2139int
2140rip_interface_delete_hook (struct interface *ifp)
2141{
2142 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002143 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002144 return 0;
2145}
2146
2147/* Allocate and initialize interface vector. */
2148void
2149rip_if_init ()
2150{
2151 /* Default initial size of interface vector. */
2152 if_init();
2153 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2154 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2155
2156 /* RIP network init. */
2157 rip_enable_interface = vector_init (1);
2158 rip_enable_network = route_table_init ();
2159
2160 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002161 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002162
2163 /* Install interface node. */
2164 install_node (&interface_node, rip_interface_config_write);
2165
2166 /* Install commands. */
2167 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002168 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002169 install_default (INTERFACE_NODE);
2170 install_element (INTERFACE_NODE, &interface_desc_cmd);
2171 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2172 install_element (RIP_NODE, &rip_network_cmd);
2173 install_element (RIP_NODE, &no_rip_network_cmd);
2174 install_element (RIP_NODE, &rip_neighbor_cmd);
2175 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2176
2177 install_element (RIP_NODE, &rip_passive_interface_cmd);
2178 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2179
2180 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2181 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2182 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2183 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2184 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2185
2186 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2187 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2188 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2189 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2190 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2191
2192 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002193 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002194 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2195 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002196 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002197
2198 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2199 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2200 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2201
2202 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2203 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2204 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2205
hasso16705132003-05-25 14:49:19 +00002206 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2207 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2208 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2209 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002210}