blob: 5fa4b7d328961aa24a39365dc9eed5652c7abc0a [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{
hasso3fb9cd62004-10-19 19:44:43 +0000142 struct in_addr addr;
paulcc1131a2003-10-15 23:20:17 +0000143 struct prefix_ipv4 *p;
paulc49ad8f2004-10-22 10:27:28 +0000144
145 assert (connected != NULL);
146
147 if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected))
148 p = (struct prefix_ipv4 *) connected->destination;
149 else
150 p = (struct prefix_ipv4 *) connected->address;
151
152 addr = p->prefix;
paul718e3742002-12-13 20:15:29 +0000153
paul1a517862004-08-19 04:03:08 +0000154 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
155 connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000156 {
157 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
158 "source address %s for interface %s",
159 sock, inet_ntoa(addr),
paulc49ad8f2004-10-22 10:27:28 +0000160 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000161 }
paul2c61ae32005-08-16 15:22:14 +0000162
hasso3fb9cd62004-10-19 19:44:43 +0000163 return;
164}
paul718e3742002-12-13 20:15:29 +0000165
166/* Send RIP request packet to specified interface. */
167void
168rip_request_interface_send (struct interface *ifp, u_char version)
169{
170 struct sockaddr_in to;
171
172 /* RIPv2 support multicast. */
173 if (version == RIPv2 && if_is_multicast (ifp))
174 {
175
176 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000177 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000178
paul931cd542004-01-23 15:31:42 +0000179 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000180 return;
181 }
182
183 /* RIPv1 and non multicast interface. */
184 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
185 {
paul1eb8ef22005-04-07 07:30:20 +0000186 struct listnode *cnode, *cnnode;
187 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000188
189 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000190 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000191
paul1eb8ef22005-04-07 07:30:20 +0000192 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000193 {
hasso3fb9cd62004-10-19 19:44:43 +0000194 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000195 {
196 memset (&to, 0, sizeof (struct sockaddr_in));
197 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000198 if (connected->destination)
199 /* use specified broadcast or point-to-point destination addr */
200 to.sin_addr = connected->destination->u.prefix4;
201 else
202 /* calculate the appropriate broadcast address */
203 to.sin_addr.s_addr =
204 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
205 connected->address->prefixlen);
paul718e3742002-12-13 20:15:29 +0000206
paul718e3742002-12-13 20:15:29 +0000207 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000208 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000209
paul931cd542004-01-23 15:31:42 +0000210 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000211 }
212 }
213 }
214}
215
216/* This will be executed when interface goes up. */
217void
218rip_request_interface (struct interface *ifp)
219{
220 struct rip_interface *ri;
221
222 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
223 if (if_is_loopback (ifp))
224 return;
225
226 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000227 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000228 return;
229
230 /* Fetch RIP interface information. */
231 ri = ifp->info;
232
233
234 /* If there is no version configuration in the interface,
235 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000236 {
237 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
238 rip->version_send : ri->ri_send);
239 if (vsend & RIPv1)
240 rip_request_interface_send (ifp, RIPv1);
241 if (vsend & RIPv2)
242 rip_request_interface_send (ifp, RIPv2);
243 }
paul718e3742002-12-13 20:15:29 +0000244}
245
246/* Send RIP request to the neighbor. */
247void
248rip_request_neighbor (struct in_addr addr)
249{
250 struct sockaddr_in to;
251
252 memset (&to, 0, sizeof (struct sockaddr_in));
253 to.sin_port = htons (RIP_PORT_DEFAULT);
254 to.sin_addr = addr;
255
paul931cd542004-01-23 15:31:42 +0000256 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000257}
258
259/* Request routes at all interfaces. */
260void
261rip_request_neighbor_all ()
262{
263 struct route_node *rp;
264
265 if (! rip)
266 return;
267
268 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000269 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000270
271 /* Send request to all neighbor. */
272 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
273 if (rp->info)
274 rip_request_neighbor (rp->p.u.prefix4);
275}
276
277/* Multicast packet receive socket. */
278int
279rip_multicast_join (struct interface *ifp, int sock)
280{
hasso52dc7ee2004-09-23 19:18:23 +0000281 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000282 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000283
paul2e3b2e42002-12-13 21:03:13 +0000284 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000285 {
286 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000287 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000288
paul1eb8ef22005-04-07 07:30:20 +0000289 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000290 {
291 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000292 struct in_addr group;
293
paul1eb8ef22005-04-07 07:30:20 +0000294 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000295
296 if (p->family != AF_INET)
297 continue;
298
299 group.s_addr = htonl (INADDR_RIP_GROUP);
300 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
301 return -1;
302 else
303 return 0;
304 }
305 }
306 return 0;
307}
308
309/* Leave from multicast group. */
310void
311rip_multicast_leave (struct interface *ifp, int sock)
312{
hasso52dc7ee2004-09-23 19:18:23 +0000313 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000314 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000315
316 if (if_is_up (ifp) && if_is_multicast (ifp))
317 {
318 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000319 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000320
paul1eb8ef22005-04-07 07:30:20 +0000321 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000322 {
323 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000324 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000325
paul718e3742002-12-13 20:15:29 +0000326 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000327
paul718e3742002-12-13 20:15:29 +0000328 if (p->family != AF_INET)
329 continue;
330
331 group.s_addr = htonl (INADDR_RIP_GROUP);
332 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
333 return;
334 }
335 }
336}
337
338/* Is there and address on interface that I could use ? */
339int
340rip_if_ipv4_address_check (struct interface *ifp)
341{
342 struct listnode *nn;
343 struct connected *connected;
344 int count = 0;
345
paul1eb8ef22005-04-07 07:30:20 +0000346 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
347 {
348 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000349
paul1eb8ef22005-04-07 07:30:20 +0000350 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000351
paul1eb8ef22005-04-07 07:30:20 +0000352 if (p->family == AF_INET)
353 count++;
354 }
paul718e3742002-12-13 20:15:29 +0000355
356 return count;
357}
paul31a476c2003-09-29 19:54:53 +0000358
359
360
361
362/* Does this address belongs to me ? */
363int
364if_check_address (struct in_addr addr)
365{
hasso52dc7ee2004-09-23 19:18:23 +0000366 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000367 struct interface *ifp;
368
369 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000370 {
hasso52dc7ee2004-09-23 19:18:23 +0000371 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000372 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000373
paul1eb8ef22005-04-07 07:30:20 +0000374 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000375 {
paul31a476c2003-09-29 19:54:53 +0000376 struct prefix_ipv4 *p;
377
paul31a476c2003-09-29 19:54:53 +0000378 p = (struct prefix_ipv4 *) connected->address;
379
380 if (p->family != AF_INET)
381 continue;
382
383 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
384 return 1;
385 }
386 }
387 return 0;
388}
389
390/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
391int
392if_valid_neighbor (struct in_addr addr)
393{
hasso52dc7ee2004-09-23 19:18:23 +0000394 struct listnode *node;
paul31a476c2003-09-29 19:54:53 +0000395 struct connected *connected = NULL;
paul1eb8ef22005-04-07 07:30:20 +0000396 struct interface *ifp;
paul31a476c2003-09-29 19:54:53 +0000397 struct prefix_ipv4 *p;
hasso3fb9cd62004-10-19 19:44:43 +0000398 struct prefix_ipv4 pa;
399
400 pa.family = AF_INET;
401 pa.prefix = addr;
402 pa.prefixlen = IPV4_MAX_PREFIXLEN;
paul31a476c2003-09-29 19:54:53 +0000403
paul1eb8ef22005-04-07 07:30:20 +0000404 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000405 {
hasso52dc7ee2004-09-23 19:18:23 +0000406 struct listnode *cnode;
paul31a476c2003-09-29 19:54:53 +0000407
paul1eb8ef22005-04-07 07:30:20 +0000408 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000409 {
paul31a476c2003-09-29 19:54:53 +0000410 if (if_is_pointopoint (ifp))
411 {
412 p = (struct prefix_ipv4 *) connected->address;
413
414 if (p && p->family == AF_INET)
415 {
416 if (IPV4_ADDR_SAME (&p->prefix, &addr))
417 return 1;
418
419 p = (struct prefix_ipv4 *) connected->destination;
hasso3fb9cd62004-10-19 19:44:43 +0000420 if (p)
421 {
422 if (IPV4_ADDR_SAME (&p->prefix, &addr))
423 return 1;
424 }
425 else
426 {
427 if (prefix_match(connected->address,(struct prefix *)&pa))
428 return 1;
429 }
paul31a476c2003-09-29 19:54:53 +0000430 }
431 }
432 else
433 {
hasso3fb9cd62004-10-19 19:44:43 +0000434 if ((connected->address->family == AF_INET) &&
435 prefix_match(connected->address,(struct prefix *)&pa))
436 return 1;
paul31a476c2003-09-29 19:54:53 +0000437 }
438 }
439 }
440 return 0;
441}
paul718e3742002-12-13 20:15:29 +0000442
443/* Inteface link down message processing. */
444int
445rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
446{
447 struct interface *ifp;
448 struct stream *s;
449
450 s = zclient->ibuf;
451
452 /* zebra_interface_state_read() updates interface structure in
453 iflist. */
454 ifp = zebra_interface_state_read(s);
455
456 if (ifp == NULL)
457 return 0;
458
459 rip_if_down(ifp);
460
461 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000462 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is down",
paul718e3742002-12-13 20:15:29 +0000463 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
464
465 return 0;
466}
467
468/* Inteface link up message processing */
469int
470rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
471{
472 struct interface *ifp;
473
474 /* zebra_interface_state_read () updates interface structure in
475 iflist. */
476 ifp = zebra_interface_state_read (zclient->ibuf);
477
478 if (ifp == NULL)
479 return 0;
480
481 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000482 zlog_debug ("interface %s index %d flags %ld metric %d mtu %d is up",
paul718e3742002-12-13 20:15:29 +0000483 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
484
485 /* Check if this interface is RIP enabled or not.*/
486 rip_enable_apply (ifp);
487
488 /* Check for a passive interface */
489 rip_passive_interface_apply (ifp);
490
491 /* Apply distribute list to the all interface. */
492 rip_distribute_update_interface (ifp);
493
494 return 0;
495}
496
497/* Inteface addition message from zebra. */
498int
499rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
500{
501 struct interface *ifp;
502
503 ifp = zebra_interface_add_read (zclient->ibuf);
504
505 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000506 zlog_debug ("interface add %s index %d flags %ld metric %d mtu %d",
paul718e3742002-12-13 20:15:29 +0000507 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
508
509 /* Check if this interface is RIP enabled or not.*/
510 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000511
512 /* Check for a passive interface */
513 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000514
515 /* Apply distribute list to the all interface. */
516 rip_distribute_update_interface (ifp);
517
518 /* rip_request_neighbor_all (); */
519
hasso16705132003-05-25 14:49:19 +0000520 /* Check interface routemap. */
521 rip_if_rmap_update_interface (ifp);
522
paul718e3742002-12-13 20:15:29 +0000523 return 0;
524}
525
526int
527rip_interface_delete (int command, struct zclient *zclient,
528 zebra_size_t length)
529{
530 struct interface *ifp;
531 struct stream *s;
532
533
534 s = zclient->ibuf;
535 /* zebra_interface_state_read() updates interface structure in iflist */
536 ifp = zebra_interface_state_read(s);
537
538 if (ifp == NULL)
539 return 0;
540
541 if (if_is_up (ifp)) {
542 rip_if_down(ifp);
543 }
544
545 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
546 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
547
548 /* To support pseudo interface do not free interface structure. */
549 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000550 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000551
552 return 0;
553}
554
555void
556rip_interface_clean ()
557{
hasso52dc7ee2004-09-23 19:18:23 +0000558 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000559 struct interface *ifp;
560 struct rip_interface *ri;
561
paul1eb8ef22005-04-07 07:30:20 +0000562 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000563 {
paul718e3742002-12-13 20:15:29 +0000564 ri = ifp->info;
565
566 ri->enable_network = 0;
567 ri->enable_interface = 0;
568 ri->running = 0;
569
570 if (ri->t_wakeup)
571 {
572 thread_cancel (ri->t_wakeup);
573 ri->t_wakeup = NULL;
574 }
575 }
576}
577
578void
579rip_interface_reset ()
580{
hasso52dc7ee2004-09-23 19:18:23 +0000581 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000582 struct interface *ifp;
583 struct rip_interface *ri;
584
paul1eb8ef22005-04-07 07:30:20 +0000585 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000586 {
paul718e3742002-12-13 20:15:29 +0000587 ri = ifp->info;
588
589 ri->enable_network = 0;
590 ri->enable_interface = 0;
591 ri->running = 0;
592
593 ri->ri_send = RI_RIP_UNSPEC;
594 ri->ri_receive = RI_RIP_UNSPEC;
595
paul7755a8c2005-06-02 08:20:53 +0000596 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000597
598 if (ri->auth_str)
599 {
600 free (ri->auth_str);
601 ri->auth_str = NULL;
602 }
603 if (ri->key_chain)
604 {
605 free (ri->key_chain);
606 ri->key_chain = NULL;
607 }
608
hasso16705132003-05-25 14:49:19 +0000609 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
610 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000611
612 ri->list[RIP_FILTER_IN] = NULL;
613 ri->list[RIP_FILTER_OUT] = NULL;
614
615 ri->prefix[RIP_FILTER_IN] = NULL;
616 ri->prefix[RIP_FILTER_OUT] = NULL;
617
618 if (ri->t_wakeup)
619 {
620 thread_cancel (ri->t_wakeup);
621 ri->t_wakeup = NULL;
622 }
623
624 ri->recv_badpackets = 0;
625 ri->recv_badroutes = 0;
626 ri->sent_updates = 0;
627
628 ri->passive = 0;
629 }
630}
631
632int
633rip_if_down(struct interface *ifp)
634{
635 struct route_node *rp;
636 struct rip_info *rinfo;
637 struct rip_interface *ri = NULL;
638 if (rip)
639 {
640 for (rp = route_top (rip->table); rp; rp = route_next (rp))
641 if ((rinfo = rp->info) != NULL)
642 {
643 /* Routes got through this interface. */
644 if (rinfo->ifindex == ifp->ifindex &&
645 rinfo->type == ZEBRA_ROUTE_RIP &&
646 rinfo->sub_type == RIP_ROUTE_RTE)
647 {
648 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
649 &rinfo->nexthop,
650 rinfo->ifindex);
651
652 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
653 (struct prefix_ipv4 *)&rp->p,
654 rinfo->ifindex);
655 }
656 else
657 {
658 /* All redistributed routes but static and system */
659 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000660 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000661 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
662 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
663 (struct prefix_ipv4 *)&rp->p,
664 rinfo->ifindex);
665 }
666 }
667 }
668
669 ri = ifp->info;
670
671 if (ri->running)
672 {
673 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000674 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000675
676 /* Leave from multicast group. */
677 rip_multicast_leave (ifp, rip->sock);
678
679 ri->running = 0;
680 }
681
682 return 0;
683}
684
685/* Needed for stop RIP process. */
686void
687rip_if_down_all ()
688{
689 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000690 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000691
paul1eb8ef22005-04-07 07:30:20 +0000692 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
693 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000694}
695
hasso16705132003-05-25 14:49:19 +0000696static void
697rip_apply_address_add (struct connected *ifc) {
698 struct prefix_ipv4 address;
699 struct prefix *p;
700
701 if (!rip)
702 return;
703
704 if (! if_is_up(ifc->ifp))
705 return;
706
707 p = ifc->address;
708
709 memset (&address, 0, sizeof (address));
710 address.family = p->family;
711 address.prefix = p->u.prefix4;
712 address.prefixlen = p->prefixlen;
713 apply_mask_ipv4(&address);
714
715 /* Check if this interface is RIP enabled or not
716 or Check if this address's prefix is RIP enabled */
717 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
718 (rip_enable_network_lookup2(ifc) >= 0))
719 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
720 &address, ifc->ifp->ifindex, NULL);
721
722}
723
paul718e3742002-12-13 20:15:29 +0000724int
725rip_interface_address_add (int command, struct zclient *zclient,
726 zebra_size_t length)
727{
728 struct connected *ifc;
729 struct prefix *p;
730
paul0a589352004-05-08 11:48:26 +0000731 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
732 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000733
734 if (ifc == NULL)
735 return 0;
736
737 p = ifc->address;
738
739 if (p->family == AF_INET)
740 {
741 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000742 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000743 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000744
paul878ef2e2003-09-23 23:41:50 +0000745 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000746 /* Check if this prefix needs to be redistributed */
747 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000748
749#ifdef HAVE_SNMP
750 rip_ifaddr_add (ifc->ifp, ifc);
751#endif /* HAVE_SNMP */
752 }
753
754 return 0;
755}
756
hasso16705132003-05-25 14:49:19 +0000757static void
758rip_apply_address_del (struct connected *ifc) {
759 struct prefix_ipv4 address;
760 struct prefix *p;
761
762 if (!rip)
763 return;
764
765 if (! if_is_up(ifc->ifp))
766 return;
767
768 p = ifc->address;
769
770 memset (&address, 0, sizeof (address));
771 address.family = p->family;
772 address.prefix = p->u.prefix4;
773 address.prefixlen = p->prefixlen;
774 apply_mask_ipv4(&address);
775
776 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
777 &address, ifc->ifp->ifindex);
778}
779
paul718e3742002-12-13 20:15:29 +0000780int
781rip_interface_address_delete (int command, struct zclient *zclient,
782 zebra_size_t length)
783{
784 struct connected *ifc;
785 struct prefix *p;
786
paul0a589352004-05-08 11:48:26 +0000787 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
788 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000789
790 if (ifc)
791 {
792 p = ifc->address;
793 if (p->family == AF_INET)
794 {
795 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000796 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000797 inet_ntoa (p->u.prefix4), p->prefixlen);
798
799#ifdef HAVE_SNMP
800 rip_ifaddr_delete (ifc->ifp, ifc);
801#endif /* HAVE_SNMP */
802
hasso16705132003-05-25 14:49:19 +0000803 /* Chech wether this prefix needs to be removed */
804 rip_apply_address_del(ifc);
805
paul718e3742002-12-13 20:15:29 +0000806 }
807
808 connected_free (ifc);
809
810 }
811
812 return 0;
813}
814
815/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000816/* Check wether the interface has at least a connected prefix that
817 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000818int
hasso16705132003-05-25 14:49:19 +0000819rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000820{
paul1eb8ef22005-04-07 07:30:20 +0000821 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000822 struct connected *connected;
823 struct prefix_ipv4 address;
824
paul1eb8ef22005-04-07 07:30:20 +0000825 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
826 {
827 struct prefix *p;
828 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000829
paul1eb8ef22005-04-07 07:30:20 +0000830 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000831
paul1eb8ef22005-04-07 07:30:20 +0000832 if (p->family == AF_INET)
833 {
834 address.family = AF_INET;
835 address.prefix = p->u.prefix4;
836 address.prefixlen = IPV4_MAX_BITLEN;
837
838 node = route_node_match (rip_enable_network,
839 (struct prefix *)&address);
840 if (node)
841 {
842 route_unlock_node (node);
843 return 1;
844 }
845 }
846 }
paul718e3742002-12-13 20:15:29 +0000847 return -1;
848}
849
hasso16705132003-05-25 14:49:19 +0000850/* Check wether connected is within the ripng_enable_network table. */
851int
852rip_enable_network_lookup2 (struct connected *connected)
853{
854 struct prefix_ipv4 address;
855 struct prefix *p;
856
857 p = connected->address;
858
859 if (p->family == AF_INET) {
860 struct route_node *node;
861
862 address.family = p->family;
863 address.prefix = p->u.prefix4;
864 address.prefixlen = IPV4_MAX_BITLEN;
865
866 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
867 node = route_node_match (rip_enable_network,
868 (struct prefix *)&address);
869
870 if (node) {
871 route_unlock_node (node);
872 return 1;
873 }
874 }
875
876 return -1;
877}
paul718e3742002-12-13 20:15:29 +0000878/* Add RIP enable network. */
879int
880rip_enable_network_add (struct prefix *p)
881{
882 struct route_node *node;
883
884 node = route_node_get (rip_enable_network, p);
885
886 if (node->info)
887 {
888 route_unlock_node (node);
889 return -1;
890 }
891 else
hasso8a676be2004-10-08 06:36:38 +0000892 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000893
hasso16705132003-05-25 14:49:19 +0000894 /* XXX: One should find a better solution than a generic one */
895 rip_enable_apply_all();
896
paul718e3742002-12-13 20:15:29 +0000897 return 1;
898}
899
900/* Delete RIP enable network. */
901int
902rip_enable_network_delete (struct prefix *p)
903{
904 struct route_node *node;
905
906 node = route_node_lookup (rip_enable_network, p);
907 if (node)
908 {
909 node->info = NULL;
910
911 /* Unlock info lock. */
912 route_unlock_node (node);
913
914 /* Unlock lookup lock. */
915 route_unlock_node (node);
916
hasso16705132003-05-25 14:49:19 +0000917 /* XXX: One should find a better solution than a generic one */
918 rip_enable_apply_all ();
919
paul718e3742002-12-13 20:15:29 +0000920 return 1;
921 }
922 return -1;
923}
924
925/* Check interface is enabled by ifname statement. */
926int
hasso98b718a2004-10-11 12:57:57 +0000927rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000928{
hasso8a676be2004-10-08 06:36:38 +0000929 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000930 char *str;
931
paul55468c82005-03-14 20:19:01 +0000932 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000933 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
934 if (strcmp (str, ifname) == 0)
935 return i;
936 return -1;
937}
938
939/* Add interface to rip_enable_if. */
940int
hasso98b718a2004-10-11 12:57:57 +0000941rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000942{
943 int ret;
944
945 ret = rip_enable_if_lookup (ifname);
946 if (ret >= 0)
947 return -1;
948
949 vector_set (rip_enable_interface, strdup (ifname));
950
hasso16705132003-05-25 14:49:19 +0000951 rip_enable_apply_all(); /* TODOVJ */
952
paul718e3742002-12-13 20:15:29 +0000953 return 1;
954}
955
956/* Delete interface from rip_enable_if. */
957int
hasso98b718a2004-10-11 12:57:57 +0000958rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000959{
960 int index;
961 char *str;
962
963 index = rip_enable_if_lookup (ifname);
964 if (index < 0)
965 return -1;
966
967 str = vector_slot (rip_enable_interface, index);
968 free (str);
969 vector_unset (rip_enable_interface, index);
970
hasso16705132003-05-25 14:49:19 +0000971 rip_enable_apply_all(); /* TODOVJ */
972
paul718e3742002-12-13 20:15:29 +0000973 return 1;
974}
975
976/* Join to multicast group and send request to the interface. */
977int
978rip_interface_wakeup (struct thread *t)
979{
980 struct interface *ifp;
981 struct rip_interface *ri;
982
983 /* Get interface. */
984 ifp = THREAD_ARG (t);
985
986 ri = ifp->info;
987 ri->t_wakeup = NULL;
988
989 /* Join to multicast group. */
990 if (rip_multicast_join (ifp, rip->sock) < 0)
991 {
992 zlog_err ("multicast join failed, interface %s not running", ifp->name);
993 return 0;
994 }
995
996 /* Set running flag. */
997 ri->running = 1;
998
999 /* Send RIP request to the interface. */
1000 rip_request_interface (ifp);
1001
1002 return 0;
1003}
1004
1005int rip_redistribute_check (int);
1006
1007void
1008rip_connect_set (struct interface *ifp, int set)
1009{
paul1eb8ef22005-04-07 07:30:20 +00001010 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001011 struct connected *connected;
1012 struct prefix_ipv4 address;
1013
paul1eb8ef22005-04-07 07:30:20 +00001014 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
1015 {
1016 struct prefix *p;
1017 p = connected->address;
paul718e3742002-12-13 20:15:29 +00001018
paul1eb8ef22005-04-07 07:30:20 +00001019 if (p->family != AF_INET)
1020 continue;
paul718e3742002-12-13 20:15:29 +00001021
paul1eb8ef22005-04-07 07:30:20 +00001022 address.family = AF_INET;
1023 address.prefix = p->u.prefix4;
1024 address.prefixlen = p->prefixlen;
1025 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +00001026
paul1eb8ef22005-04-07 07:30:20 +00001027 if (set) {
1028 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1029 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1030 (rip_enable_network_lookup2(connected) >= 0))
1031 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1032 &address, connected->ifp->ifindex, NULL);
1033 } else
1034 {
1035 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1036 &address, connected->ifp->ifindex);
1037 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1038 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1039 &address, connected->ifp->ifindex, NULL);
1040 }
1041 }
paul718e3742002-12-13 20:15:29 +00001042}
1043
1044/* Update interface status. */
1045void
1046rip_enable_apply (struct interface *ifp)
1047{
1048 int ret;
1049 struct rip_interface *ri = NULL;
1050
1051 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001052 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001053 return;
1054
1055 ri = ifp->info;
1056
1057 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001058 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001059
1060 /* If the interface is matched. */
1061 if (ret > 0)
1062 ri->enable_network = 1;
1063 else
1064 ri->enable_network = 0;
1065
1066 /* Check interface name configuration. */
1067 ret = rip_enable_if_lookup (ifp->name);
1068 if (ret >= 0)
1069 ri->enable_interface = 1;
1070 else
1071 ri->enable_interface = 0;
1072
1073 /* any interface MUST have an IPv4 address */
1074 if ( ! rip_if_ipv4_address_check (ifp) )
1075 {
1076 ri->enable_network = 0;
1077 ri->enable_interface = 0;
1078 }
1079
1080 /* Update running status of the interface. */
1081 if (ri->enable_network || ri->enable_interface)
1082 {
paul718e3742002-12-13 20:15:29 +00001083 {
1084 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001085 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001086
1087 /* Add interface wake up thread. */
1088 if (! ri->t_wakeup)
1089 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1090 ifp, 1);
1091 rip_connect_set (ifp, 1);
1092 }
1093 }
1094 else
1095 {
1096 if (ri->running)
1097 {
hasso16705132003-05-25 14:49:19 +00001098 /* Might as well clean up the route table as well
1099 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1100 **/
paul718e3742002-12-13 20:15:29 +00001101 rip_if_down(ifp);
1102
paul718e3742002-12-13 20:15:29 +00001103 rip_connect_set (ifp, 0);
1104 }
1105 }
1106}
1107
1108/* Apply network configuration to all interface. */
1109void
1110rip_enable_apply_all ()
1111{
1112 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001113 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001114
1115 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001116 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1117 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001118}
1119
1120int
1121rip_neighbor_lookup (struct sockaddr_in *from)
1122{
1123 struct prefix_ipv4 p;
1124 struct route_node *node;
1125
1126 memset (&p, 0, sizeof (struct prefix_ipv4));
1127 p.family = AF_INET;
1128 p.prefix = from->sin_addr;
1129 p.prefixlen = IPV4_MAX_BITLEN;
1130
1131 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1132 if (node)
1133 {
1134 route_unlock_node (node);
1135 return 1;
1136 }
1137 return 0;
1138}
1139
1140/* Add new RIP neighbor to the neighbor tree. */
1141int
1142rip_neighbor_add (struct prefix_ipv4 *p)
1143{
1144 struct route_node *node;
1145
1146 node = route_node_get (rip->neighbor, (struct prefix *) p);
1147
1148 if (node->info)
1149 return -1;
1150
1151 node->info = rip->neighbor;
1152
1153 return 0;
1154}
1155
1156/* Delete RIP neighbor from the neighbor tree. */
1157int
1158rip_neighbor_delete (struct prefix_ipv4 *p)
1159{
1160 struct route_node *node;
1161
1162 /* Lock for look up. */
1163 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1164 if (! node)
1165 return -1;
1166
1167 node->info = NULL;
1168
1169 /* Unlock lookup lock. */
1170 route_unlock_node (node);
1171
1172 /* Unlock real neighbor information lock. */
1173 route_unlock_node (node);
1174
1175 return 0;
1176}
1177
1178/* Clear all network and neighbor configuration. */
1179void
1180rip_clean_network ()
1181{
hasso8a676be2004-10-08 06:36:38 +00001182 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001183 char *str;
1184 struct route_node *rn;
1185
1186 /* rip_enable_network. */
1187 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1188 if (rn->info)
1189 {
1190 rn->info = NULL;
1191 route_unlock_node (rn);
1192 }
1193
1194 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001195 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001196 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1197 {
1198 free (str);
1199 vector_slot (rip_enable_interface, i) = NULL;
1200 }
1201}
1202
1203/* Utility function for looking up passive interface settings. */
1204int
hasso98b718a2004-10-11 12:57:57 +00001205rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001206{
hasso8a676be2004-10-08 06:36:38 +00001207 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001208 char *str;
1209
paul55468c82005-03-14 20:19:01 +00001210 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001211 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001212 if (strcmp (str, ifname) == 0)
1213 return i;
1214 return -1;
1215}
1216
1217void
1218rip_passive_interface_apply (struct interface *ifp)
1219{
paul718e3742002-12-13 20:15:29 +00001220 struct rip_interface *ri;
1221
1222 ri = ifp->info;
1223
paul4aaff3f2003-06-07 01:04:45 +00001224 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1225 passive_default : !passive_default);
1226
1227 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001228 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001229}
1230
1231void
1232rip_passive_interface_apply_all ()
1233{
1234 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001235 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001236
paul1eb8ef22005-04-07 07:30:20 +00001237 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1238 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001239}
1240
1241/* Passive interface. */
1242int
hasso98b718a2004-10-11 12:57:57 +00001243rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001244{
paul4aaff3f2003-06-07 01:04:45 +00001245 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001246 return CMD_WARNING;
1247
paul4aaff3f2003-06-07 01:04:45 +00001248 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001249
1250 rip_passive_interface_apply_all ();
1251
1252 return CMD_SUCCESS;
1253}
1254
1255int
hasso98b718a2004-10-11 12:57:57 +00001256rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001257{
1258 int i;
1259 char *str;
1260
paul4aaff3f2003-06-07 01:04:45 +00001261 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001262 if (i < 0)
1263 return CMD_WARNING;
1264
paul4aaff3f2003-06-07 01:04:45 +00001265 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001266 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001267 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001268
1269 rip_passive_interface_apply_all ();
1270
1271 return CMD_SUCCESS;
1272}
1273
1274/* Free all configured RIP passive-interface settings. */
1275void
paul4aaff3f2003-06-07 01:04:45 +00001276rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001277{
hasso8a676be2004-10-08 06:36:38 +00001278 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001279 char *str;
1280
paul55468c82005-03-14 20:19:01 +00001281 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001282 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001283 {
1284 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001285 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001286 }
1287 rip_passive_interface_apply_all ();
1288}
1289
1290/* RIP enable network or interface configuration. */
1291DEFUN (rip_network,
1292 rip_network_cmd,
1293 "network (A.B.C.D/M|WORD)",
1294 "Enable routing on an IP network\n"
1295 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1296 "Interface name\n")
1297{
1298 int ret;
1299 struct prefix_ipv4 p;
1300
1301 ret = str2prefix_ipv4 (argv[0], &p);
1302
1303 if (ret)
1304 ret = rip_enable_network_add ((struct prefix *) &p);
1305 else
1306 ret = rip_enable_if_add (argv[0]);
1307
1308 if (ret < 0)
1309 {
1310 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1311 VTY_NEWLINE);
1312 return CMD_WARNING;
1313 }
1314
paul718e3742002-12-13 20:15:29 +00001315 return CMD_SUCCESS;
1316}
1317
1318/* RIP enable network or interface configuration. */
1319DEFUN (no_rip_network,
1320 no_rip_network_cmd,
1321 "no network (A.B.C.D/M|WORD)",
1322 NO_STR
1323 "Enable routing on an IP network\n"
1324 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1325 "Interface name\n")
1326{
1327 int ret;
1328 struct prefix_ipv4 p;
1329
1330 ret = str2prefix_ipv4 (argv[0], &p);
1331
1332 if (ret)
1333 ret = rip_enable_network_delete ((struct prefix *) &p);
1334 else
1335 ret = rip_enable_if_delete (argv[0]);
1336
1337 if (ret < 0)
1338 {
1339 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1340 VTY_NEWLINE);
1341 return CMD_WARNING;
1342 }
1343
paul718e3742002-12-13 20:15:29 +00001344 return CMD_SUCCESS;
1345}
1346
1347/* RIP neighbor configuration set. */
1348DEFUN (rip_neighbor,
1349 rip_neighbor_cmd,
1350 "neighbor A.B.C.D",
1351 "Specify a neighbor router\n"
1352 "Neighbor address\n")
1353{
1354 int ret;
1355 struct prefix_ipv4 p;
1356
1357 ret = str2prefix_ipv4 (argv[0], &p);
1358
1359 if (ret <= 0)
1360 {
1361 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1362 return CMD_WARNING;
1363 }
1364
1365 rip_neighbor_add (&p);
1366
1367 return CMD_SUCCESS;
1368}
1369
1370/* RIP neighbor configuration unset. */
1371DEFUN (no_rip_neighbor,
1372 no_rip_neighbor_cmd,
1373 "no neighbor A.B.C.D",
1374 NO_STR
1375 "Specify a neighbor router\n"
1376 "Neighbor address\n")
1377{
1378 int ret;
1379 struct prefix_ipv4 p;
1380
1381 ret = str2prefix_ipv4 (argv[0], &p);
1382
1383 if (ret <= 0)
1384 {
1385 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1386 return CMD_WARNING;
1387 }
1388
1389 rip_neighbor_delete (&p);
1390
1391 return CMD_SUCCESS;
1392}
1393
1394DEFUN (ip_rip_receive_version,
1395 ip_rip_receive_version_cmd,
1396 "ip rip receive version (1|2)",
1397 IP_STR
1398 "Routing Information Protocol\n"
1399 "Advertisement reception\n"
1400 "Version control\n"
1401 "RIP version 1\n"
1402 "RIP version 2\n")
1403{
1404 struct interface *ifp;
1405 struct rip_interface *ri;
1406
1407 ifp = (struct interface *)vty->index;
1408 ri = ifp->info;
1409
1410 /* Version 1. */
1411 if (atoi (argv[0]) == 1)
1412 {
1413 ri->ri_receive = RI_RIP_VERSION_1;
1414 return CMD_SUCCESS;
1415 }
1416 if (atoi (argv[0]) == 2)
1417 {
1418 ri->ri_receive = RI_RIP_VERSION_2;
1419 return CMD_SUCCESS;
1420 }
1421 return CMD_WARNING;
1422}
1423
1424DEFUN (ip_rip_receive_version_1,
1425 ip_rip_receive_version_1_cmd,
1426 "ip rip receive version 1 2",
1427 IP_STR
1428 "Routing Information Protocol\n"
1429 "Advertisement reception\n"
1430 "Version control\n"
1431 "RIP version 1\n"
1432 "RIP version 2\n")
1433{
1434 struct interface *ifp;
1435 struct rip_interface *ri;
1436
1437 ifp = (struct interface *)vty->index;
1438 ri = ifp->info;
1439
1440 /* Version 1 and 2. */
1441 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1442 return CMD_SUCCESS;
1443}
1444
1445DEFUN (ip_rip_receive_version_2,
1446 ip_rip_receive_version_2_cmd,
1447 "ip rip receive version 2 1",
1448 IP_STR
1449 "Routing Information Protocol\n"
1450 "Advertisement reception\n"
1451 "Version control\n"
1452 "RIP version 2\n"
1453 "RIP version 1\n")
1454{
1455 struct interface *ifp;
1456 struct rip_interface *ri;
1457
1458 ifp = (struct interface *)vty->index;
1459 ri = ifp->info;
1460
1461 /* Version 1 and 2. */
1462 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1463 return CMD_SUCCESS;
1464}
1465
1466DEFUN (no_ip_rip_receive_version,
1467 no_ip_rip_receive_version_cmd,
1468 "no ip rip receive version",
1469 NO_STR
1470 IP_STR
1471 "Routing Information Protocol\n"
1472 "Advertisement reception\n"
1473 "Version control\n")
1474{
1475 struct interface *ifp;
1476 struct rip_interface *ri;
1477
1478 ifp = (struct interface *)vty->index;
1479 ri = ifp->info;
1480
1481 ri->ri_receive = RI_RIP_UNSPEC;
1482 return CMD_SUCCESS;
1483}
1484
1485ALIAS (no_ip_rip_receive_version,
1486 no_ip_rip_receive_version_num_cmd,
1487 "no ip rip receive version (1|2)",
1488 NO_STR
1489 IP_STR
1490 "Routing Information Protocol\n"
1491 "Advertisement reception\n"
1492 "Version control\n"
1493 "Version 1\n"
1494 "Version 2\n")
1495
1496DEFUN (ip_rip_send_version,
1497 ip_rip_send_version_cmd,
1498 "ip rip send version (1|2)",
1499 IP_STR
1500 "Routing Information Protocol\n"
1501 "Advertisement transmission\n"
1502 "Version control\n"
1503 "RIP version 1\n"
1504 "RIP version 2\n")
1505{
1506 struct interface *ifp;
1507 struct rip_interface *ri;
1508
1509 ifp = (struct interface *)vty->index;
1510 ri = ifp->info;
1511
1512 /* Version 1. */
1513 if (atoi (argv[0]) == 1)
1514 {
1515 ri->ri_send = RI_RIP_VERSION_1;
1516 return CMD_SUCCESS;
1517 }
1518 if (atoi (argv[0]) == 2)
1519 {
1520 ri->ri_send = RI_RIP_VERSION_2;
1521 return CMD_SUCCESS;
1522 }
1523 return CMD_WARNING;
1524}
1525
1526DEFUN (ip_rip_send_version_1,
1527 ip_rip_send_version_1_cmd,
1528 "ip rip send version 1 2",
1529 IP_STR
1530 "Routing Information Protocol\n"
1531 "Advertisement transmission\n"
1532 "Version control\n"
1533 "RIP version 1\n"
1534 "RIP version 2\n")
1535{
1536 struct interface *ifp;
1537 struct rip_interface *ri;
1538
1539 ifp = (struct interface *)vty->index;
1540 ri = ifp->info;
1541
1542 /* Version 1 and 2. */
1543 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1544 return CMD_SUCCESS;
1545}
1546
1547DEFUN (ip_rip_send_version_2,
1548 ip_rip_send_version_2_cmd,
1549 "ip rip send version 2 1",
1550 IP_STR
1551 "Routing Information Protocol\n"
1552 "Advertisement transmission\n"
1553 "Version control\n"
1554 "RIP version 2\n"
1555 "RIP version 1\n")
1556{
1557 struct interface *ifp;
1558 struct rip_interface *ri;
1559
1560 ifp = (struct interface *)vty->index;
1561 ri = ifp->info;
1562
1563 /* Version 1 and 2. */
1564 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1565 return CMD_SUCCESS;
1566}
1567
1568DEFUN (no_ip_rip_send_version,
1569 no_ip_rip_send_version_cmd,
1570 "no ip rip send version",
1571 NO_STR
1572 IP_STR
1573 "Routing Information Protocol\n"
1574 "Advertisement transmission\n"
1575 "Version control\n")
1576{
1577 struct interface *ifp;
1578 struct rip_interface *ri;
1579
1580 ifp = (struct interface *)vty->index;
1581 ri = ifp->info;
1582
1583 ri->ri_send = RI_RIP_UNSPEC;
1584 return CMD_SUCCESS;
1585}
1586
1587ALIAS (no_ip_rip_send_version,
1588 no_ip_rip_send_version_num_cmd,
1589 "no ip rip send version (1|2)",
1590 NO_STR
1591 IP_STR
1592 "Routing Information Protocol\n"
1593 "Advertisement transmission\n"
1594 "Version control\n"
1595 "Version 1\n"
1596 "Version 2\n")
1597
1598DEFUN (ip_rip_authentication_mode,
1599 ip_rip_authentication_mode_cmd,
1600 "ip rip authentication mode (md5|text)",
1601 IP_STR
1602 "Routing Information Protocol\n"
1603 "Authentication control\n"
1604 "Authentication mode\n"
1605 "Keyed message digest\n"
1606 "Clear text authentication\n")
1607{
1608 struct interface *ifp;
1609 struct rip_interface *ri;
1610
1611 ifp = (struct interface *)vty->index;
1612 ri = ifp->info;
1613
paulca5e5162004-06-06 22:06:33 +00001614 if ( (argc < 1) || (argc > 2) )
1615 {
1616 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1617 return CMD_WARNING;
1618 }
1619
paul718e3742002-12-13 20:15:29 +00001620 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1621 ri->auth_type = RIP_AUTH_MD5;
1622 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1623 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1624 else
1625 {
1626 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1627 return CMD_WARNING;
1628 }
1629
paulca5e5162004-06-06 22:06:33 +00001630 if (argc == 1)
1631 return CMD_SUCCESS;
1632
1633 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1634 {
1635 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1636 return CMD_WARNING;
1637}
1638
1639 if (strncmp ("r", argv[1], 1) == 0)
1640 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1641 else if (strncmp ("o", argv[1], 1) == 0)
1642 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1643 else
1644 return CMD_WARNING;
1645
paul718e3742002-12-13 20:15:29 +00001646 return CMD_SUCCESS;
1647}
1648
paulca5e5162004-06-06 22:06:33 +00001649ALIAS (ip_rip_authentication_mode,
1650 ip_rip_authentication_mode_authlen_cmd,
1651 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1652 IP_STR
1653 "Routing Information Protocol\n"
1654 "Authentication control\n"
1655 "Authentication mode\n"
1656 "Keyed message digest\n"
1657 "Clear text authentication\n"
1658 "MD5 authentication data length\n"
1659 "RFC compatible\n"
1660 "Old ripd compatible\n")
1661
paul718e3742002-12-13 20:15:29 +00001662DEFUN (no_ip_rip_authentication_mode,
1663 no_ip_rip_authentication_mode_cmd,
1664 "no ip rip authentication mode",
1665 NO_STR
1666 IP_STR
1667 "Routing Information Protocol\n"
1668 "Authentication control\n"
1669 "Authentication mode\n")
1670{
1671 struct interface *ifp;
1672 struct rip_interface *ri;
1673
1674 ifp = (struct interface *)vty->index;
1675 ri = ifp->info;
1676
paul7755a8c2005-06-02 08:20:53 +00001677 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001678 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001679
1680 return CMD_SUCCESS;
1681}
1682
1683ALIAS (no_ip_rip_authentication_mode,
1684 no_ip_rip_authentication_mode_type_cmd,
1685 "no ip rip authentication mode (md5|text)",
1686 NO_STR
1687 IP_STR
1688 "Routing Information Protocol\n"
1689 "Authentication control\n"
1690 "Authentication mode\n"
1691 "Keyed message digest\n"
1692 "Clear text authentication\n")
1693
paulca5e5162004-06-06 22:06:33 +00001694ALIAS (no_ip_rip_authentication_mode,
1695 no_ip_rip_authentication_mode_type_authlen_cmd,
1696 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1697 NO_STR
1698 IP_STR
1699 "Routing Information Protocol\n"
1700 "Authentication control\n"
1701 "Authentication mode\n"
1702 "Keyed message digest\n"
1703 "Clear text authentication\n"
1704 "MD5 authentication data length\n"
1705 "RFC compatible\n"
1706 "Old ripd compatible\n")
1707
paul718e3742002-12-13 20:15:29 +00001708DEFUN (ip_rip_authentication_string,
1709 ip_rip_authentication_string_cmd,
1710 "ip rip authentication string LINE",
1711 IP_STR
1712 "Routing Information Protocol\n"
1713 "Authentication control\n"
1714 "Authentication string\n"
1715 "Authentication string\n")
1716{
1717 struct interface *ifp;
1718 struct rip_interface *ri;
1719
1720 ifp = (struct interface *)vty->index;
1721 ri = ifp->info;
1722
1723 if (strlen (argv[0]) > 16)
1724 {
1725 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1726 VTY_NEWLINE);
1727 return CMD_WARNING;
1728 }
1729
1730 if (ri->key_chain)
1731 {
1732 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1733 return CMD_WARNING;
1734 }
1735
1736 if (ri->auth_str)
1737 free (ri->auth_str);
1738
1739 ri->auth_str = strdup (argv[0]);
1740
1741 return CMD_SUCCESS;
1742}
1743
1744DEFUN (no_ip_rip_authentication_string,
1745 no_ip_rip_authentication_string_cmd,
1746 "no ip rip authentication string",
1747 NO_STR
1748 IP_STR
1749 "Routing Information Protocol\n"
1750 "Authentication control\n"
1751 "Authentication string\n")
1752{
1753 struct interface *ifp;
1754 struct rip_interface *ri;
1755
1756 ifp = (struct interface *)vty->index;
1757 ri = ifp->info;
1758
1759 if (ri->auth_str)
1760 free (ri->auth_str);
1761
1762 ri->auth_str = NULL;
1763
1764 return CMD_SUCCESS;
1765}
1766
1767ALIAS (no_ip_rip_authentication_string,
1768 no_ip_rip_authentication_string2_cmd,
1769 "no ip rip authentication string LINE",
1770 NO_STR
1771 IP_STR
1772 "Routing Information Protocol\n"
1773 "Authentication control\n"
1774 "Authentication string\n"
1775 "Authentication string\n")
1776
1777DEFUN (ip_rip_authentication_key_chain,
1778 ip_rip_authentication_key_chain_cmd,
1779 "ip rip authentication key-chain LINE",
1780 IP_STR
1781 "Routing Information Protocol\n"
1782 "Authentication control\n"
1783 "Authentication key-chain\n"
1784 "name of key-chain\n")
1785{
1786 struct interface *ifp;
1787 struct rip_interface *ri;
1788
1789 ifp = (struct interface *) vty->index;
1790 ri = ifp->info;
1791
1792 if (ri->auth_str)
1793 {
1794 vty_out (vty, "%% authentication string configuration exists%s",
1795 VTY_NEWLINE);
1796 return CMD_WARNING;
1797 }
1798
1799 if (ri->key_chain)
1800 free (ri->key_chain);
1801
1802 ri->key_chain = strdup (argv[0]);
1803
1804 return CMD_SUCCESS;
1805}
1806
1807DEFUN (no_ip_rip_authentication_key_chain,
1808 no_ip_rip_authentication_key_chain_cmd,
1809 "no ip rip authentication key-chain",
1810 NO_STR
1811 IP_STR
1812 "Routing Information Protocol\n"
1813 "Authentication control\n"
1814 "Authentication key-chain\n")
1815{
1816 struct interface *ifp;
1817 struct rip_interface *ri;
1818
1819 ifp = (struct interface *) vty->index;
1820 ri = ifp->info;
1821
1822 if (ri->key_chain)
1823 free (ri->key_chain);
1824
1825 ri->key_chain = NULL;
1826
1827 return CMD_SUCCESS;
1828}
1829
1830ALIAS (no_ip_rip_authentication_key_chain,
1831 no_ip_rip_authentication_key_chain2_cmd,
1832 "no ip rip authentication key-chain LINE",
1833 NO_STR
1834 IP_STR
1835 "Routing Information Protocol\n"
1836 "Authentication control\n"
1837 "Authentication key-chain\n"
1838 "name of key-chain\n")
1839
hasso16705132003-05-25 14:49:19 +00001840/* CHANGED: ip rip split-horizon
1841 Cisco and Zebra's command is
1842 ip split-horizon
1843 */
1844DEFUN (ip_rip_split_horizon,
1845 ip_rip_split_horizon_cmd,
1846 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001847 IP_STR
hasso16705132003-05-25 14:49:19 +00001848 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001849 "Perform split horizon\n")
1850{
1851 struct interface *ifp;
1852 struct rip_interface *ri;
1853
1854 ifp = vty->index;
1855 ri = ifp->info;
1856
hasso16705132003-05-25 14:49:19 +00001857 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001858 return CMD_SUCCESS;
1859}
1860
hasso16705132003-05-25 14:49:19 +00001861DEFUN (ip_rip_split_horizon_poisoned_reverse,
1862 ip_rip_split_horizon_poisoned_reverse_cmd,
1863 "ip rip split-horizon poisoned-reverse",
1864 IP_STR
1865 "Routing Information Protocol\n"
1866 "Perform split horizon\n"
1867 "With poisoned-reverse\n")
1868{
1869 struct interface *ifp;
1870 struct rip_interface *ri;
1871
1872 ifp = vty->index;
1873 ri = ifp->info;
1874
1875 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1876 return CMD_SUCCESS;
1877}
1878
1879/* CHANGED: no ip rip split-horizon
1880 Cisco and Zebra's command is
1881 no ip split-horizon
1882 */
1883DEFUN (no_ip_rip_split_horizon,
1884 no_ip_rip_split_horizon_cmd,
1885 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001886 NO_STR
1887 IP_STR
hasso16705132003-05-25 14:49:19 +00001888 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001889 "Perform split horizon\n")
1890{
1891 struct interface *ifp;
1892 struct rip_interface *ri;
1893
1894 ifp = vty->index;
1895 ri = ifp->info;
1896
hasso16705132003-05-25 14:49:19 +00001897 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001898 return CMD_SUCCESS;
1899}
1900
hasso16705132003-05-25 14:49:19 +00001901ALIAS (no_ip_rip_split_horizon,
1902 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1903 "no ip rip split-horizon poisoned-reverse",
1904 NO_STR
1905 IP_STR
1906 "Routing Information Protocol\n"
1907 "Perform split horizon\n"
1908 "With poisoned-reverse\n")
1909
paul718e3742002-12-13 20:15:29 +00001910DEFUN (rip_passive_interface,
1911 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001912 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001913 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001914 "Interface name\n"
1915 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001916{
hasso98b718a2004-10-11 12:57:57 +00001917 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001918
1919 if (!strcmp(ifname,"default")) {
1920 passive_default = 1;
1921 rip_passive_nondefault_clean();
1922 return CMD_SUCCESS;
1923 }
1924 if (passive_default)
1925 return rip_passive_nondefault_unset (vty, ifname);
1926 else
1927 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001928}
1929
1930DEFUN (no_rip_passive_interface,
1931 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001932 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001933 NO_STR
1934 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001935 "Interface name\n"
1936 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001937{
hasso98b718a2004-10-11 12:57:57 +00001938 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001939
1940 if (!strcmp(ifname,"default")) {
1941 passive_default = 0;
1942 rip_passive_nondefault_clean();
1943 return CMD_SUCCESS;
1944 }
1945 if (passive_default)
1946 return rip_passive_nondefault_set (vty, ifname);
1947 else
1948 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001949}
1950
1951/* Write rip configuration of each interface. */
1952int
1953rip_interface_config_write (struct vty *vty)
1954{
hasso52dc7ee2004-09-23 19:18:23 +00001955 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001956 struct interface *ifp;
1957
paul1eb8ef22005-04-07 07:30:20 +00001958 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001959 {
1960 struct rip_interface *ri;
1961
paul718e3742002-12-13 20:15:29 +00001962 ri = ifp->info;
1963
hasso16705132003-05-25 14:49:19 +00001964 /* Do not display the interface if there is no
1965 * configuration about it.
1966 **/
1967 if ((!ifp->desc) &&
1968 (ri->split_horizon == ri->split_horizon_default) &&
1969 (ri->ri_send == RI_RIP_UNSPEC) &&
1970 (ri->ri_receive == RI_RIP_UNSPEC) &&
1971 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001972 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001973 (!ri->auth_str) &&
1974 (!ri->key_chain) )
1975 continue;
1976
paul718e3742002-12-13 20:15:29 +00001977 vty_out (vty, "interface %s%s", ifp->name,
1978 VTY_NEWLINE);
1979
1980 if (ifp->desc)
1981 vty_out (vty, " description %s%s", ifp->desc,
1982 VTY_NEWLINE);
1983
1984 /* Split horizon. */
1985 if (ri->split_horizon != ri->split_horizon_default)
1986 {
hasso16705132003-05-25 14:49:19 +00001987 switch (ri->split_horizon) {
1988 case RIP_SPLIT_HORIZON:
1989 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1990 break;
1991 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1992 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1993 VTY_NEWLINE);
1994 break;
1995 case RIP_NO_SPLIT_HORIZON:
1996 default:
1997 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1998 break;
1999 }
paul718e3742002-12-13 20:15:29 +00002000 }
2001
2002 /* RIP version setting. */
2003 if (ri->ri_send != RI_RIP_UNSPEC)
2004 vty_out (vty, " ip rip send version %s%s",
2005 lookup (ri_version_msg, ri->ri_send),
2006 VTY_NEWLINE);
2007
2008 if (ri->ri_receive != RI_RIP_UNSPEC)
2009 vty_out (vty, " ip rip receive version %s%s",
2010 lookup (ri_version_msg, ri->ri_receive),
2011 VTY_NEWLINE);
2012
2013 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00002014 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2015 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00002016
paul718e3742002-12-13 20:15:29 +00002017 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002018 {
2019 vty_out (vty, " ip rip authentication mode md5");
2020 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2021 vty_out (vty, " auth-length old-ripd");
2022 else
2023 vty_out (vty, " auth-length rfc");
2024 vty_out (vty, "%s", VTY_NEWLINE);
2025 }
paul718e3742002-12-13 20:15:29 +00002026
2027 if (ri->auth_str)
2028 vty_out (vty, " ip rip authentication string %s%s",
2029 ri->auth_str, VTY_NEWLINE);
2030
2031 if (ri->key_chain)
2032 vty_out (vty, " ip rip authentication key-chain %s%s",
2033 ri->key_chain, VTY_NEWLINE);
2034
2035 vty_out (vty, "!%s", VTY_NEWLINE);
2036 }
2037 return 0;
2038}
2039
2040int
2041config_write_rip_network (struct vty *vty, int config_mode)
2042{
hasso8a676be2004-10-08 06:36:38 +00002043 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002044 char *ifname;
2045 struct route_node *node;
2046
2047 /* Network type RIP enable interface statement. */
2048 for (node = route_top (rip_enable_network); node; node = route_next (node))
2049 if (node->info)
2050 vty_out (vty, "%s%s/%d%s",
2051 config_mode ? " network " : " ",
2052 inet_ntoa (node->p.u.prefix4),
2053 node->p.prefixlen,
2054 VTY_NEWLINE);
2055
2056 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002057 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002058 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2059 vty_out (vty, "%s%s%s",
2060 config_mode ? " network " : " ",
2061 ifname,
2062 VTY_NEWLINE);
2063
2064 /* RIP neighbors listing. */
2065 for (node = route_top (rip->neighbor); node; node = route_next (node))
2066 if (node->info)
2067 vty_out (vty, "%s%s%s",
2068 config_mode ? " neighbor " : " ",
2069 inet_ntoa (node->p.u.prefix4),
2070 VTY_NEWLINE);
2071
2072 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002073 if (config_mode) {
2074 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002075 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002076 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002077 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2078 vty_out (vty, " %spassive-interface %s%s",
2079 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2080 }
paul718e3742002-12-13 20:15:29 +00002081
2082 return 0;
2083}
2084
2085struct cmd_node interface_node =
2086{
2087 INTERFACE_NODE,
2088 "%s(config-if)# ",
2089 1,
2090};
2091
2092/* Called when interface structure allocated. */
2093int
2094rip_interface_new_hook (struct interface *ifp)
2095{
2096 ifp->info = rip_interface_new ();
2097 return 0;
2098}
2099
2100/* Called when interface structure deleted. */
2101int
2102rip_interface_delete_hook (struct interface *ifp)
2103{
2104 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002105 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002106 return 0;
2107}
2108
2109/* Allocate and initialize interface vector. */
2110void
2111rip_if_init ()
2112{
2113 /* Default initial size of interface vector. */
2114 if_init();
2115 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2116 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2117
2118 /* RIP network init. */
2119 rip_enable_interface = vector_init (1);
2120 rip_enable_network = route_table_init ();
2121
2122 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002123 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002124
2125 /* Install interface node. */
2126 install_node (&interface_node, rip_interface_config_write);
2127
2128 /* Install commands. */
2129 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002130 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002131 install_default (INTERFACE_NODE);
2132 install_element (INTERFACE_NODE, &interface_desc_cmd);
2133 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2134 install_element (RIP_NODE, &rip_network_cmd);
2135 install_element (RIP_NODE, &no_rip_network_cmd);
2136 install_element (RIP_NODE, &rip_neighbor_cmd);
2137 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2138
2139 install_element (RIP_NODE, &rip_passive_interface_cmd);
2140 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2141
2142 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2143 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2144 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2145 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2146 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2147
2148 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2149 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2150 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2151 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2152 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2153
2154 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002155 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002156 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2157 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002158 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002159
2160 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2161 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2162 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2163
2164 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2165 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2166 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2167
hasso16705132003-05-25 14:49:19 +00002168 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2169 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2170 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2171 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002172}