blob: 35685a75b74c575def7cb72230dcbfeab7de9193 [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"
pauldc63bfd2005-10-25 23:31:05 +000043#include "ripd/rip_interface.h"
David Lamparter6b0655a2014-06-04 06:53:35 +020044
pauldc63bfd2005-10-25 23:31:05 +000045/* static prototypes */
46static void rip_enable_apply (struct interface *);
47static void rip_passive_interface_apply (struct interface *);
48static int rip_if_down(struct interface *ifp);
49static int rip_enable_if_lookup (const char *ifname);
50static int rip_enable_network_lookup2 (struct connected *connected);
51static void rip_enable_apply_all (void);
David Lamparter6b0655a2014-06-04 06:53:35 +020052
Stephen Hemminger88d37b92014-11-03 01:20:09 +000053const struct message ri_version_msg[] =
paul718e3742002-12-13 20:15:29 +000054{
55 {RI_RIP_VERSION_1, "1"},
56 {RI_RIP_VERSION_2, "2"},
57 {RI_RIP_VERSION_1_AND_2, "1 2"},
paul718e3742002-12-13 20:15:29 +000058};
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;
David Lamparter6b0655a2014-06-04 06:53:35 +020071
paul718e3742002-12-13 20:15:29 +000072/* Join to the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000073static int
paul718e3742002-12-13 20:15:29 +000074ipv4_multicast_join (int sock,
75 struct in_addr group,
76 struct in_addr ifa,
77 unsigned int ifindex)
78{
79 int ret;
80
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +040081 ret = setsockopt_ipv4_multicast (sock,
paul718e3742002-12-13 20:15:29 +000082 IP_ADD_MEMBERSHIP,
paul718e3742002-12-13 20:15:29 +000083 group.s_addr,
84 ifindex);
85
86 if (ret < 0)
87 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
ajs6099b3b2004-11-20 02:06:59 +000088 safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +000089
90 return ret;
91}
92
93/* Leave from the RIP version 2 multicast group. */
pauldc63bfd2005-10-25 23:31:05 +000094static int
paul718e3742002-12-13 20:15:29 +000095ipv4_multicast_leave (int sock,
96 struct in_addr group,
97 struct in_addr ifa,
98 unsigned int ifindex)
99{
100 int ret;
101
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +0400102 ret = setsockopt_ipv4_multicast (sock,
paul718e3742002-12-13 20:15:29 +0000103 IP_DROP_MEMBERSHIP,
paul718e3742002-12-13 20:15:29 +0000104 group.s_addr,
105 ifindex);
106
107 if (ret < 0)
108 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
109
110 return ret;
111}
David Lamparter6b0655a2014-06-04 06:53:35 +0200112
paul718e3742002-12-13 20:15:29 +0000113/* Allocate new RIP's interface configuration. */
pauldc63bfd2005-10-25 23:31:05 +0000114static struct rip_interface *
115rip_interface_new (void)
paul718e3742002-12-13 20:15:29 +0000116{
117 struct rip_interface *ri;
118
Stephen Hemminger393deb92008-08-18 14:13:29 -0700119 ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
paul718e3742002-12-13 20:15:29 +0000120
121 /* Default authentication type is simple password for Cisco
122 compatibility. */
paul7755a8c2005-06-02 08:20:53 +0000123 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +0000124 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +0000125
126 /* Set default split-horizon behavior. If the interface is Frame
127 Relay or SMDS is enabled, the default value for split-horizon is
128 off. But currently Zebra does detect Frame Relay or SMDS
129 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000130 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000131 ri->split_horizon = ri->split_horizon_default;
132
133 return ri;
134}
135
136void
paul1a517862004-08-19 04:03:08 +0000137rip_interface_multicast_set (int sock, struct connected *connected)
paul718e3742002-12-13 20:15:29 +0000138{
paulc49ad8f2004-10-22 10:27:28 +0000139 assert (connected != NULL);
140
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +0400141 if (setsockopt_ipv4_multicast_if (sock, connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000142 {
143 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +0400144 "ifindex %d for interface %s",
145 sock, connected->ifp->ifindex,
paulc49ad8f2004-10-22 10:27:28 +0000146 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000147 }
paul2c61ae32005-08-16 15:22:14 +0000148
hasso3fb9cd62004-10-19 19:44:43 +0000149 return;
150}
paul718e3742002-12-13 20:15:29 +0000151
152/* Send RIP request packet to specified interface. */
pauldc63bfd2005-10-25 23:31:05 +0000153static void
paul718e3742002-12-13 20:15:29 +0000154rip_request_interface_send (struct interface *ifp, u_char version)
155{
156 struct sockaddr_in to;
157
158 /* RIPv2 support multicast. */
159 if (version == RIPv2 && if_is_multicast (ifp))
160 {
161
162 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000163 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000164
paul931cd542004-01-23 15:31:42 +0000165 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000166 return;
167 }
168
169 /* RIPv1 and non multicast interface. */
170 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
171 {
paul1eb8ef22005-04-07 07:30:20 +0000172 struct listnode *cnode, *cnnode;
173 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000174
175 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000176 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000177
paul1eb8ef22005-04-07 07:30:20 +0000178 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000179 {
hasso3fb9cd62004-10-19 19:44:43 +0000180 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000181 {
182 memset (&to, 0, sizeof (struct sockaddr_in));
183 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000184 if (connected->destination)
Andrew J. Schorre4529632006-12-12 19:18:21 +0000185 /* use specified broadcast or peer destination addr */
hasso3fb9cd62004-10-19 19:44:43 +0000186 to.sin_addr = connected->destination->u.prefix4;
Andrew J. Schorre4529632006-12-12 19:18:21 +0000187 else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
hasso3fb9cd62004-10-19 19:44:43 +0000188 /* calculate the appropriate broadcast address */
189 to.sin_addr.s_addr =
190 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
191 connected->address->prefixlen);
Andrew J. Schorre4529632006-12-12 19:18:21 +0000192 else
193 /* do not know where to send the packet */
194 continue;
paul718e3742002-12-13 20:15:29 +0000195
paul718e3742002-12-13 20:15:29 +0000196 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000197 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000198
paul931cd542004-01-23 15:31:42 +0000199 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000200 }
201 }
202 }
203}
204
205/* This will be executed when interface goes up. */
pauldc63bfd2005-10-25 23:31:05 +0000206static void
paul718e3742002-12-13 20:15:29 +0000207rip_request_interface (struct interface *ifp)
208{
209 struct rip_interface *ri;
210
211 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
212 if (if_is_loopback (ifp))
213 return;
214
215 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000216 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000217 return;
218
219 /* Fetch RIP interface information. */
220 ri = ifp->info;
221
222
223 /* If there is no version configuration in the interface,
224 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000225 {
226 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
227 rip->version_send : ri->ri_send);
228 if (vsend & RIPv1)
229 rip_request_interface_send (ifp, RIPv1);
230 if (vsend & RIPv2)
231 rip_request_interface_send (ifp, RIPv2);
232 }
paul718e3742002-12-13 20:15:29 +0000233}
234
Stephen Hemminger2c239702009-12-10 19:16:05 +0300235#if 0
paul718e3742002-12-13 20:15:29 +0000236/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000237static void
paul718e3742002-12-13 20:15:29 +0000238rip_request_neighbor (struct in_addr addr)
239{
240 struct sockaddr_in to;
241
242 memset (&to, 0, sizeof (struct sockaddr_in));
243 to.sin_port = htons (RIP_PORT_DEFAULT);
244 to.sin_addr = addr;
245
paul931cd542004-01-23 15:31:42 +0000246 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000247}
248
249/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000250static void
251rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000252{
253 struct route_node *rp;
254
255 if (! rip)
256 return;
257
258 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000259 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000260
261 /* Send request to all neighbor. */
262 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
263 if (rp->info)
264 rip_request_neighbor (rp->p.u.prefix4);
265}
Stephen Hemminger2c239702009-12-10 19:16:05 +0300266#endif
paul718e3742002-12-13 20:15:29 +0000267
268/* Multicast packet receive socket. */
pauldc63bfd2005-10-25 23:31:05 +0000269static int
paul718e3742002-12-13 20:15:29 +0000270rip_multicast_join (struct interface *ifp, int sock)
271{
hasso52dc7ee2004-09-23 19:18:23 +0000272 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000273 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000274
paul2e3b2e42002-12-13 21:03:13 +0000275 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000276 {
277 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000278 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000279
paul1eb8ef22005-04-07 07:30:20 +0000280 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000281 {
282 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000283 struct in_addr group;
284
paul1eb8ef22005-04-07 07:30:20 +0000285 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000286
287 if (p->family != AF_INET)
288 continue;
289
290 group.s_addr = htonl (INADDR_RIP_GROUP);
291 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
292 return -1;
293 else
294 return 0;
295 }
296 }
297 return 0;
298}
299
300/* Leave from multicast group. */
pauldc63bfd2005-10-25 23:31:05 +0000301static void
paul718e3742002-12-13 20:15:29 +0000302rip_multicast_leave (struct interface *ifp, int sock)
303{
hasso52dc7ee2004-09-23 19:18:23 +0000304 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000305 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000306
307 if (if_is_up (ifp) && if_is_multicast (ifp))
308 {
309 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000310 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000311
paul1eb8ef22005-04-07 07:30:20 +0000312 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000313 {
314 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000315 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000316
paul718e3742002-12-13 20:15:29 +0000317 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000318
paul718e3742002-12-13 20:15:29 +0000319 if (p->family != AF_INET)
320 continue;
321
322 group.s_addr = htonl (INADDR_RIP_GROUP);
323 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
324 return;
325 }
326 }
327}
328
329/* Is there and address on interface that I could use ? */
pauldc63bfd2005-10-25 23:31:05 +0000330static int
paul718e3742002-12-13 20:15:29 +0000331rip_if_ipv4_address_check (struct interface *ifp)
332{
333 struct listnode *nn;
334 struct connected *connected;
335 int count = 0;
336
paul1eb8ef22005-04-07 07:30:20 +0000337 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
338 {
339 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000340
paul1eb8ef22005-04-07 07:30:20 +0000341 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000342
paul1eb8ef22005-04-07 07:30:20 +0000343 if (p->family == AF_INET)
344 count++;
345 }
paul718e3742002-12-13 20:15:29 +0000346
347 return count;
348}
paul31a476c2003-09-29 19:54:53 +0000349
350
351
352
353/* Does this address belongs to me ? */
354int
355if_check_address (struct in_addr addr)
356{
hasso52dc7ee2004-09-23 19:18:23 +0000357 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000358 struct interface *ifp;
359
360 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000361 {
hasso52dc7ee2004-09-23 19:18:23 +0000362 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000363 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000364
paul1eb8ef22005-04-07 07:30:20 +0000365 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000366 {
paul31a476c2003-09-29 19:54:53 +0000367 struct prefix_ipv4 *p;
368
paul31a476c2003-09-29 19:54:53 +0000369 p = (struct prefix_ipv4 *) connected->address;
370
371 if (p->family != AF_INET)
372 continue;
373
374 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
375 return 1;
376 }
377 }
378 return 0;
379}
380
paul718e3742002-12-13 20:15:29 +0000381/* Inteface link down message processing. */
382int
383rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
384{
385 struct interface *ifp;
386 struct stream *s;
387
388 s = zclient->ibuf;
389
390 /* zebra_interface_state_read() updates interface structure in
391 iflist. */
392 ifp = zebra_interface_state_read(s);
393
394 if (ifp == NULL)
395 return 0;
396
397 rip_if_down(ifp);
398
399 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger30d20592009-07-28 11:58:51 +0100400 zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down",
401 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
402 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000403
404 return 0;
405}
406
407/* Inteface link up message processing */
408int
409rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
410{
411 struct interface *ifp;
412
413 /* zebra_interface_state_read () updates interface structure in
414 iflist. */
415 ifp = zebra_interface_state_read (zclient->ibuf);
416
417 if (ifp == NULL)
418 return 0;
419
420 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300421 zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up",
422 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
423 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000424
425 /* Check if this interface is RIP enabled or not.*/
426 rip_enable_apply (ifp);
427
428 /* Check for a passive interface */
429 rip_passive_interface_apply (ifp);
430
431 /* Apply distribute list to the all interface. */
432 rip_distribute_update_interface (ifp);
433
434 return 0;
435}
436
437/* Inteface addition message from zebra. */
438int
439rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
440{
441 struct interface *ifp;
442
443 ifp = zebra_interface_add_read (zclient->ibuf);
444
445 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300446 zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d",
447 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
448 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000449
450 /* Check if this interface is RIP enabled or not.*/
451 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000452
453 /* Check for a passive interface */
454 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000455
456 /* Apply distribute list to the all interface. */
457 rip_distribute_update_interface (ifp);
458
459 /* rip_request_neighbor_all (); */
460
hasso16705132003-05-25 14:49:19 +0000461 /* Check interface routemap. */
462 rip_if_rmap_update_interface (ifp);
463
paul718e3742002-12-13 20:15:29 +0000464 return 0;
465}
466
467int
468rip_interface_delete (int command, struct zclient *zclient,
469 zebra_size_t length)
470{
471 struct interface *ifp;
472 struct stream *s;
473
474
475 s = zclient->ibuf;
476 /* zebra_interface_state_read() updates interface structure in iflist */
477 ifp = zebra_interface_state_read(s);
478
479 if (ifp == NULL)
480 return 0;
481
482 if (if_is_up (ifp)) {
483 rip_if_down(ifp);
484 }
485
Stephen Hemminger2c239702009-12-10 19:16:05 +0300486 zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
487 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
488 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000489
490 /* To support pseudo interface do not free interface structure. */
491 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000492 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000493
494 return 0;
495}
496
497void
pauldc63bfd2005-10-25 23:31:05 +0000498rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000499{
hasso52dc7ee2004-09-23 19:18:23 +0000500 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000501 struct interface *ifp;
502 struct rip_interface *ri;
503
paul1eb8ef22005-04-07 07:30:20 +0000504 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000505 {
paul718e3742002-12-13 20:15:29 +0000506 ri = ifp->info;
507
508 ri->enable_network = 0;
509 ri->enable_interface = 0;
510 ri->running = 0;
511
512 if (ri->t_wakeup)
513 {
514 thread_cancel (ri->t_wakeup);
515 ri->t_wakeup = NULL;
516 }
517 }
518}
519
520void
pauldc63bfd2005-10-25 23:31:05 +0000521rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000522{
hasso52dc7ee2004-09-23 19:18:23 +0000523 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000524 struct interface *ifp;
525 struct rip_interface *ri;
526
paul1eb8ef22005-04-07 07:30:20 +0000527 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000528 {
paul718e3742002-12-13 20:15:29 +0000529 ri = ifp->info;
530
531 ri->enable_network = 0;
532 ri->enable_interface = 0;
533 ri->running = 0;
534
535 ri->ri_send = RI_RIP_UNSPEC;
536 ri->ri_receive = RI_RIP_UNSPEC;
537
paul7755a8c2005-06-02 08:20:53 +0000538 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000539
540 if (ri->auth_str)
541 {
542 free (ri->auth_str);
543 ri->auth_str = NULL;
544 }
545 if (ri->key_chain)
546 {
547 free (ri->key_chain);
548 ri->key_chain = NULL;
549 }
550
hasso16705132003-05-25 14:49:19 +0000551 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
552 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000553
554 ri->list[RIP_FILTER_IN] = NULL;
555 ri->list[RIP_FILTER_OUT] = NULL;
556
557 ri->prefix[RIP_FILTER_IN] = NULL;
558 ri->prefix[RIP_FILTER_OUT] = NULL;
559
560 if (ri->t_wakeup)
561 {
562 thread_cancel (ri->t_wakeup);
563 ri->t_wakeup = NULL;
564 }
565
566 ri->recv_badpackets = 0;
567 ri->recv_badroutes = 0;
568 ri->sent_updates = 0;
569
570 ri->passive = 0;
571 }
572}
573
574int
575rip_if_down(struct interface *ifp)
576{
577 struct route_node *rp;
578 struct rip_info *rinfo;
579 struct rip_interface *ri = NULL;
Lu Fengb397cf42014-07-18 06:13:18 +0000580 struct list *list = NULL;
581 struct listnode *listnode = NULL, *nextnode = NULL;
paul718e3742002-12-13 20:15:29 +0000582 if (rip)
Lu Fengb397cf42014-07-18 06:13:18 +0000583 for (rp = route_top (rip->table); rp; rp = route_next (rp))
584 if ((list = rp->info) != NULL)
585 for (ALL_LIST_ELEMENTS (list, listnode, nextnode, rinfo))
586 if (rinfo->ifindex == ifp->ifindex)
587 rip_ecmp_delete (rinfo);
paul718e3742002-12-13 20:15:29 +0000588
paul718e3742002-12-13 20:15:29 +0000589 ri = ifp->info;
590
591 if (ri->running)
592 {
593 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000594 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000595
596 /* Leave from multicast group. */
597 rip_multicast_leave (ifp, rip->sock);
598
599 ri->running = 0;
600 }
601
602 return 0;
603}
604
605/* Needed for stop RIP process. */
606void
607rip_if_down_all ()
608{
609 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000610 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000611
paul1eb8ef22005-04-07 07:30:20 +0000612 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
613 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000614}
615
hasso16705132003-05-25 14:49:19 +0000616static void
pauldc63bfd2005-10-25 23:31:05 +0000617rip_apply_address_add (struct connected *ifc)
618{
hasso16705132003-05-25 14:49:19 +0000619 struct prefix_ipv4 address;
620 struct prefix *p;
621
622 if (!rip)
623 return;
624
625 if (! if_is_up(ifc->ifp))
626 return;
627
628 p = ifc->address;
629
630 memset (&address, 0, sizeof (address));
631 address.family = p->family;
632 address.prefix = p->u.prefix4;
633 address.prefixlen = p->prefixlen;
634 apply_mask_ipv4(&address);
635
636 /* Check if this interface is RIP enabled or not
637 or Check if this address's prefix is RIP enabled */
638 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
639 (rip_enable_network_lookup2(ifc) >= 0))
640 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000641 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000642
643}
644
paul718e3742002-12-13 20:15:29 +0000645int
646rip_interface_address_add (int command, struct zclient *zclient,
647 zebra_size_t length)
648{
649 struct connected *ifc;
650 struct prefix *p;
651
paul0a589352004-05-08 11:48:26 +0000652 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
653 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000654
655 if (ifc == NULL)
656 return 0;
657
658 p = ifc->address;
659
660 if (p->family == AF_INET)
661 {
662 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000663 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000664 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000665
paul878ef2e2003-09-23 23:41:50 +0000666 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000667 /* Check if this prefix needs to be redistributed */
668 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000669
670#ifdef HAVE_SNMP
671 rip_ifaddr_add (ifc->ifp, ifc);
672#endif /* HAVE_SNMP */
673 }
674
675 return 0;
676}
677
hasso16705132003-05-25 14:49:19 +0000678static void
679rip_apply_address_del (struct connected *ifc) {
680 struct prefix_ipv4 address;
681 struct prefix *p;
682
683 if (!rip)
684 return;
685
686 if (! if_is_up(ifc->ifp))
687 return;
688
689 p = ifc->address;
690
691 memset (&address, 0, sizeof (address));
692 address.family = p->family;
693 address.prefix = p->u.prefix4;
694 address.prefixlen = p->prefixlen;
695 apply_mask_ipv4(&address);
696
697 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
698 &address, ifc->ifp->ifindex);
699}
700
paul718e3742002-12-13 20:15:29 +0000701int
702rip_interface_address_delete (int command, struct zclient *zclient,
703 zebra_size_t length)
704{
705 struct connected *ifc;
706 struct prefix *p;
707
paul0a589352004-05-08 11:48:26 +0000708 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
709 zclient->ibuf);
paul718e3742002-12-13 20:15:29 +0000710
711 if (ifc)
712 {
713 p = ifc->address;
714 if (p->family == AF_INET)
715 {
716 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000717 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000718 inet_ntoa (p->u.prefix4), p->prefixlen);
719
720#ifdef HAVE_SNMP
721 rip_ifaddr_delete (ifc->ifp, ifc);
722#endif /* HAVE_SNMP */
723
hasso16705132003-05-25 14:49:19 +0000724 /* Chech wether this prefix needs to be removed */
725 rip_apply_address_del(ifc);
726
paul718e3742002-12-13 20:15:29 +0000727 }
728
729 connected_free (ifc);
730
731 }
732
733 return 0;
734}
David Lamparter6b0655a2014-06-04 06:53:35 +0200735
paul718e3742002-12-13 20:15:29 +0000736/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000737/* Check wether the interface has at least a connected prefix that
738 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000739static int
hasso16705132003-05-25 14:49:19 +0000740rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000741{
paul1eb8ef22005-04-07 07:30:20 +0000742 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000743 struct connected *connected;
744 struct prefix_ipv4 address;
745
paul1eb8ef22005-04-07 07:30:20 +0000746 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
747 {
748 struct prefix *p;
749 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000750
paul1eb8ef22005-04-07 07:30:20 +0000751 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000752
paul1eb8ef22005-04-07 07:30:20 +0000753 if (p->family == AF_INET)
754 {
755 address.family = AF_INET;
756 address.prefix = p->u.prefix4;
757 address.prefixlen = IPV4_MAX_BITLEN;
758
759 node = route_node_match (rip_enable_network,
760 (struct prefix *)&address);
761 if (node)
762 {
763 route_unlock_node (node);
764 return 1;
765 }
766 }
767 }
paul718e3742002-12-13 20:15:29 +0000768 return -1;
769}
770
hasso16705132003-05-25 14:49:19 +0000771/* Check wether connected is within the ripng_enable_network table. */
772int
773rip_enable_network_lookup2 (struct connected *connected)
774{
775 struct prefix_ipv4 address;
776 struct prefix *p;
777
778 p = connected->address;
779
780 if (p->family == AF_INET) {
781 struct route_node *node;
782
783 address.family = p->family;
784 address.prefix = p->u.prefix4;
785 address.prefixlen = IPV4_MAX_BITLEN;
786
787 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
788 node = route_node_match (rip_enable_network,
789 (struct prefix *)&address);
790
791 if (node) {
792 route_unlock_node (node);
793 return 1;
794 }
795 }
796
797 return -1;
798}
paul718e3742002-12-13 20:15:29 +0000799/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000800static int
paul718e3742002-12-13 20:15:29 +0000801rip_enable_network_add (struct prefix *p)
802{
803 struct route_node *node;
804
805 node = route_node_get (rip_enable_network, p);
806
807 if (node->info)
808 {
809 route_unlock_node (node);
810 return -1;
811 }
812 else
hasso8a676be2004-10-08 06:36:38 +0000813 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000814
hasso16705132003-05-25 14:49:19 +0000815 /* XXX: One should find a better solution than a generic one */
816 rip_enable_apply_all();
817
paul718e3742002-12-13 20:15:29 +0000818 return 1;
819}
820
821/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000822static int
paul718e3742002-12-13 20:15:29 +0000823rip_enable_network_delete (struct prefix *p)
824{
825 struct route_node *node;
826
827 node = route_node_lookup (rip_enable_network, p);
828 if (node)
829 {
830 node->info = NULL;
831
832 /* Unlock info lock. */
833 route_unlock_node (node);
834
835 /* Unlock lookup lock. */
836 route_unlock_node (node);
837
hasso16705132003-05-25 14:49:19 +0000838 /* XXX: One should find a better solution than a generic one */
839 rip_enable_apply_all ();
840
paul718e3742002-12-13 20:15:29 +0000841 return 1;
842 }
843 return -1;
844}
845
846/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000847static int
hasso98b718a2004-10-11 12:57:57 +0000848rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000849{
hasso8a676be2004-10-08 06:36:38 +0000850 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000851 char *str;
852
paul55468c82005-03-14 20:19:01 +0000853 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000854 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
855 if (strcmp (str, ifname) == 0)
856 return i;
857 return -1;
858}
859
860/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000861static int
hasso98b718a2004-10-11 12:57:57 +0000862rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000863{
864 int ret;
865
866 ret = rip_enable_if_lookup (ifname);
867 if (ret >= 0)
868 return -1;
869
870 vector_set (rip_enable_interface, strdup (ifname));
871
hasso16705132003-05-25 14:49:19 +0000872 rip_enable_apply_all(); /* TODOVJ */
873
paul718e3742002-12-13 20:15:29 +0000874 return 1;
875}
876
877/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000878static int
hasso98b718a2004-10-11 12:57:57 +0000879rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000880{
881 int index;
882 char *str;
883
884 index = rip_enable_if_lookup (ifname);
885 if (index < 0)
886 return -1;
887
888 str = vector_slot (rip_enable_interface, index);
889 free (str);
890 vector_unset (rip_enable_interface, index);
891
hasso16705132003-05-25 14:49:19 +0000892 rip_enable_apply_all(); /* TODOVJ */
893
paul718e3742002-12-13 20:15:29 +0000894 return 1;
895}
896
897/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000898static int
paul718e3742002-12-13 20:15:29 +0000899rip_interface_wakeup (struct thread *t)
900{
901 struct interface *ifp;
902 struct rip_interface *ri;
903
904 /* Get interface. */
905 ifp = THREAD_ARG (t);
906
907 ri = ifp->info;
908 ri->t_wakeup = NULL;
909
910 /* Join to multicast group. */
911 if (rip_multicast_join (ifp, rip->sock) < 0)
912 {
913 zlog_err ("multicast join failed, interface %s not running", ifp->name);
914 return 0;
915 }
916
917 /* Set running flag. */
918 ri->running = 1;
919
920 /* Send RIP request to the interface. */
921 rip_request_interface (ifp);
922
923 return 0;
924}
925
pauldc63bfd2005-10-25 23:31:05 +0000926static void
paul718e3742002-12-13 20:15:29 +0000927rip_connect_set (struct interface *ifp, int set)
928{
paul1eb8ef22005-04-07 07:30:20 +0000929 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000930 struct connected *connected;
931 struct prefix_ipv4 address;
932
paul1eb8ef22005-04-07 07:30:20 +0000933 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
934 {
935 struct prefix *p;
936 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000937
paul1eb8ef22005-04-07 07:30:20 +0000938 if (p->family != AF_INET)
939 continue;
paul718e3742002-12-13 20:15:29 +0000940
paul1eb8ef22005-04-07 07:30:20 +0000941 address.family = AF_INET;
942 address.prefix = p->u.prefix4;
943 address.prefixlen = p->prefixlen;
944 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000945
paul1eb8ef22005-04-07 07:30:20 +0000946 if (set) {
947 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
948 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
949 (rip_enable_network_lookup2(connected) >= 0))
950 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000951 &address, connected->ifp->ifindex,
952 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000953 } else
954 {
955 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
956 &address, connected->ifp->ifindex);
957 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
958 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000959 &address, connected->ifp->ifindex,
960 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000961 }
962 }
paul718e3742002-12-13 20:15:29 +0000963}
964
965/* Update interface status. */
966void
967rip_enable_apply (struct interface *ifp)
968{
969 int ret;
970 struct rip_interface *ri = NULL;
971
972 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +0000973 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000974 return;
975
976 ri = ifp->info;
977
978 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +0000979 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +0000980
981 /* If the interface is matched. */
982 if (ret > 0)
983 ri->enable_network = 1;
984 else
985 ri->enable_network = 0;
986
987 /* Check interface name configuration. */
988 ret = rip_enable_if_lookup (ifp->name);
989 if (ret >= 0)
990 ri->enable_interface = 1;
991 else
992 ri->enable_interface = 0;
993
994 /* any interface MUST have an IPv4 address */
995 if ( ! rip_if_ipv4_address_check (ifp) )
996 {
997 ri->enable_network = 0;
998 ri->enable_interface = 0;
999 }
1000
1001 /* Update running status of the interface. */
1002 if (ri->enable_network || ri->enable_interface)
1003 {
paul718e3742002-12-13 20:15:29 +00001004 {
1005 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001006 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001007
1008 /* Add interface wake up thread. */
1009 if (! ri->t_wakeup)
1010 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1011 ifp, 1);
1012 rip_connect_set (ifp, 1);
1013 }
1014 }
1015 else
1016 {
1017 if (ri->running)
1018 {
hasso16705132003-05-25 14:49:19 +00001019 /* Might as well clean up the route table as well
1020 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1021 **/
paul718e3742002-12-13 20:15:29 +00001022 rip_if_down(ifp);
1023
paul718e3742002-12-13 20:15:29 +00001024 rip_connect_set (ifp, 0);
1025 }
1026 }
1027}
1028
1029/* Apply network configuration to all interface. */
1030void
1031rip_enable_apply_all ()
1032{
1033 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001034 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001035
1036 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001037 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1038 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001039}
1040
1041int
1042rip_neighbor_lookup (struct sockaddr_in *from)
1043{
1044 struct prefix_ipv4 p;
1045 struct route_node *node;
1046
1047 memset (&p, 0, sizeof (struct prefix_ipv4));
1048 p.family = AF_INET;
1049 p.prefix = from->sin_addr;
1050 p.prefixlen = IPV4_MAX_BITLEN;
1051
1052 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1053 if (node)
1054 {
1055 route_unlock_node (node);
1056 return 1;
1057 }
1058 return 0;
1059}
1060
1061/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001062static int
paul718e3742002-12-13 20:15:29 +00001063rip_neighbor_add (struct prefix_ipv4 *p)
1064{
1065 struct route_node *node;
1066
1067 node = route_node_get (rip->neighbor, (struct prefix *) p);
1068
1069 if (node->info)
1070 return -1;
1071
1072 node->info = rip->neighbor;
1073
1074 return 0;
1075}
1076
1077/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001078static int
paul718e3742002-12-13 20:15:29 +00001079rip_neighbor_delete (struct prefix_ipv4 *p)
1080{
1081 struct route_node *node;
1082
1083 /* Lock for look up. */
1084 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1085 if (! node)
1086 return -1;
1087
1088 node->info = NULL;
1089
1090 /* Unlock lookup lock. */
1091 route_unlock_node (node);
1092
1093 /* Unlock real neighbor information lock. */
1094 route_unlock_node (node);
1095
1096 return 0;
1097}
1098
1099/* Clear all network and neighbor configuration. */
1100void
1101rip_clean_network ()
1102{
hasso8a676be2004-10-08 06:36:38 +00001103 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001104 char *str;
1105 struct route_node *rn;
1106
1107 /* rip_enable_network. */
1108 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1109 if (rn->info)
1110 {
1111 rn->info = NULL;
1112 route_unlock_node (rn);
1113 }
1114
1115 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001116 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001117 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1118 {
1119 free (str);
1120 vector_slot (rip_enable_interface, i) = NULL;
1121 }
1122}
David Lamparter6b0655a2014-06-04 06:53:35 +02001123
paul718e3742002-12-13 20:15:29 +00001124/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001125static int
hasso98b718a2004-10-11 12:57:57 +00001126rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001127{
hasso8a676be2004-10-08 06:36:38 +00001128 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001129 char *str;
1130
paul55468c82005-03-14 20:19:01 +00001131 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001132 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001133 if (strcmp (str, ifname) == 0)
1134 return i;
1135 return -1;
1136}
1137
1138void
1139rip_passive_interface_apply (struct interface *ifp)
1140{
paul718e3742002-12-13 20:15:29 +00001141 struct rip_interface *ri;
1142
1143 ri = ifp->info;
1144
paul4aaff3f2003-06-07 01:04:45 +00001145 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1146 passive_default : !passive_default);
1147
1148 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001149 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001150}
1151
pauldc63bfd2005-10-25 23:31:05 +00001152static void
1153rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001154{
1155 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001156 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001157
paul1eb8ef22005-04-07 07:30:20 +00001158 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1159 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001160}
1161
1162/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001163static int
hasso98b718a2004-10-11 12:57:57 +00001164rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001165{
paul4aaff3f2003-06-07 01:04:45 +00001166 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001167 return CMD_WARNING;
1168
paul4aaff3f2003-06-07 01:04:45 +00001169 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001170
1171 rip_passive_interface_apply_all ();
1172
1173 return CMD_SUCCESS;
1174}
1175
pauldc63bfd2005-10-25 23:31:05 +00001176static int
hasso98b718a2004-10-11 12:57:57 +00001177rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001178{
1179 int i;
1180 char *str;
1181
paul4aaff3f2003-06-07 01:04:45 +00001182 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001183 if (i < 0)
1184 return CMD_WARNING;
1185
paul4aaff3f2003-06-07 01:04:45 +00001186 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001187 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001188 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001189
1190 rip_passive_interface_apply_all ();
1191
1192 return CMD_SUCCESS;
1193}
1194
1195/* Free all configured RIP passive-interface settings. */
1196void
pauldc63bfd2005-10-25 23:31:05 +00001197rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001198{
hasso8a676be2004-10-08 06:36:38 +00001199 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001200 char *str;
1201
paul55468c82005-03-14 20:19:01 +00001202 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001203 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001204 {
1205 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001206 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001207 }
1208 rip_passive_interface_apply_all ();
1209}
David Lamparter6b0655a2014-06-04 06:53:35 +02001210
paul718e3742002-12-13 20:15:29 +00001211/* RIP enable network or interface configuration. */
1212DEFUN (rip_network,
1213 rip_network_cmd,
1214 "network (A.B.C.D/M|WORD)",
1215 "Enable routing on an IP network\n"
1216 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1217 "Interface name\n")
1218{
1219 int ret;
1220 struct prefix_ipv4 p;
1221
1222 ret = str2prefix_ipv4 (argv[0], &p);
1223
1224 if (ret)
1225 ret = rip_enable_network_add ((struct prefix *) &p);
1226 else
1227 ret = rip_enable_if_add (argv[0]);
1228
1229 if (ret < 0)
1230 {
1231 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1232 VTY_NEWLINE);
1233 return CMD_WARNING;
1234 }
1235
paul718e3742002-12-13 20:15:29 +00001236 return CMD_SUCCESS;
1237}
1238
1239/* RIP enable network or interface configuration. */
1240DEFUN (no_rip_network,
1241 no_rip_network_cmd,
1242 "no network (A.B.C.D/M|WORD)",
1243 NO_STR
1244 "Enable routing on an IP network\n"
1245 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1246 "Interface name\n")
1247{
1248 int ret;
1249 struct prefix_ipv4 p;
1250
1251 ret = str2prefix_ipv4 (argv[0], &p);
1252
1253 if (ret)
1254 ret = rip_enable_network_delete ((struct prefix *) &p);
1255 else
1256 ret = rip_enable_if_delete (argv[0]);
1257
1258 if (ret < 0)
1259 {
1260 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1261 VTY_NEWLINE);
1262 return CMD_WARNING;
1263 }
1264
paul718e3742002-12-13 20:15:29 +00001265 return CMD_SUCCESS;
1266}
1267
1268/* RIP neighbor configuration set. */
1269DEFUN (rip_neighbor,
1270 rip_neighbor_cmd,
1271 "neighbor A.B.C.D",
1272 "Specify a neighbor router\n"
1273 "Neighbor address\n")
1274{
1275 int ret;
1276 struct prefix_ipv4 p;
1277
1278 ret = str2prefix_ipv4 (argv[0], &p);
1279
1280 if (ret <= 0)
1281 {
1282 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1283 return CMD_WARNING;
1284 }
1285
1286 rip_neighbor_add (&p);
1287
1288 return CMD_SUCCESS;
1289}
1290
1291/* RIP neighbor configuration unset. */
1292DEFUN (no_rip_neighbor,
1293 no_rip_neighbor_cmd,
1294 "no neighbor A.B.C.D",
1295 NO_STR
1296 "Specify a neighbor router\n"
1297 "Neighbor address\n")
1298{
1299 int ret;
1300 struct prefix_ipv4 p;
1301
1302 ret = str2prefix_ipv4 (argv[0], &p);
1303
1304 if (ret <= 0)
1305 {
1306 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1307 return CMD_WARNING;
1308 }
1309
1310 rip_neighbor_delete (&p);
1311
1312 return CMD_SUCCESS;
1313}
1314
1315DEFUN (ip_rip_receive_version,
1316 ip_rip_receive_version_cmd,
1317 "ip rip receive version (1|2)",
1318 IP_STR
1319 "Routing Information Protocol\n"
1320 "Advertisement reception\n"
1321 "Version control\n"
1322 "RIP version 1\n"
1323 "RIP version 2\n")
1324{
1325 struct interface *ifp;
1326 struct rip_interface *ri;
1327
1328 ifp = (struct interface *)vty->index;
1329 ri = ifp->info;
1330
1331 /* Version 1. */
1332 if (atoi (argv[0]) == 1)
1333 {
1334 ri->ri_receive = RI_RIP_VERSION_1;
1335 return CMD_SUCCESS;
1336 }
1337 if (atoi (argv[0]) == 2)
1338 {
1339 ri->ri_receive = RI_RIP_VERSION_2;
1340 return CMD_SUCCESS;
1341 }
1342 return CMD_WARNING;
1343}
1344
1345DEFUN (ip_rip_receive_version_1,
1346 ip_rip_receive_version_1_cmd,
1347 "ip rip receive version 1 2",
1348 IP_STR
1349 "Routing Information Protocol\n"
1350 "Advertisement reception\n"
1351 "Version control\n"
1352 "RIP version 1\n"
1353 "RIP version 2\n")
1354{
1355 struct interface *ifp;
1356 struct rip_interface *ri;
1357
1358 ifp = (struct interface *)vty->index;
1359 ri = ifp->info;
1360
1361 /* Version 1 and 2. */
1362 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1363 return CMD_SUCCESS;
1364}
1365
1366DEFUN (ip_rip_receive_version_2,
1367 ip_rip_receive_version_2_cmd,
1368 "ip rip receive version 2 1",
1369 IP_STR
1370 "Routing Information Protocol\n"
1371 "Advertisement reception\n"
1372 "Version control\n"
1373 "RIP version 2\n"
1374 "RIP version 1\n")
1375{
1376 struct interface *ifp;
1377 struct rip_interface *ri;
1378
1379 ifp = (struct interface *)vty->index;
1380 ri = ifp->info;
1381
1382 /* Version 1 and 2. */
1383 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1384 return CMD_SUCCESS;
1385}
1386
1387DEFUN (no_ip_rip_receive_version,
1388 no_ip_rip_receive_version_cmd,
1389 "no ip rip receive version",
1390 NO_STR
1391 IP_STR
1392 "Routing Information Protocol\n"
1393 "Advertisement reception\n"
1394 "Version control\n")
1395{
1396 struct interface *ifp;
1397 struct rip_interface *ri;
1398
1399 ifp = (struct interface *)vty->index;
1400 ri = ifp->info;
1401
1402 ri->ri_receive = RI_RIP_UNSPEC;
1403 return CMD_SUCCESS;
1404}
1405
1406ALIAS (no_ip_rip_receive_version,
1407 no_ip_rip_receive_version_num_cmd,
1408 "no ip rip receive version (1|2)",
1409 NO_STR
1410 IP_STR
1411 "Routing Information Protocol\n"
1412 "Advertisement reception\n"
1413 "Version control\n"
1414 "Version 1\n"
1415 "Version 2\n")
1416
1417DEFUN (ip_rip_send_version,
1418 ip_rip_send_version_cmd,
1419 "ip rip send version (1|2)",
1420 IP_STR
1421 "Routing Information Protocol\n"
1422 "Advertisement transmission\n"
1423 "Version control\n"
1424 "RIP version 1\n"
1425 "RIP version 2\n")
1426{
1427 struct interface *ifp;
1428 struct rip_interface *ri;
1429
1430 ifp = (struct interface *)vty->index;
1431 ri = ifp->info;
1432
1433 /* Version 1. */
1434 if (atoi (argv[0]) == 1)
1435 {
1436 ri->ri_send = RI_RIP_VERSION_1;
1437 return CMD_SUCCESS;
1438 }
1439 if (atoi (argv[0]) == 2)
1440 {
1441 ri->ri_send = RI_RIP_VERSION_2;
1442 return CMD_SUCCESS;
1443 }
1444 return CMD_WARNING;
1445}
1446
1447DEFUN (ip_rip_send_version_1,
1448 ip_rip_send_version_1_cmd,
1449 "ip rip send version 1 2",
1450 IP_STR
1451 "Routing Information Protocol\n"
1452 "Advertisement transmission\n"
1453 "Version control\n"
1454 "RIP version 1\n"
1455 "RIP version 2\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_send = RI_RIP_VERSION_1_AND_2;
1465 return CMD_SUCCESS;
1466}
1467
1468DEFUN (ip_rip_send_version_2,
1469 ip_rip_send_version_2_cmd,
1470 "ip rip send version 2 1",
1471 IP_STR
1472 "Routing Information Protocol\n"
1473 "Advertisement transmission\n"
1474 "Version control\n"
1475 "RIP version 2\n"
1476 "RIP version 1\n")
1477{
1478 struct interface *ifp;
1479 struct rip_interface *ri;
1480
1481 ifp = (struct interface *)vty->index;
1482 ri = ifp->info;
1483
1484 /* Version 1 and 2. */
1485 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1486 return CMD_SUCCESS;
1487}
1488
1489DEFUN (no_ip_rip_send_version,
1490 no_ip_rip_send_version_cmd,
1491 "no ip rip send version",
1492 NO_STR
1493 IP_STR
1494 "Routing Information Protocol\n"
1495 "Advertisement transmission\n"
1496 "Version control\n")
1497{
1498 struct interface *ifp;
1499 struct rip_interface *ri;
1500
1501 ifp = (struct interface *)vty->index;
1502 ri = ifp->info;
1503
1504 ri->ri_send = RI_RIP_UNSPEC;
1505 return CMD_SUCCESS;
1506}
1507
1508ALIAS (no_ip_rip_send_version,
1509 no_ip_rip_send_version_num_cmd,
1510 "no ip rip send version (1|2)",
1511 NO_STR
1512 IP_STR
1513 "Routing Information Protocol\n"
1514 "Advertisement transmission\n"
1515 "Version control\n"
1516 "Version 1\n"
1517 "Version 2\n")
1518
1519DEFUN (ip_rip_authentication_mode,
1520 ip_rip_authentication_mode_cmd,
1521 "ip rip authentication mode (md5|text)",
1522 IP_STR
1523 "Routing Information Protocol\n"
1524 "Authentication control\n"
1525 "Authentication mode\n"
1526 "Keyed message digest\n"
1527 "Clear text authentication\n")
1528{
1529 struct interface *ifp;
1530 struct rip_interface *ri;
Paul Jakma15a2b082006-05-04 07:36:34 +00001531 int auth_type;
paul718e3742002-12-13 20:15:29 +00001532
1533 ifp = (struct interface *)vty->index;
1534 ri = ifp->info;
1535
paulca5e5162004-06-06 22:06:33 +00001536 if ( (argc < 1) || (argc > 2) )
1537 {
1538 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1539 return CMD_WARNING;
1540 }
1541
paul718e3742002-12-13 20:15:29 +00001542 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001543 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001544 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001545 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001546 else
1547 {
1548 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1549 return CMD_WARNING;
1550 }
1551
paulca5e5162004-06-06 22:06:33 +00001552 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001553 {
1554 ri->auth_type = auth_type;
1555 return CMD_SUCCESS;
1556 }
paulca5e5162004-06-06 22:06:33 +00001557
Paul Jakma15a2b082006-05-04 07:36:34 +00001558 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001559 {
1560 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1561 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001562 }
paulca5e5162004-06-06 22:06:33 +00001563
1564 if (strncmp ("r", argv[1], 1) == 0)
1565 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1566 else if (strncmp ("o", argv[1], 1) == 0)
1567 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1568 else
1569 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001570
1571 ri->auth_type = auth_type;
1572
paul718e3742002-12-13 20:15:29 +00001573 return CMD_SUCCESS;
1574}
1575
paulca5e5162004-06-06 22:06:33 +00001576ALIAS (ip_rip_authentication_mode,
1577 ip_rip_authentication_mode_authlen_cmd,
1578 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1579 IP_STR
1580 "Routing Information Protocol\n"
1581 "Authentication control\n"
1582 "Authentication mode\n"
1583 "Keyed message digest\n"
1584 "Clear text authentication\n"
1585 "MD5 authentication data length\n"
1586 "RFC compatible\n"
1587 "Old ripd compatible\n")
1588
paul718e3742002-12-13 20:15:29 +00001589DEFUN (no_ip_rip_authentication_mode,
1590 no_ip_rip_authentication_mode_cmd,
1591 "no ip rip authentication mode",
1592 NO_STR
1593 IP_STR
1594 "Routing Information Protocol\n"
1595 "Authentication control\n"
1596 "Authentication mode\n")
1597{
1598 struct interface *ifp;
1599 struct rip_interface *ri;
1600
1601 ifp = (struct interface *)vty->index;
1602 ri = ifp->info;
1603
paul7755a8c2005-06-02 08:20:53 +00001604 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001605 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001606
1607 return CMD_SUCCESS;
1608}
1609
1610ALIAS (no_ip_rip_authentication_mode,
1611 no_ip_rip_authentication_mode_type_cmd,
1612 "no ip rip authentication mode (md5|text)",
1613 NO_STR
1614 IP_STR
1615 "Routing Information Protocol\n"
1616 "Authentication control\n"
1617 "Authentication mode\n"
1618 "Keyed message digest\n"
1619 "Clear text authentication\n")
1620
paulca5e5162004-06-06 22:06:33 +00001621ALIAS (no_ip_rip_authentication_mode,
1622 no_ip_rip_authentication_mode_type_authlen_cmd,
1623 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1624 NO_STR
1625 IP_STR
1626 "Routing Information Protocol\n"
1627 "Authentication control\n"
1628 "Authentication mode\n"
1629 "Keyed message digest\n"
1630 "Clear text authentication\n"
1631 "MD5 authentication data length\n"
1632 "RFC compatible\n"
1633 "Old ripd compatible\n")
1634
paul718e3742002-12-13 20:15:29 +00001635DEFUN (ip_rip_authentication_string,
1636 ip_rip_authentication_string_cmd,
1637 "ip rip authentication string LINE",
1638 IP_STR
1639 "Routing Information Protocol\n"
1640 "Authentication control\n"
1641 "Authentication string\n"
1642 "Authentication string\n")
1643{
1644 struct interface *ifp;
1645 struct rip_interface *ri;
1646
1647 ifp = (struct interface *)vty->index;
1648 ri = ifp->info;
1649
1650 if (strlen (argv[0]) > 16)
1651 {
1652 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1653 VTY_NEWLINE);
1654 return CMD_WARNING;
1655 }
1656
1657 if (ri->key_chain)
1658 {
1659 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1660 return CMD_WARNING;
1661 }
1662
1663 if (ri->auth_str)
1664 free (ri->auth_str);
1665
1666 ri->auth_str = strdup (argv[0]);
1667
1668 return CMD_SUCCESS;
1669}
1670
1671DEFUN (no_ip_rip_authentication_string,
1672 no_ip_rip_authentication_string_cmd,
1673 "no ip rip authentication string",
1674 NO_STR
1675 IP_STR
1676 "Routing Information Protocol\n"
1677 "Authentication control\n"
1678 "Authentication string\n")
1679{
1680 struct interface *ifp;
1681 struct rip_interface *ri;
1682
1683 ifp = (struct interface *)vty->index;
1684 ri = ifp->info;
1685
1686 if (ri->auth_str)
1687 free (ri->auth_str);
1688
1689 ri->auth_str = NULL;
1690
1691 return CMD_SUCCESS;
1692}
1693
1694ALIAS (no_ip_rip_authentication_string,
1695 no_ip_rip_authentication_string2_cmd,
1696 "no ip rip authentication string LINE",
1697 NO_STR
1698 IP_STR
1699 "Routing Information Protocol\n"
1700 "Authentication control\n"
1701 "Authentication string\n"
1702 "Authentication string\n")
1703
1704DEFUN (ip_rip_authentication_key_chain,
1705 ip_rip_authentication_key_chain_cmd,
1706 "ip rip authentication key-chain LINE",
1707 IP_STR
1708 "Routing Information Protocol\n"
1709 "Authentication control\n"
1710 "Authentication key-chain\n"
1711 "name of key-chain\n")
1712{
1713 struct interface *ifp;
1714 struct rip_interface *ri;
1715
1716 ifp = (struct interface *) vty->index;
1717 ri = ifp->info;
1718
1719 if (ri->auth_str)
1720 {
1721 vty_out (vty, "%% authentication string configuration exists%s",
1722 VTY_NEWLINE);
1723 return CMD_WARNING;
1724 }
1725
1726 if (ri->key_chain)
1727 free (ri->key_chain);
1728
1729 ri->key_chain = strdup (argv[0]);
1730
1731 return CMD_SUCCESS;
1732}
1733
1734DEFUN (no_ip_rip_authentication_key_chain,
1735 no_ip_rip_authentication_key_chain_cmd,
1736 "no ip rip authentication key-chain",
1737 NO_STR
1738 IP_STR
1739 "Routing Information Protocol\n"
1740 "Authentication control\n"
1741 "Authentication key-chain\n")
1742{
1743 struct interface *ifp;
1744 struct rip_interface *ri;
1745
1746 ifp = (struct interface *) vty->index;
1747 ri = ifp->info;
1748
1749 if (ri->key_chain)
1750 free (ri->key_chain);
1751
1752 ri->key_chain = NULL;
1753
1754 return CMD_SUCCESS;
1755}
1756
1757ALIAS (no_ip_rip_authentication_key_chain,
1758 no_ip_rip_authentication_key_chain2_cmd,
1759 "no ip rip authentication key-chain LINE",
1760 NO_STR
1761 IP_STR
1762 "Routing Information Protocol\n"
1763 "Authentication control\n"
1764 "Authentication key-chain\n"
1765 "name of key-chain\n")
1766
hasso16705132003-05-25 14:49:19 +00001767/* CHANGED: ip rip split-horizon
1768 Cisco and Zebra's command is
1769 ip split-horizon
1770 */
1771DEFUN (ip_rip_split_horizon,
1772 ip_rip_split_horizon_cmd,
1773 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001774 IP_STR
hasso16705132003-05-25 14:49:19 +00001775 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001776 "Perform split horizon\n")
1777{
1778 struct interface *ifp;
1779 struct rip_interface *ri;
1780
1781 ifp = vty->index;
1782 ri = ifp->info;
1783
hasso16705132003-05-25 14:49:19 +00001784 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001785 return CMD_SUCCESS;
1786}
1787
hasso16705132003-05-25 14:49:19 +00001788DEFUN (ip_rip_split_horizon_poisoned_reverse,
1789 ip_rip_split_horizon_poisoned_reverse_cmd,
1790 "ip rip split-horizon poisoned-reverse",
1791 IP_STR
1792 "Routing Information Protocol\n"
1793 "Perform split horizon\n"
1794 "With poisoned-reverse\n")
1795{
1796 struct interface *ifp;
1797 struct rip_interface *ri;
1798
1799 ifp = vty->index;
1800 ri = ifp->info;
1801
1802 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1803 return CMD_SUCCESS;
1804}
1805
1806/* CHANGED: no ip rip split-horizon
1807 Cisco and Zebra's command is
1808 no ip split-horizon
1809 */
1810DEFUN (no_ip_rip_split_horizon,
1811 no_ip_rip_split_horizon_cmd,
1812 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001813 NO_STR
1814 IP_STR
hasso16705132003-05-25 14:49:19 +00001815 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001816 "Perform split horizon\n")
1817{
1818 struct interface *ifp;
1819 struct rip_interface *ri;
1820
1821 ifp = vty->index;
1822 ri = ifp->info;
1823
hasso16705132003-05-25 14:49:19 +00001824 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001825 return CMD_SUCCESS;
1826}
1827
vincentfac3e842005-10-06 07:45:43 +00001828DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001829 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1830 "no ip rip split-horizon poisoned-reverse",
1831 NO_STR
1832 IP_STR
1833 "Routing Information Protocol\n"
1834 "Perform split horizon\n"
1835 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001836{
1837 struct interface *ifp;
1838 struct rip_interface *ri;
1839
1840 ifp = vty->index;
1841 ri = ifp->info;
1842
1843 switch( ri->split_horizon )
1844 {
1845 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1846 ri->split_horizon = RIP_SPLIT_HORIZON;
1847 default:
1848 break;
1849 }
1850
1851 return CMD_SUCCESS;
1852}
hasso16705132003-05-25 14:49:19 +00001853
paul718e3742002-12-13 20:15:29 +00001854DEFUN (rip_passive_interface,
1855 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001856 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001857 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001858 "Interface name\n"
1859 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001860{
hasso98b718a2004-10-11 12:57:57 +00001861 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001862
1863 if (!strcmp(ifname,"default")) {
1864 passive_default = 1;
1865 rip_passive_nondefault_clean();
1866 return CMD_SUCCESS;
1867 }
1868 if (passive_default)
1869 return rip_passive_nondefault_unset (vty, ifname);
1870 else
1871 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001872}
1873
1874DEFUN (no_rip_passive_interface,
1875 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001876 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001877 NO_STR
1878 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001879 "Interface name\n"
1880 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001881{
hasso98b718a2004-10-11 12:57:57 +00001882 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001883
1884 if (!strcmp(ifname,"default")) {
1885 passive_default = 0;
1886 rip_passive_nondefault_clean();
1887 return CMD_SUCCESS;
1888 }
1889 if (passive_default)
1890 return rip_passive_nondefault_set (vty, ifname);
1891 else
1892 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001893}
David Lamparter6b0655a2014-06-04 06:53:35 +02001894
paul718e3742002-12-13 20:15:29 +00001895/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001896static int
paul718e3742002-12-13 20:15:29 +00001897rip_interface_config_write (struct vty *vty)
1898{
hasso52dc7ee2004-09-23 19:18:23 +00001899 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001900 struct interface *ifp;
1901
paul1eb8ef22005-04-07 07:30:20 +00001902 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001903 {
1904 struct rip_interface *ri;
1905
paul718e3742002-12-13 20:15:29 +00001906 ri = ifp->info;
1907
hasso16705132003-05-25 14:49:19 +00001908 /* Do not display the interface if there is no
1909 * configuration about it.
1910 **/
1911 if ((!ifp->desc) &&
1912 (ri->split_horizon == ri->split_horizon_default) &&
1913 (ri->ri_send == RI_RIP_UNSPEC) &&
1914 (ri->ri_receive == RI_RIP_UNSPEC) &&
1915 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001916 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001917 (!ri->auth_str) &&
1918 (!ri->key_chain) )
1919 continue;
1920
paul718e3742002-12-13 20:15:29 +00001921 vty_out (vty, "interface %s%s", ifp->name,
1922 VTY_NEWLINE);
1923
1924 if (ifp->desc)
1925 vty_out (vty, " description %s%s", ifp->desc,
1926 VTY_NEWLINE);
1927
1928 /* Split horizon. */
1929 if (ri->split_horizon != ri->split_horizon_default)
1930 {
hasso16705132003-05-25 14:49:19 +00001931 switch (ri->split_horizon) {
1932 case RIP_SPLIT_HORIZON:
1933 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1934 break;
1935 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1936 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1937 VTY_NEWLINE);
1938 break;
1939 case RIP_NO_SPLIT_HORIZON:
1940 default:
1941 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1942 break;
1943 }
paul718e3742002-12-13 20:15:29 +00001944 }
1945
1946 /* RIP version setting. */
1947 if (ri->ri_send != RI_RIP_UNSPEC)
1948 vty_out (vty, " ip rip send version %s%s",
1949 lookup (ri_version_msg, ri->ri_send),
1950 VTY_NEWLINE);
1951
1952 if (ri->ri_receive != RI_RIP_UNSPEC)
1953 vty_out (vty, " ip rip receive version %s%s",
1954 lookup (ri_version_msg, ri->ri_receive),
1955 VTY_NEWLINE);
1956
1957 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001958 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1959 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001960
paul718e3742002-12-13 20:15:29 +00001961 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001962 {
1963 vty_out (vty, " ip rip authentication mode md5");
1964 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1965 vty_out (vty, " auth-length old-ripd");
1966 else
1967 vty_out (vty, " auth-length rfc");
1968 vty_out (vty, "%s", VTY_NEWLINE);
1969 }
paul718e3742002-12-13 20:15:29 +00001970
1971 if (ri->auth_str)
1972 vty_out (vty, " ip rip authentication string %s%s",
1973 ri->auth_str, VTY_NEWLINE);
1974
1975 if (ri->key_chain)
1976 vty_out (vty, " ip rip authentication key-chain %s%s",
1977 ri->key_chain, VTY_NEWLINE);
1978
1979 vty_out (vty, "!%s", VTY_NEWLINE);
1980 }
1981 return 0;
1982}
1983
1984int
1985config_write_rip_network (struct vty *vty, int config_mode)
1986{
hasso8a676be2004-10-08 06:36:38 +00001987 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001988 char *ifname;
1989 struct route_node *node;
1990
1991 /* Network type RIP enable interface statement. */
1992 for (node = route_top (rip_enable_network); node; node = route_next (node))
1993 if (node->info)
1994 vty_out (vty, "%s%s/%d%s",
1995 config_mode ? " network " : " ",
1996 inet_ntoa (node->p.u.prefix4),
1997 node->p.prefixlen,
1998 VTY_NEWLINE);
1999
2000 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002001 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002002 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2003 vty_out (vty, "%s%s%s",
2004 config_mode ? " network " : " ",
2005 ifname,
2006 VTY_NEWLINE);
2007
2008 /* RIP neighbors listing. */
2009 for (node = route_top (rip->neighbor); node; node = route_next (node))
2010 if (node->info)
2011 vty_out (vty, "%s%s%s",
2012 config_mode ? " neighbor " : " ",
2013 inet_ntoa (node->p.u.prefix4),
2014 VTY_NEWLINE);
2015
2016 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002017 if (config_mode) {
2018 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002019 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002020 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002021 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2022 vty_out (vty, " %spassive-interface %s%s",
2023 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2024 }
paul718e3742002-12-13 20:15:29 +00002025
2026 return 0;
2027}
2028
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002029static struct cmd_node interface_node =
paul718e3742002-12-13 20:15:29 +00002030{
2031 INTERFACE_NODE,
2032 "%s(config-if)# ",
2033 1,
2034};
2035
2036/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002037static int
paul718e3742002-12-13 20:15:29 +00002038rip_interface_new_hook (struct interface *ifp)
2039{
2040 ifp->info = rip_interface_new ();
2041 return 0;
2042}
2043
2044/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002045static int
paul718e3742002-12-13 20:15:29 +00002046rip_interface_delete_hook (struct interface *ifp)
2047{
2048 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002049 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002050 return 0;
2051}
2052
2053/* Allocate and initialize interface vector. */
2054void
pauldc63bfd2005-10-25 23:31:05 +00002055rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002056{
2057 /* Default initial size of interface vector. */
2058 if_init();
2059 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2060 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2061
2062 /* RIP network init. */
2063 rip_enable_interface = vector_init (1);
2064 rip_enable_network = route_table_init ();
2065
2066 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002067 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002068
2069 /* Install interface node. */
2070 install_node (&interface_node, rip_interface_config_write);
2071
2072 /* Install commands. */
2073 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002074 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002075 install_default (INTERFACE_NODE);
2076 install_element (INTERFACE_NODE, &interface_desc_cmd);
2077 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2078 install_element (RIP_NODE, &rip_network_cmd);
2079 install_element (RIP_NODE, &no_rip_network_cmd);
2080 install_element (RIP_NODE, &rip_neighbor_cmd);
2081 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2082
2083 install_element (RIP_NODE, &rip_passive_interface_cmd);
2084 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2085
2086 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2087 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2088 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2089 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2090 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2091
2092 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2093 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2094 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2095 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2096 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2097
2098 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002099 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002100 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2101 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002102 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002103
2104 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2105 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2106 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2107
2108 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2109 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2110 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2111
hasso16705132003-05-25 14:49:19 +00002112 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2113 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2114 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2115 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002116}