blob: 85bf3c5ad011400db489ada99280ed2f674df4df [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,
vincentfbf5d032005-09-29 11:25:50 +0000720 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000721
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,
vincentfbf5d032005-09-29 11:25:50 +00001032 &address, connected->ifp->ifindex,
1033 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +00001034 } else
1035 {
1036 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1037 &address, connected->ifp->ifindex);
1038 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1039 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +00001040 &address, connected->ifp->ifindex,
1041 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +00001042 }
1043 }
paul718e3742002-12-13 20:15:29 +00001044}
1045
1046/* Update interface status. */
1047void
1048rip_enable_apply (struct interface *ifp)
1049{
1050 int ret;
1051 struct rip_interface *ri = NULL;
1052
1053 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001054 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001055 return;
1056
1057 ri = ifp->info;
1058
1059 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001060 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001061
1062 /* If the interface is matched. */
1063 if (ret > 0)
1064 ri->enable_network = 1;
1065 else
1066 ri->enable_network = 0;
1067
1068 /* Check interface name configuration. */
1069 ret = rip_enable_if_lookup (ifp->name);
1070 if (ret >= 0)
1071 ri->enable_interface = 1;
1072 else
1073 ri->enable_interface = 0;
1074
1075 /* any interface MUST have an IPv4 address */
1076 if ( ! rip_if_ipv4_address_check (ifp) )
1077 {
1078 ri->enable_network = 0;
1079 ri->enable_interface = 0;
1080 }
1081
1082 /* Update running status of the interface. */
1083 if (ri->enable_network || ri->enable_interface)
1084 {
paul718e3742002-12-13 20:15:29 +00001085 {
1086 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001087 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001088
1089 /* Add interface wake up thread. */
1090 if (! ri->t_wakeup)
1091 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1092 ifp, 1);
1093 rip_connect_set (ifp, 1);
1094 }
1095 }
1096 else
1097 {
1098 if (ri->running)
1099 {
hasso16705132003-05-25 14:49:19 +00001100 /* Might as well clean up the route table as well
1101 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1102 **/
paul718e3742002-12-13 20:15:29 +00001103 rip_if_down(ifp);
1104
paul718e3742002-12-13 20:15:29 +00001105 rip_connect_set (ifp, 0);
1106 }
1107 }
1108}
1109
1110/* Apply network configuration to all interface. */
1111void
1112rip_enable_apply_all ()
1113{
1114 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001115 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001116
1117 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001118 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1119 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001120}
1121
1122int
1123rip_neighbor_lookup (struct sockaddr_in *from)
1124{
1125 struct prefix_ipv4 p;
1126 struct route_node *node;
1127
1128 memset (&p, 0, sizeof (struct prefix_ipv4));
1129 p.family = AF_INET;
1130 p.prefix = from->sin_addr;
1131 p.prefixlen = IPV4_MAX_BITLEN;
1132
1133 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1134 if (node)
1135 {
1136 route_unlock_node (node);
1137 return 1;
1138 }
1139 return 0;
1140}
1141
1142/* Add new RIP neighbor to the neighbor tree. */
1143int
1144rip_neighbor_add (struct prefix_ipv4 *p)
1145{
1146 struct route_node *node;
1147
1148 node = route_node_get (rip->neighbor, (struct prefix *) p);
1149
1150 if (node->info)
1151 return -1;
1152
1153 node->info = rip->neighbor;
1154
1155 return 0;
1156}
1157
1158/* Delete RIP neighbor from the neighbor tree. */
1159int
1160rip_neighbor_delete (struct prefix_ipv4 *p)
1161{
1162 struct route_node *node;
1163
1164 /* Lock for look up. */
1165 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1166 if (! node)
1167 return -1;
1168
1169 node->info = NULL;
1170
1171 /* Unlock lookup lock. */
1172 route_unlock_node (node);
1173
1174 /* Unlock real neighbor information lock. */
1175 route_unlock_node (node);
1176
1177 return 0;
1178}
1179
1180/* Clear all network and neighbor configuration. */
1181void
1182rip_clean_network ()
1183{
hasso8a676be2004-10-08 06:36:38 +00001184 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001185 char *str;
1186 struct route_node *rn;
1187
1188 /* rip_enable_network. */
1189 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1190 if (rn->info)
1191 {
1192 rn->info = NULL;
1193 route_unlock_node (rn);
1194 }
1195
1196 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001197 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001198 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1199 {
1200 free (str);
1201 vector_slot (rip_enable_interface, i) = NULL;
1202 }
1203}
1204
1205/* Utility function for looking up passive interface settings. */
1206int
hasso98b718a2004-10-11 12:57:57 +00001207rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001208{
hasso8a676be2004-10-08 06:36:38 +00001209 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001210 char *str;
1211
paul55468c82005-03-14 20:19:01 +00001212 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001213 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001214 if (strcmp (str, ifname) == 0)
1215 return i;
1216 return -1;
1217}
1218
1219void
1220rip_passive_interface_apply (struct interface *ifp)
1221{
paul718e3742002-12-13 20:15:29 +00001222 struct rip_interface *ri;
1223
1224 ri = ifp->info;
1225
paul4aaff3f2003-06-07 01:04:45 +00001226 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1227 passive_default : !passive_default);
1228
1229 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001230 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001231}
1232
1233void
1234rip_passive_interface_apply_all ()
1235{
1236 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001237 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001238
paul1eb8ef22005-04-07 07:30:20 +00001239 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1240 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001241}
1242
1243/* Passive interface. */
1244int
hasso98b718a2004-10-11 12:57:57 +00001245rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001246{
paul4aaff3f2003-06-07 01:04:45 +00001247 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001248 return CMD_WARNING;
1249
paul4aaff3f2003-06-07 01:04:45 +00001250 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001251
1252 rip_passive_interface_apply_all ();
1253
1254 return CMD_SUCCESS;
1255}
1256
1257int
hasso98b718a2004-10-11 12:57:57 +00001258rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001259{
1260 int i;
1261 char *str;
1262
paul4aaff3f2003-06-07 01:04:45 +00001263 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001264 if (i < 0)
1265 return CMD_WARNING;
1266
paul4aaff3f2003-06-07 01:04:45 +00001267 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001268 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001269 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001270
1271 rip_passive_interface_apply_all ();
1272
1273 return CMD_SUCCESS;
1274}
1275
1276/* Free all configured RIP passive-interface settings. */
1277void
paul4aaff3f2003-06-07 01:04:45 +00001278rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001279{
hasso8a676be2004-10-08 06:36:38 +00001280 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001281 char *str;
1282
paul55468c82005-03-14 20:19:01 +00001283 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001284 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001285 {
1286 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001287 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001288 }
1289 rip_passive_interface_apply_all ();
1290}
1291
1292/* RIP enable network or interface configuration. */
1293DEFUN (rip_network,
1294 rip_network_cmd,
1295 "network (A.B.C.D/M|WORD)",
1296 "Enable routing on an IP network\n"
1297 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1298 "Interface name\n")
1299{
1300 int ret;
1301 struct prefix_ipv4 p;
1302
1303 ret = str2prefix_ipv4 (argv[0], &p);
1304
1305 if (ret)
1306 ret = rip_enable_network_add ((struct prefix *) &p);
1307 else
1308 ret = rip_enable_if_add (argv[0]);
1309
1310 if (ret < 0)
1311 {
1312 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1313 VTY_NEWLINE);
1314 return CMD_WARNING;
1315 }
1316
paul718e3742002-12-13 20:15:29 +00001317 return CMD_SUCCESS;
1318}
1319
1320/* RIP enable network or interface configuration. */
1321DEFUN (no_rip_network,
1322 no_rip_network_cmd,
1323 "no network (A.B.C.D/M|WORD)",
1324 NO_STR
1325 "Enable routing on an IP network\n"
1326 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1327 "Interface name\n")
1328{
1329 int ret;
1330 struct prefix_ipv4 p;
1331
1332 ret = str2prefix_ipv4 (argv[0], &p);
1333
1334 if (ret)
1335 ret = rip_enable_network_delete ((struct prefix *) &p);
1336 else
1337 ret = rip_enable_if_delete (argv[0]);
1338
1339 if (ret < 0)
1340 {
1341 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1342 VTY_NEWLINE);
1343 return CMD_WARNING;
1344 }
1345
paul718e3742002-12-13 20:15:29 +00001346 return CMD_SUCCESS;
1347}
1348
1349/* RIP neighbor configuration set. */
1350DEFUN (rip_neighbor,
1351 rip_neighbor_cmd,
1352 "neighbor A.B.C.D",
1353 "Specify a neighbor router\n"
1354 "Neighbor address\n")
1355{
1356 int ret;
1357 struct prefix_ipv4 p;
1358
1359 ret = str2prefix_ipv4 (argv[0], &p);
1360
1361 if (ret <= 0)
1362 {
1363 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1364 return CMD_WARNING;
1365 }
1366
1367 rip_neighbor_add (&p);
1368
1369 return CMD_SUCCESS;
1370}
1371
1372/* RIP neighbor configuration unset. */
1373DEFUN (no_rip_neighbor,
1374 no_rip_neighbor_cmd,
1375 "no neighbor A.B.C.D",
1376 NO_STR
1377 "Specify a neighbor router\n"
1378 "Neighbor address\n")
1379{
1380 int ret;
1381 struct prefix_ipv4 p;
1382
1383 ret = str2prefix_ipv4 (argv[0], &p);
1384
1385 if (ret <= 0)
1386 {
1387 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1388 return CMD_WARNING;
1389 }
1390
1391 rip_neighbor_delete (&p);
1392
1393 return CMD_SUCCESS;
1394}
1395
1396DEFUN (ip_rip_receive_version,
1397 ip_rip_receive_version_cmd,
1398 "ip rip receive version (1|2)",
1399 IP_STR
1400 "Routing Information Protocol\n"
1401 "Advertisement reception\n"
1402 "Version control\n"
1403 "RIP version 1\n"
1404 "RIP version 2\n")
1405{
1406 struct interface *ifp;
1407 struct rip_interface *ri;
1408
1409 ifp = (struct interface *)vty->index;
1410 ri = ifp->info;
1411
1412 /* Version 1. */
1413 if (atoi (argv[0]) == 1)
1414 {
1415 ri->ri_receive = RI_RIP_VERSION_1;
1416 return CMD_SUCCESS;
1417 }
1418 if (atoi (argv[0]) == 2)
1419 {
1420 ri->ri_receive = RI_RIP_VERSION_2;
1421 return CMD_SUCCESS;
1422 }
1423 return CMD_WARNING;
1424}
1425
1426DEFUN (ip_rip_receive_version_1,
1427 ip_rip_receive_version_1_cmd,
1428 "ip rip receive version 1 2",
1429 IP_STR
1430 "Routing Information Protocol\n"
1431 "Advertisement reception\n"
1432 "Version control\n"
1433 "RIP version 1\n"
1434 "RIP version 2\n")
1435{
1436 struct interface *ifp;
1437 struct rip_interface *ri;
1438
1439 ifp = (struct interface *)vty->index;
1440 ri = ifp->info;
1441
1442 /* Version 1 and 2. */
1443 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1444 return CMD_SUCCESS;
1445}
1446
1447DEFUN (ip_rip_receive_version_2,
1448 ip_rip_receive_version_2_cmd,
1449 "ip rip receive version 2 1",
1450 IP_STR
1451 "Routing Information Protocol\n"
1452 "Advertisement reception\n"
1453 "Version control\n"
1454 "RIP version 2\n"
1455 "RIP version 1\n")
1456{
1457 struct interface *ifp;
1458 struct rip_interface *ri;
1459
1460 ifp = (struct interface *)vty->index;
1461 ri = ifp->info;
1462
1463 /* Version 1 and 2. */
1464 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1465 return CMD_SUCCESS;
1466}
1467
1468DEFUN (no_ip_rip_receive_version,
1469 no_ip_rip_receive_version_cmd,
1470 "no ip rip receive version",
1471 NO_STR
1472 IP_STR
1473 "Routing Information Protocol\n"
1474 "Advertisement reception\n"
1475 "Version control\n")
1476{
1477 struct interface *ifp;
1478 struct rip_interface *ri;
1479
1480 ifp = (struct interface *)vty->index;
1481 ri = ifp->info;
1482
1483 ri->ri_receive = RI_RIP_UNSPEC;
1484 return CMD_SUCCESS;
1485}
1486
1487ALIAS (no_ip_rip_receive_version,
1488 no_ip_rip_receive_version_num_cmd,
1489 "no ip rip receive version (1|2)",
1490 NO_STR
1491 IP_STR
1492 "Routing Information Protocol\n"
1493 "Advertisement reception\n"
1494 "Version control\n"
1495 "Version 1\n"
1496 "Version 2\n")
1497
1498DEFUN (ip_rip_send_version,
1499 ip_rip_send_version_cmd,
1500 "ip rip send version (1|2)",
1501 IP_STR
1502 "Routing Information Protocol\n"
1503 "Advertisement transmission\n"
1504 "Version control\n"
1505 "RIP version 1\n"
1506 "RIP version 2\n")
1507{
1508 struct interface *ifp;
1509 struct rip_interface *ri;
1510
1511 ifp = (struct interface *)vty->index;
1512 ri = ifp->info;
1513
1514 /* Version 1. */
1515 if (atoi (argv[0]) == 1)
1516 {
1517 ri->ri_send = RI_RIP_VERSION_1;
1518 return CMD_SUCCESS;
1519 }
1520 if (atoi (argv[0]) == 2)
1521 {
1522 ri->ri_send = RI_RIP_VERSION_2;
1523 return CMD_SUCCESS;
1524 }
1525 return CMD_WARNING;
1526}
1527
1528DEFUN (ip_rip_send_version_1,
1529 ip_rip_send_version_1_cmd,
1530 "ip rip send version 1 2",
1531 IP_STR
1532 "Routing Information Protocol\n"
1533 "Advertisement transmission\n"
1534 "Version control\n"
1535 "RIP version 1\n"
1536 "RIP version 2\n")
1537{
1538 struct interface *ifp;
1539 struct rip_interface *ri;
1540
1541 ifp = (struct interface *)vty->index;
1542 ri = ifp->info;
1543
1544 /* Version 1 and 2. */
1545 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1546 return CMD_SUCCESS;
1547}
1548
1549DEFUN (ip_rip_send_version_2,
1550 ip_rip_send_version_2_cmd,
1551 "ip rip send version 2 1",
1552 IP_STR
1553 "Routing Information Protocol\n"
1554 "Advertisement transmission\n"
1555 "Version control\n"
1556 "RIP version 2\n"
1557 "RIP version 1\n")
1558{
1559 struct interface *ifp;
1560 struct rip_interface *ri;
1561
1562 ifp = (struct interface *)vty->index;
1563 ri = ifp->info;
1564
1565 /* Version 1 and 2. */
1566 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1567 return CMD_SUCCESS;
1568}
1569
1570DEFUN (no_ip_rip_send_version,
1571 no_ip_rip_send_version_cmd,
1572 "no ip rip send version",
1573 NO_STR
1574 IP_STR
1575 "Routing Information Protocol\n"
1576 "Advertisement transmission\n"
1577 "Version control\n")
1578{
1579 struct interface *ifp;
1580 struct rip_interface *ri;
1581
1582 ifp = (struct interface *)vty->index;
1583 ri = ifp->info;
1584
1585 ri->ri_send = RI_RIP_UNSPEC;
1586 return CMD_SUCCESS;
1587}
1588
1589ALIAS (no_ip_rip_send_version,
1590 no_ip_rip_send_version_num_cmd,
1591 "no ip rip send version (1|2)",
1592 NO_STR
1593 IP_STR
1594 "Routing Information Protocol\n"
1595 "Advertisement transmission\n"
1596 "Version control\n"
1597 "Version 1\n"
1598 "Version 2\n")
1599
1600DEFUN (ip_rip_authentication_mode,
1601 ip_rip_authentication_mode_cmd,
1602 "ip rip authentication mode (md5|text)",
1603 IP_STR
1604 "Routing Information Protocol\n"
1605 "Authentication control\n"
1606 "Authentication mode\n"
1607 "Keyed message digest\n"
1608 "Clear text authentication\n")
1609{
1610 struct interface *ifp;
1611 struct rip_interface *ri;
1612
1613 ifp = (struct interface *)vty->index;
1614 ri = ifp->info;
1615
paulca5e5162004-06-06 22:06:33 +00001616 if ( (argc < 1) || (argc > 2) )
1617 {
1618 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1619 return CMD_WARNING;
1620 }
1621
paul718e3742002-12-13 20:15:29 +00001622 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1623 ri->auth_type = RIP_AUTH_MD5;
1624 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1625 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1626 else
1627 {
1628 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1629 return CMD_WARNING;
1630 }
1631
paulca5e5162004-06-06 22:06:33 +00001632 if (argc == 1)
1633 return CMD_SUCCESS;
1634
1635 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1636 {
1637 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1638 return CMD_WARNING;
1639}
1640
1641 if (strncmp ("r", argv[1], 1) == 0)
1642 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1643 else if (strncmp ("o", argv[1], 1) == 0)
1644 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1645 else
1646 return CMD_WARNING;
1647
paul718e3742002-12-13 20:15:29 +00001648 return CMD_SUCCESS;
1649}
1650
paulca5e5162004-06-06 22:06:33 +00001651ALIAS (ip_rip_authentication_mode,
1652 ip_rip_authentication_mode_authlen_cmd,
1653 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1654 IP_STR
1655 "Routing Information Protocol\n"
1656 "Authentication control\n"
1657 "Authentication mode\n"
1658 "Keyed message digest\n"
1659 "Clear text authentication\n"
1660 "MD5 authentication data length\n"
1661 "RFC compatible\n"
1662 "Old ripd compatible\n")
1663
paul718e3742002-12-13 20:15:29 +00001664DEFUN (no_ip_rip_authentication_mode,
1665 no_ip_rip_authentication_mode_cmd,
1666 "no ip rip authentication mode",
1667 NO_STR
1668 IP_STR
1669 "Routing Information Protocol\n"
1670 "Authentication control\n"
1671 "Authentication mode\n")
1672{
1673 struct interface *ifp;
1674 struct rip_interface *ri;
1675
1676 ifp = (struct interface *)vty->index;
1677 ri = ifp->info;
1678
paul7755a8c2005-06-02 08:20:53 +00001679 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001680 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001681
1682 return CMD_SUCCESS;
1683}
1684
1685ALIAS (no_ip_rip_authentication_mode,
1686 no_ip_rip_authentication_mode_type_cmd,
1687 "no ip rip authentication mode (md5|text)",
1688 NO_STR
1689 IP_STR
1690 "Routing Information Protocol\n"
1691 "Authentication control\n"
1692 "Authentication mode\n"
1693 "Keyed message digest\n"
1694 "Clear text authentication\n")
1695
paulca5e5162004-06-06 22:06:33 +00001696ALIAS (no_ip_rip_authentication_mode,
1697 no_ip_rip_authentication_mode_type_authlen_cmd,
1698 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1699 NO_STR
1700 IP_STR
1701 "Routing Information Protocol\n"
1702 "Authentication control\n"
1703 "Authentication mode\n"
1704 "Keyed message digest\n"
1705 "Clear text authentication\n"
1706 "MD5 authentication data length\n"
1707 "RFC compatible\n"
1708 "Old ripd compatible\n")
1709
paul718e3742002-12-13 20:15:29 +00001710DEFUN (ip_rip_authentication_string,
1711 ip_rip_authentication_string_cmd,
1712 "ip rip authentication string LINE",
1713 IP_STR
1714 "Routing Information Protocol\n"
1715 "Authentication control\n"
1716 "Authentication string\n"
1717 "Authentication string\n")
1718{
1719 struct interface *ifp;
1720 struct rip_interface *ri;
1721
1722 ifp = (struct interface *)vty->index;
1723 ri = ifp->info;
1724
1725 if (strlen (argv[0]) > 16)
1726 {
1727 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1728 VTY_NEWLINE);
1729 return CMD_WARNING;
1730 }
1731
1732 if (ri->key_chain)
1733 {
1734 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1735 return CMD_WARNING;
1736 }
1737
1738 if (ri->auth_str)
1739 free (ri->auth_str);
1740
1741 ri->auth_str = strdup (argv[0]);
1742
1743 return CMD_SUCCESS;
1744}
1745
1746DEFUN (no_ip_rip_authentication_string,
1747 no_ip_rip_authentication_string_cmd,
1748 "no ip rip authentication string",
1749 NO_STR
1750 IP_STR
1751 "Routing Information Protocol\n"
1752 "Authentication control\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 (ri->auth_str)
1762 free (ri->auth_str);
1763
1764 ri->auth_str = NULL;
1765
1766 return CMD_SUCCESS;
1767}
1768
1769ALIAS (no_ip_rip_authentication_string,
1770 no_ip_rip_authentication_string2_cmd,
1771 "no ip rip authentication string LINE",
1772 NO_STR
1773 IP_STR
1774 "Routing Information Protocol\n"
1775 "Authentication control\n"
1776 "Authentication string\n"
1777 "Authentication string\n")
1778
1779DEFUN (ip_rip_authentication_key_chain,
1780 ip_rip_authentication_key_chain_cmd,
1781 "ip rip authentication key-chain LINE",
1782 IP_STR
1783 "Routing Information Protocol\n"
1784 "Authentication control\n"
1785 "Authentication key-chain\n"
1786 "name of key-chain\n")
1787{
1788 struct interface *ifp;
1789 struct rip_interface *ri;
1790
1791 ifp = (struct interface *) vty->index;
1792 ri = ifp->info;
1793
1794 if (ri->auth_str)
1795 {
1796 vty_out (vty, "%% authentication string configuration exists%s",
1797 VTY_NEWLINE);
1798 return CMD_WARNING;
1799 }
1800
1801 if (ri->key_chain)
1802 free (ri->key_chain);
1803
1804 ri->key_chain = strdup (argv[0]);
1805
1806 return CMD_SUCCESS;
1807}
1808
1809DEFUN (no_ip_rip_authentication_key_chain,
1810 no_ip_rip_authentication_key_chain_cmd,
1811 "no ip rip authentication key-chain",
1812 NO_STR
1813 IP_STR
1814 "Routing Information Protocol\n"
1815 "Authentication control\n"
1816 "Authentication key-chain\n")
1817{
1818 struct interface *ifp;
1819 struct rip_interface *ri;
1820
1821 ifp = (struct interface *) vty->index;
1822 ri = ifp->info;
1823
1824 if (ri->key_chain)
1825 free (ri->key_chain);
1826
1827 ri->key_chain = NULL;
1828
1829 return CMD_SUCCESS;
1830}
1831
1832ALIAS (no_ip_rip_authentication_key_chain,
1833 no_ip_rip_authentication_key_chain2_cmd,
1834 "no ip rip authentication key-chain LINE",
1835 NO_STR
1836 IP_STR
1837 "Routing Information Protocol\n"
1838 "Authentication control\n"
1839 "Authentication key-chain\n"
1840 "name of key-chain\n")
1841
hasso16705132003-05-25 14:49:19 +00001842/* CHANGED: ip rip split-horizon
1843 Cisco and Zebra's command is
1844 ip split-horizon
1845 */
1846DEFUN (ip_rip_split_horizon,
1847 ip_rip_split_horizon_cmd,
1848 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001849 IP_STR
hasso16705132003-05-25 14:49:19 +00001850 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001851 "Perform split horizon\n")
1852{
1853 struct interface *ifp;
1854 struct rip_interface *ri;
1855
1856 ifp = vty->index;
1857 ri = ifp->info;
1858
hasso16705132003-05-25 14:49:19 +00001859 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001860 return CMD_SUCCESS;
1861}
1862
hasso16705132003-05-25 14:49:19 +00001863DEFUN (ip_rip_split_horizon_poisoned_reverse,
1864 ip_rip_split_horizon_poisoned_reverse_cmd,
1865 "ip rip split-horizon poisoned-reverse",
1866 IP_STR
1867 "Routing Information Protocol\n"
1868 "Perform split horizon\n"
1869 "With poisoned-reverse\n")
1870{
1871 struct interface *ifp;
1872 struct rip_interface *ri;
1873
1874 ifp = vty->index;
1875 ri = ifp->info;
1876
1877 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1878 return CMD_SUCCESS;
1879}
1880
1881/* CHANGED: no ip rip split-horizon
1882 Cisco and Zebra's command is
1883 no ip split-horizon
1884 */
1885DEFUN (no_ip_rip_split_horizon,
1886 no_ip_rip_split_horizon_cmd,
1887 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001888 NO_STR
1889 IP_STR
hasso16705132003-05-25 14:49:19 +00001890 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001891 "Perform split horizon\n")
1892{
1893 struct interface *ifp;
1894 struct rip_interface *ri;
1895
1896 ifp = vty->index;
1897 ri = ifp->info;
1898
hasso16705132003-05-25 14:49:19 +00001899 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001900 return CMD_SUCCESS;
1901}
1902
hasso16705132003-05-25 14:49:19 +00001903ALIAS (no_ip_rip_split_horizon,
1904 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1905 "no ip rip split-horizon poisoned-reverse",
1906 NO_STR
1907 IP_STR
1908 "Routing Information Protocol\n"
1909 "Perform split horizon\n"
1910 "With poisoned-reverse\n")
1911
paul718e3742002-12-13 20:15:29 +00001912DEFUN (rip_passive_interface,
1913 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001914 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001915 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001916 "Interface name\n"
1917 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001918{
hasso98b718a2004-10-11 12:57:57 +00001919 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001920
1921 if (!strcmp(ifname,"default")) {
1922 passive_default = 1;
1923 rip_passive_nondefault_clean();
1924 return CMD_SUCCESS;
1925 }
1926 if (passive_default)
1927 return rip_passive_nondefault_unset (vty, ifname);
1928 else
1929 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001930}
1931
1932DEFUN (no_rip_passive_interface,
1933 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001934 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001935 NO_STR
1936 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001937 "Interface name\n"
1938 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001939{
hasso98b718a2004-10-11 12:57:57 +00001940 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001941
1942 if (!strcmp(ifname,"default")) {
1943 passive_default = 0;
1944 rip_passive_nondefault_clean();
1945 return CMD_SUCCESS;
1946 }
1947 if (passive_default)
1948 return rip_passive_nondefault_set (vty, ifname);
1949 else
1950 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001951}
1952
1953/* Write rip configuration of each interface. */
1954int
1955rip_interface_config_write (struct vty *vty)
1956{
hasso52dc7ee2004-09-23 19:18:23 +00001957 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001958 struct interface *ifp;
1959
paul1eb8ef22005-04-07 07:30:20 +00001960 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001961 {
1962 struct rip_interface *ri;
1963
paul718e3742002-12-13 20:15:29 +00001964 ri = ifp->info;
1965
hasso16705132003-05-25 14:49:19 +00001966 /* Do not display the interface if there is no
1967 * configuration about it.
1968 **/
1969 if ((!ifp->desc) &&
1970 (ri->split_horizon == ri->split_horizon_default) &&
1971 (ri->ri_send == RI_RIP_UNSPEC) &&
1972 (ri->ri_receive == RI_RIP_UNSPEC) &&
1973 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001974 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001975 (!ri->auth_str) &&
1976 (!ri->key_chain) )
1977 continue;
1978
paul718e3742002-12-13 20:15:29 +00001979 vty_out (vty, "interface %s%s", ifp->name,
1980 VTY_NEWLINE);
1981
1982 if (ifp->desc)
1983 vty_out (vty, " description %s%s", ifp->desc,
1984 VTY_NEWLINE);
1985
1986 /* Split horizon. */
1987 if (ri->split_horizon != ri->split_horizon_default)
1988 {
hasso16705132003-05-25 14:49:19 +00001989 switch (ri->split_horizon) {
1990 case RIP_SPLIT_HORIZON:
1991 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1992 break;
1993 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1994 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1995 VTY_NEWLINE);
1996 break;
1997 case RIP_NO_SPLIT_HORIZON:
1998 default:
1999 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2000 break;
2001 }
paul718e3742002-12-13 20:15:29 +00002002 }
2003
2004 /* RIP version setting. */
2005 if (ri->ri_send != RI_RIP_UNSPEC)
2006 vty_out (vty, " ip rip send version %s%s",
2007 lookup (ri_version_msg, ri->ri_send),
2008 VTY_NEWLINE);
2009
2010 if (ri->ri_receive != RI_RIP_UNSPEC)
2011 vty_out (vty, " ip rip receive version %s%s",
2012 lookup (ri_version_msg, ri->ri_receive),
2013 VTY_NEWLINE);
2014
2015 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00002016 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2017 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00002018
paul718e3742002-12-13 20:15:29 +00002019 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00002020 {
2021 vty_out (vty, " ip rip authentication mode md5");
2022 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2023 vty_out (vty, " auth-length old-ripd");
2024 else
2025 vty_out (vty, " auth-length rfc");
2026 vty_out (vty, "%s", VTY_NEWLINE);
2027 }
paul718e3742002-12-13 20:15:29 +00002028
2029 if (ri->auth_str)
2030 vty_out (vty, " ip rip authentication string %s%s",
2031 ri->auth_str, VTY_NEWLINE);
2032
2033 if (ri->key_chain)
2034 vty_out (vty, " ip rip authentication key-chain %s%s",
2035 ri->key_chain, VTY_NEWLINE);
2036
2037 vty_out (vty, "!%s", VTY_NEWLINE);
2038 }
2039 return 0;
2040}
2041
2042int
2043config_write_rip_network (struct vty *vty, int config_mode)
2044{
hasso8a676be2004-10-08 06:36:38 +00002045 unsigned int i;
paul718e3742002-12-13 20:15:29 +00002046 char *ifname;
2047 struct route_node *node;
2048
2049 /* Network type RIP enable interface statement. */
2050 for (node = route_top (rip_enable_network); node; node = route_next (node))
2051 if (node->info)
2052 vty_out (vty, "%s%s/%d%s",
2053 config_mode ? " network " : " ",
2054 inet_ntoa (node->p.u.prefix4),
2055 node->p.prefixlen,
2056 VTY_NEWLINE);
2057
2058 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002059 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002060 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2061 vty_out (vty, "%s%s%s",
2062 config_mode ? " network " : " ",
2063 ifname,
2064 VTY_NEWLINE);
2065
2066 /* RIP neighbors listing. */
2067 for (node = route_top (rip->neighbor); node; node = route_next (node))
2068 if (node->info)
2069 vty_out (vty, "%s%s%s",
2070 config_mode ? " neighbor " : " ",
2071 inet_ntoa (node->p.u.prefix4),
2072 VTY_NEWLINE);
2073
2074 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002075 if (config_mode) {
2076 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002077 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002078 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002079 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2080 vty_out (vty, " %spassive-interface %s%s",
2081 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2082 }
paul718e3742002-12-13 20:15:29 +00002083
2084 return 0;
2085}
2086
2087struct cmd_node interface_node =
2088{
2089 INTERFACE_NODE,
2090 "%s(config-if)# ",
2091 1,
2092};
2093
2094/* Called when interface structure allocated. */
2095int
2096rip_interface_new_hook (struct interface *ifp)
2097{
2098 ifp->info = rip_interface_new ();
2099 return 0;
2100}
2101
2102/* Called when interface structure deleted. */
2103int
2104rip_interface_delete_hook (struct interface *ifp)
2105{
2106 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002107 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002108 return 0;
2109}
2110
2111/* Allocate and initialize interface vector. */
2112void
2113rip_if_init ()
2114{
2115 /* Default initial size of interface vector. */
2116 if_init();
2117 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2118 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2119
2120 /* RIP network init. */
2121 rip_enable_interface = vector_init (1);
2122 rip_enable_network = route_table_init ();
2123
2124 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002125 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002126
2127 /* Install interface node. */
2128 install_node (&interface_node, rip_interface_config_write);
2129
2130 /* Install commands. */
2131 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002132 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002133 install_default (INTERFACE_NODE);
2134 install_element (INTERFACE_NODE, &interface_desc_cmd);
2135 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2136 install_element (RIP_NODE, &rip_network_cmd);
2137 install_element (RIP_NODE, &no_rip_network_cmd);
2138 install_element (RIP_NODE, &rip_neighbor_cmd);
2139 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2140
2141 install_element (RIP_NODE, &rip_passive_interface_cmd);
2142 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2143
2144 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2145 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2146 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2147 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2148 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2149
2150 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2151 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2152 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2153 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2154 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2155
2156 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002157 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002158 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2159 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002160 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002161
2162 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2163 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2164 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2165
2166 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2167 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2168 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2169
hasso16705132003-05-25 14:49:19 +00002170 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2171 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2172 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2173 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002174}