blob: 7bdcf46a102b9b56e8bacbccc4be0d059500a408 [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,
Paul Jakma9099f9b2016-01-18 10:12:10 +000077 ifindex_t ifindex)
paul718e3742002-12-13 20:15:29 +000078{
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,
Paul Jakma9099f9b2016-01-18 10:12:10 +000098 ifindex_t ifindex)
paul718e3742002-12-13 20:15:29 +000099{
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
Feng Luc99f3482014-10-16 09:52:36 +0800383rip_interface_down (int command, struct zclient *zclient, zebra_size_t length,
384 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000385{
386 struct interface *ifp;
387 struct stream *s;
388
389 s = zclient->ibuf;
390
391 /* zebra_interface_state_read() updates interface structure in
392 iflist. */
Feng Luc99f3482014-10-16 09:52:36 +0800393 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000394
395 if (ifp == NULL)
396 return 0;
397
398 rip_if_down(ifp);
399
400 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger30d20592009-07-28 11:58:51 +0100401 zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down",
402 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
403 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000404
405 return 0;
406}
407
408/* Inteface link up message processing */
409int
Feng Luc99f3482014-10-16 09:52:36 +0800410rip_interface_up (int command, struct zclient *zclient, zebra_size_t length,
411 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000412{
413 struct interface *ifp;
414
415 /* zebra_interface_state_read () updates interface structure in
416 iflist. */
Feng Luc99f3482014-10-16 09:52:36 +0800417 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000418
419 if (ifp == NULL)
420 return 0;
421
422 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300423 zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up",
424 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
425 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000426
427 /* Check if this interface is RIP enabled or not.*/
428 rip_enable_apply (ifp);
429
430 /* Check for a passive interface */
431 rip_passive_interface_apply (ifp);
432
433 /* Apply distribute list to the all interface. */
434 rip_distribute_update_interface (ifp);
435
436 return 0;
437}
438
439/* Inteface addition message from zebra. */
440int
Feng Luc99f3482014-10-16 09:52:36 +0800441rip_interface_add (int command, struct zclient *zclient, zebra_size_t length,
442 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000443{
444 struct interface *ifp;
445
Feng Luc99f3482014-10-16 09:52:36 +0800446 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000447
448 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300449 zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d",
450 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
451 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000452
453 /* Check if this interface is RIP enabled or not.*/
454 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000455
456 /* Check for a passive interface */
457 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000458
459 /* Apply distribute list to the all interface. */
460 rip_distribute_update_interface (ifp);
461
462 /* rip_request_neighbor_all (); */
463
hasso16705132003-05-25 14:49:19 +0000464 /* Check interface routemap. */
465 rip_if_rmap_update_interface (ifp);
466
paul718e3742002-12-13 20:15:29 +0000467 return 0;
468}
469
470int
471rip_interface_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800472 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000473{
474 struct interface *ifp;
475 struct stream *s;
476
477
478 s = zclient->ibuf;
479 /* zebra_interface_state_read() updates interface structure in iflist */
Feng Luc99f3482014-10-16 09:52:36 +0800480 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000481
482 if (ifp == NULL)
483 return 0;
484
485 if (if_is_up (ifp)) {
486 rip_if_down(ifp);
487 }
488
Stephen Hemminger2c239702009-12-10 19:16:05 +0300489 zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
490 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
491 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000492
493 /* To support pseudo interface do not free interface structure. */
494 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000495 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000496
497 return 0;
498}
499
500void
pauldc63bfd2005-10-25 23:31:05 +0000501rip_interface_clean (void)
paul718e3742002-12-13 20:15:29 +0000502{
hasso52dc7ee2004-09-23 19:18:23 +0000503 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000504 struct interface *ifp;
505 struct rip_interface *ri;
506
paul1eb8ef22005-04-07 07:30:20 +0000507 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000508 {
paul718e3742002-12-13 20:15:29 +0000509 ri = ifp->info;
510
511 ri->enable_network = 0;
512 ri->enable_interface = 0;
513 ri->running = 0;
514
515 if (ri->t_wakeup)
516 {
517 thread_cancel (ri->t_wakeup);
518 ri->t_wakeup = NULL;
519 }
520 }
521}
522
523void
pauldc63bfd2005-10-25 23:31:05 +0000524rip_interface_reset (void)
paul718e3742002-12-13 20:15:29 +0000525{
hasso52dc7ee2004-09-23 19:18:23 +0000526 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000527 struct interface *ifp;
528 struct rip_interface *ri;
529
paul1eb8ef22005-04-07 07:30:20 +0000530 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +0000531 {
paul718e3742002-12-13 20:15:29 +0000532 ri = ifp->info;
533
534 ri->enable_network = 0;
535 ri->enable_interface = 0;
536 ri->running = 0;
537
538 ri->ri_send = RI_RIP_UNSPEC;
539 ri->ri_receive = RI_RIP_UNSPEC;
540
paul7755a8c2005-06-02 08:20:53 +0000541 ri->auth_type = RIP_NO_AUTH;
paul718e3742002-12-13 20:15:29 +0000542
543 if (ri->auth_str)
544 {
545 free (ri->auth_str);
546 ri->auth_str = NULL;
547 }
548 if (ri->key_chain)
549 {
550 free (ri->key_chain);
551 ri->key_chain = NULL;
552 }
553
hasso16705132003-05-25 14:49:19 +0000554 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
555 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000556
557 ri->list[RIP_FILTER_IN] = NULL;
558 ri->list[RIP_FILTER_OUT] = NULL;
559
560 ri->prefix[RIP_FILTER_IN] = NULL;
561 ri->prefix[RIP_FILTER_OUT] = NULL;
562
563 if (ri->t_wakeup)
564 {
565 thread_cancel (ri->t_wakeup);
566 ri->t_wakeup = NULL;
567 }
568
569 ri->recv_badpackets = 0;
570 ri->recv_badroutes = 0;
571 ri->sent_updates = 0;
572
573 ri->passive = 0;
574 }
575}
576
577int
578rip_if_down(struct interface *ifp)
579{
580 struct route_node *rp;
581 struct rip_info *rinfo;
582 struct rip_interface *ri = NULL;
Lu Fengb397cf42014-07-18 06:13:18 +0000583 struct list *list = NULL;
584 struct listnode *listnode = NULL, *nextnode = NULL;
paul718e3742002-12-13 20:15:29 +0000585 if (rip)
Lu Fengb397cf42014-07-18 06:13:18 +0000586 for (rp = route_top (rip->table); rp; rp = route_next (rp))
587 if ((list = rp->info) != NULL)
588 for (ALL_LIST_ELEMENTS (list, listnode, nextnode, rinfo))
589 if (rinfo->ifindex == ifp->ifindex)
590 rip_ecmp_delete (rinfo);
paul718e3742002-12-13 20:15:29 +0000591
paul718e3742002-12-13 20:15:29 +0000592 ri = ifp->info;
593
594 if (ri->running)
595 {
596 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000597 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000598
599 /* Leave from multicast group. */
600 rip_multicast_leave (ifp, rip->sock);
601
602 ri->running = 0;
603 }
604
605 return 0;
606}
607
608/* Needed for stop RIP process. */
609void
610rip_if_down_all ()
611{
612 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000613 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000614
paul1eb8ef22005-04-07 07:30:20 +0000615 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
616 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000617}
618
hasso16705132003-05-25 14:49:19 +0000619static void
pauldc63bfd2005-10-25 23:31:05 +0000620rip_apply_address_add (struct connected *ifc)
621{
hasso16705132003-05-25 14:49:19 +0000622 struct prefix_ipv4 address;
623 struct prefix *p;
624
625 if (!rip)
626 return;
627
628 if (! if_is_up(ifc->ifp))
629 return;
630
631 p = ifc->address;
632
633 memset (&address, 0, sizeof (address));
634 address.family = p->family;
635 address.prefix = p->u.prefix4;
636 address.prefixlen = p->prefixlen;
637 apply_mask_ipv4(&address);
638
639 /* Check if this interface is RIP enabled or not
640 or Check if this address's prefix is RIP enabled */
641 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
642 (rip_enable_network_lookup2(ifc) >= 0))
643 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000644 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000645
646}
647
paul718e3742002-12-13 20:15:29 +0000648int
649rip_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800650 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000651{
652 struct connected *ifc;
653 struct prefix *p;
654
paul0a589352004-05-08 11:48:26 +0000655 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
Feng Luc99f3482014-10-16 09:52:36 +0800656 zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000657
658 if (ifc == NULL)
659 return 0;
660
661 p = ifc->address;
662
663 if (p->family == AF_INET)
664 {
665 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000666 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000667 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000668
paul878ef2e2003-09-23 23:41:50 +0000669 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000670 /* Check if this prefix needs to be redistributed */
671 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000672
673#ifdef HAVE_SNMP
674 rip_ifaddr_add (ifc->ifp, ifc);
675#endif /* HAVE_SNMP */
676 }
677
678 return 0;
679}
680
hasso16705132003-05-25 14:49:19 +0000681static void
682rip_apply_address_del (struct connected *ifc) {
683 struct prefix_ipv4 address;
684 struct prefix *p;
685
686 if (!rip)
687 return;
688
689 if (! if_is_up(ifc->ifp))
690 return;
691
692 p = ifc->address;
693
694 memset (&address, 0, sizeof (address));
695 address.family = p->family;
696 address.prefix = p->u.prefix4;
697 address.prefixlen = p->prefixlen;
698 apply_mask_ipv4(&address);
699
700 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
701 &address, ifc->ifp->ifindex);
702}
703
paul718e3742002-12-13 20:15:29 +0000704int
705rip_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800706 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000707{
708 struct connected *ifc;
709 struct prefix *p;
710
paul0a589352004-05-08 11:48:26 +0000711 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
Feng Luc99f3482014-10-16 09:52:36 +0800712 zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000713
714 if (ifc)
715 {
716 p = ifc->address;
717 if (p->family == AF_INET)
718 {
719 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000720 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000721 inet_ntoa (p->u.prefix4), p->prefixlen);
722
723#ifdef HAVE_SNMP
724 rip_ifaddr_delete (ifc->ifp, ifc);
725#endif /* HAVE_SNMP */
726
hasso16705132003-05-25 14:49:19 +0000727 /* Chech wether this prefix needs to be removed */
728 rip_apply_address_del(ifc);
729
paul718e3742002-12-13 20:15:29 +0000730 }
731
732 connected_free (ifc);
733
734 }
735
736 return 0;
737}
David Lamparter6b0655a2014-06-04 06:53:35 +0200738
paul718e3742002-12-13 20:15:29 +0000739/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000740/* Check wether the interface has at least a connected prefix that
741 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000742static int
hasso16705132003-05-25 14:49:19 +0000743rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000744{
paul1eb8ef22005-04-07 07:30:20 +0000745 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000746 struct connected *connected;
747 struct prefix_ipv4 address;
748
paul1eb8ef22005-04-07 07:30:20 +0000749 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
750 {
751 struct prefix *p;
752 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000753
paul1eb8ef22005-04-07 07:30:20 +0000754 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000755
paul1eb8ef22005-04-07 07:30:20 +0000756 if (p->family == AF_INET)
757 {
758 address.family = AF_INET;
759 address.prefix = p->u.prefix4;
760 address.prefixlen = IPV4_MAX_BITLEN;
761
762 node = route_node_match (rip_enable_network,
763 (struct prefix *)&address);
764 if (node)
765 {
766 route_unlock_node (node);
767 return 1;
768 }
769 }
770 }
paul718e3742002-12-13 20:15:29 +0000771 return -1;
772}
773
hasso16705132003-05-25 14:49:19 +0000774/* Check wether connected is within the ripng_enable_network table. */
775int
776rip_enable_network_lookup2 (struct connected *connected)
777{
778 struct prefix_ipv4 address;
779 struct prefix *p;
780
781 p = connected->address;
782
783 if (p->family == AF_INET) {
784 struct route_node *node;
785
786 address.family = p->family;
787 address.prefix = p->u.prefix4;
788 address.prefixlen = IPV4_MAX_BITLEN;
789
790 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
791 node = route_node_match (rip_enable_network,
792 (struct prefix *)&address);
793
794 if (node) {
795 route_unlock_node (node);
796 return 1;
797 }
798 }
799
800 return -1;
801}
paul718e3742002-12-13 20:15:29 +0000802/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000803static int
paul718e3742002-12-13 20:15:29 +0000804rip_enable_network_add (struct prefix *p)
805{
806 struct route_node *node;
807
808 node = route_node_get (rip_enable_network, p);
809
810 if (node->info)
811 {
812 route_unlock_node (node);
813 return -1;
814 }
815 else
hasso8a676be2004-10-08 06:36:38 +0000816 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000817
hasso16705132003-05-25 14:49:19 +0000818 /* XXX: One should find a better solution than a generic one */
819 rip_enable_apply_all();
820
paul718e3742002-12-13 20:15:29 +0000821 return 1;
822}
823
824/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000825static int
paul718e3742002-12-13 20:15:29 +0000826rip_enable_network_delete (struct prefix *p)
827{
828 struct route_node *node;
829
830 node = route_node_lookup (rip_enable_network, p);
831 if (node)
832 {
833 node->info = NULL;
834
835 /* Unlock info lock. */
836 route_unlock_node (node);
837
838 /* Unlock lookup lock. */
839 route_unlock_node (node);
840
hasso16705132003-05-25 14:49:19 +0000841 /* XXX: One should find a better solution than a generic one */
842 rip_enable_apply_all ();
843
paul718e3742002-12-13 20:15:29 +0000844 return 1;
845 }
846 return -1;
847}
848
849/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000850static int
hasso98b718a2004-10-11 12:57:57 +0000851rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000852{
hasso8a676be2004-10-08 06:36:38 +0000853 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000854 char *str;
855
paul55468c82005-03-14 20:19:01 +0000856 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000857 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
858 if (strcmp (str, ifname) == 0)
859 return i;
860 return -1;
861}
862
863/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000864static int
hasso98b718a2004-10-11 12:57:57 +0000865rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000866{
867 int ret;
868
869 ret = rip_enable_if_lookup (ifname);
870 if (ret >= 0)
871 return -1;
872
873 vector_set (rip_enable_interface, strdup (ifname));
874
hasso16705132003-05-25 14:49:19 +0000875 rip_enable_apply_all(); /* TODOVJ */
876
paul718e3742002-12-13 20:15:29 +0000877 return 1;
878}
879
880/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000881static int
hasso98b718a2004-10-11 12:57:57 +0000882rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000883{
884 int index;
885 char *str;
886
887 index = rip_enable_if_lookup (ifname);
888 if (index < 0)
889 return -1;
890
891 str = vector_slot (rip_enable_interface, index);
892 free (str);
893 vector_unset (rip_enable_interface, index);
894
hasso16705132003-05-25 14:49:19 +0000895 rip_enable_apply_all(); /* TODOVJ */
896
paul718e3742002-12-13 20:15:29 +0000897 return 1;
898}
899
900/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000901static int
paul718e3742002-12-13 20:15:29 +0000902rip_interface_wakeup (struct thread *t)
903{
904 struct interface *ifp;
905 struct rip_interface *ri;
906
907 /* Get interface. */
908 ifp = THREAD_ARG (t);
909
910 ri = ifp->info;
911 ri->t_wakeup = NULL;
912
913 /* Join to multicast group. */
914 if (rip_multicast_join (ifp, rip->sock) < 0)
915 {
916 zlog_err ("multicast join failed, interface %s not running", ifp->name);
917 return 0;
918 }
919
920 /* Set running flag. */
921 ri->running = 1;
922
923 /* Send RIP request to the interface. */
924 rip_request_interface (ifp);
925
926 return 0;
927}
928
pauldc63bfd2005-10-25 23:31:05 +0000929static void
paul718e3742002-12-13 20:15:29 +0000930rip_connect_set (struct interface *ifp, int set)
931{
paul1eb8ef22005-04-07 07:30:20 +0000932 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000933 struct connected *connected;
934 struct prefix_ipv4 address;
935
paul1eb8ef22005-04-07 07:30:20 +0000936 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
937 {
938 struct prefix *p;
939 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000940
paul1eb8ef22005-04-07 07:30:20 +0000941 if (p->family != AF_INET)
942 continue;
paul718e3742002-12-13 20:15:29 +0000943
paul1eb8ef22005-04-07 07:30:20 +0000944 address.family = AF_INET;
945 address.prefix = p->u.prefix4;
946 address.prefixlen = p->prefixlen;
947 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000948
paul1eb8ef22005-04-07 07:30:20 +0000949 if (set) {
950 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
951 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
952 (rip_enable_network_lookup2(connected) >= 0))
953 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000954 &address, connected->ifp->ifindex,
955 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000956 } else
957 {
958 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
959 &address, connected->ifp->ifindex);
960 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
961 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000962 &address, connected->ifp->ifindex,
963 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000964 }
965 }
paul718e3742002-12-13 20:15:29 +0000966}
967
968/* Update interface status. */
969void
970rip_enable_apply (struct interface *ifp)
971{
972 int ret;
973 struct rip_interface *ri = NULL;
974
975 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +0000976 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000977 return;
978
979 ri = ifp->info;
980
981 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +0000982 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +0000983
984 /* If the interface is matched. */
985 if (ret > 0)
986 ri->enable_network = 1;
987 else
988 ri->enable_network = 0;
989
990 /* Check interface name configuration. */
991 ret = rip_enable_if_lookup (ifp->name);
992 if (ret >= 0)
993 ri->enable_interface = 1;
994 else
995 ri->enable_interface = 0;
996
997 /* any interface MUST have an IPv4 address */
998 if ( ! rip_if_ipv4_address_check (ifp) )
999 {
1000 ri->enable_network = 0;
1001 ri->enable_interface = 0;
1002 }
1003
1004 /* Update running status of the interface. */
1005 if (ri->enable_network || ri->enable_interface)
1006 {
paul718e3742002-12-13 20:15:29 +00001007 {
1008 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001009 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001010
1011 /* Add interface wake up thread. */
1012 if (! ri->t_wakeup)
1013 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1014 ifp, 1);
1015 rip_connect_set (ifp, 1);
1016 }
1017 }
1018 else
1019 {
1020 if (ri->running)
1021 {
hasso16705132003-05-25 14:49:19 +00001022 /* Might as well clean up the route table as well
1023 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1024 **/
paul718e3742002-12-13 20:15:29 +00001025 rip_if_down(ifp);
1026
paul718e3742002-12-13 20:15:29 +00001027 rip_connect_set (ifp, 0);
1028 }
1029 }
1030}
1031
1032/* Apply network configuration to all interface. */
1033void
1034rip_enable_apply_all ()
1035{
1036 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001037 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001038
1039 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001040 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1041 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001042}
1043
1044int
1045rip_neighbor_lookup (struct sockaddr_in *from)
1046{
1047 struct prefix_ipv4 p;
1048 struct route_node *node;
1049
1050 memset (&p, 0, sizeof (struct prefix_ipv4));
1051 p.family = AF_INET;
1052 p.prefix = from->sin_addr;
1053 p.prefixlen = IPV4_MAX_BITLEN;
1054
1055 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1056 if (node)
1057 {
1058 route_unlock_node (node);
1059 return 1;
1060 }
1061 return 0;
1062}
1063
1064/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001065static int
paul718e3742002-12-13 20:15:29 +00001066rip_neighbor_add (struct prefix_ipv4 *p)
1067{
1068 struct route_node *node;
1069
1070 node = route_node_get (rip->neighbor, (struct prefix *) p);
1071
1072 if (node->info)
1073 return -1;
1074
1075 node->info = rip->neighbor;
1076
1077 return 0;
1078}
1079
1080/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001081static int
paul718e3742002-12-13 20:15:29 +00001082rip_neighbor_delete (struct prefix_ipv4 *p)
1083{
1084 struct route_node *node;
1085
1086 /* Lock for look up. */
1087 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1088 if (! node)
1089 return -1;
1090
1091 node->info = NULL;
1092
1093 /* Unlock lookup lock. */
1094 route_unlock_node (node);
1095
1096 /* Unlock real neighbor information lock. */
1097 route_unlock_node (node);
1098
1099 return 0;
1100}
1101
1102/* Clear all network and neighbor configuration. */
1103void
1104rip_clean_network ()
1105{
hasso8a676be2004-10-08 06:36:38 +00001106 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001107 char *str;
1108 struct route_node *rn;
1109
1110 /* rip_enable_network. */
1111 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1112 if (rn->info)
1113 {
1114 rn->info = NULL;
1115 route_unlock_node (rn);
1116 }
1117
1118 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001119 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001120 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1121 {
1122 free (str);
1123 vector_slot (rip_enable_interface, i) = NULL;
1124 }
1125}
David Lamparter6b0655a2014-06-04 06:53:35 +02001126
paul718e3742002-12-13 20:15:29 +00001127/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001128static int
hasso98b718a2004-10-11 12:57:57 +00001129rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001130{
hasso8a676be2004-10-08 06:36:38 +00001131 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001132 char *str;
1133
paul55468c82005-03-14 20:19:01 +00001134 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001135 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001136 if (strcmp (str, ifname) == 0)
1137 return i;
1138 return -1;
1139}
1140
1141void
1142rip_passive_interface_apply (struct interface *ifp)
1143{
paul718e3742002-12-13 20:15:29 +00001144 struct rip_interface *ri;
1145
1146 ri = ifp->info;
1147
paul4aaff3f2003-06-07 01:04:45 +00001148 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1149 passive_default : !passive_default);
1150
1151 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001152 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001153}
1154
pauldc63bfd2005-10-25 23:31:05 +00001155static void
1156rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001157{
1158 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001159 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001160
paul1eb8ef22005-04-07 07:30:20 +00001161 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1162 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001163}
1164
1165/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001166static int
hasso98b718a2004-10-11 12:57:57 +00001167rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001168{
paul4aaff3f2003-06-07 01:04:45 +00001169 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001170 return CMD_WARNING;
1171
paul4aaff3f2003-06-07 01:04:45 +00001172 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001173
1174 rip_passive_interface_apply_all ();
1175
1176 return CMD_SUCCESS;
1177}
1178
pauldc63bfd2005-10-25 23:31:05 +00001179static int
hasso98b718a2004-10-11 12:57:57 +00001180rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001181{
1182 int i;
1183 char *str;
1184
paul4aaff3f2003-06-07 01:04:45 +00001185 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001186 if (i < 0)
1187 return CMD_WARNING;
1188
paul4aaff3f2003-06-07 01:04:45 +00001189 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001190 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001191 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001192
1193 rip_passive_interface_apply_all ();
1194
1195 return CMD_SUCCESS;
1196}
1197
1198/* Free all configured RIP passive-interface settings. */
1199void
pauldc63bfd2005-10-25 23:31:05 +00001200rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001201{
hasso8a676be2004-10-08 06:36:38 +00001202 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001203 char *str;
1204
paul55468c82005-03-14 20:19:01 +00001205 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001206 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001207 {
1208 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001209 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001210 }
1211 rip_passive_interface_apply_all ();
1212}
David Lamparter6b0655a2014-06-04 06:53:35 +02001213
paul718e3742002-12-13 20:15:29 +00001214/* RIP enable network or interface configuration. */
1215DEFUN (rip_network,
1216 rip_network_cmd,
1217 "network (A.B.C.D/M|WORD)",
1218 "Enable routing on an IP network\n"
1219 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1220 "Interface name\n")
1221{
1222 int ret;
1223 struct prefix_ipv4 p;
1224
1225 ret = str2prefix_ipv4 (argv[0], &p);
1226
1227 if (ret)
1228 ret = rip_enable_network_add ((struct prefix *) &p);
1229 else
1230 ret = rip_enable_if_add (argv[0]);
1231
1232 if (ret < 0)
1233 {
1234 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1235 VTY_NEWLINE);
1236 return CMD_WARNING;
1237 }
1238
paul718e3742002-12-13 20:15:29 +00001239 return CMD_SUCCESS;
1240}
1241
1242/* RIP enable network or interface configuration. */
1243DEFUN (no_rip_network,
1244 no_rip_network_cmd,
1245 "no network (A.B.C.D/M|WORD)",
1246 NO_STR
1247 "Enable routing on an IP network\n"
1248 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1249 "Interface name\n")
1250{
1251 int ret;
1252 struct prefix_ipv4 p;
1253
1254 ret = str2prefix_ipv4 (argv[0], &p);
1255
1256 if (ret)
1257 ret = rip_enable_network_delete ((struct prefix *) &p);
1258 else
1259 ret = rip_enable_if_delete (argv[0]);
1260
1261 if (ret < 0)
1262 {
1263 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1264 VTY_NEWLINE);
1265 return CMD_WARNING;
1266 }
1267
paul718e3742002-12-13 20:15:29 +00001268 return CMD_SUCCESS;
1269}
1270
1271/* RIP neighbor configuration set. */
1272DEFUN (rip_neighbor,
1273 rip_neighbor_cmd,
1274 "neighbor A.B.C.D",
1275 "Specify a neighbor router\n"
1276 "Neighbor address\n")
1277{
1278 int ret;
1279 struct prefix_ipv4 p;
1280
1281 ret = str2prefix_ipv4 (argv[0], &p);
1282
1283 if (ret <= 0)
1284 {
1285 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1286 return CMD_WARNING;
1287 }
1288
1289 rip_neighbor_add (&p);
1290
1291 return CMD_SUCCESS;
1292}
1293
1294/* RIP neighbor configuration unset. */
1295DEFUN (no_rip_neighbor,
1296 no_rip_neighbor_cmd,
1297 "no neighbor A.B.C.D",
1298 NO_STR
1299 "Specify a neighbor router\n"
1300 "Neighbor address\n")
1301{
1302 int ret;
1303 struct prefix_ipv4 p;
1304
1305 ret = str2prefix_ipv4 (argv[0], &p);
1306
1307 if (ret <= 0)
1308 {
1309 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1310 return CMD_WARNING;
1311 }
1312
1313 rip_neighbor_delete (&p);
1314
1315 return CMD_SUCCESS;
1316}
1317
1318DEFUN (ip_rip_receive_version,
1319 ip_rip_receive_version_cmd,
1320 "ip rip receive version (1|2)",
1321 IP_STR
1322 "Routing Information Protocol\n"
1323 "Advertisement reception\n"
1324 "Version control\n"
1325 "RIP version 1\n"
1326 "RIP version 2\n")
1327{
1328 struct interface *ifp;
1329 struct rip_interface *ri;
1330
1331 ifp = (struct interface *)vty->index;
1332 ri = ifp->info;
1333
1334 /* Version 1. */
1335 if (atoi (argv[0]) == 1)
1336 {
1337 ri->ri_receive = RI_RIP_VERSION_1;
1338 return CMD_SUCCESS;
1339 }
1340 if (atoi (argv[0]) == 2)
1341 {
1342 ri->ri_receive = RI_RIP_VERSION_2;
1343 return CMD_SUCCESS;
1344 }
1345 return CMD_WARNING;
1346}
1347
1348DEFUN (ip_rip_receive_version_1,
1349 ip_rip_receive_version_1_cmd,
1350 "ip rip receive version 1 2",
1351 IP_STR
1352 "Routing Information Protocol\n"
1353 "Advertisement reception\n"
1354 "Version control\n"
1355 "RIP version 1\n"
1356 "RIP version 2\n")
1357{
1358 struct interface *ifp;
1359 struct rip_interface *ri;
1360
1361 ifp = (struct interface *)vty->index;
1362 ri = ifp->info;
1363
1364 /* Version 1 and 2. */
1365 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1366 return CMD_SUCCESS;
1367}
1368
1369DEFUN (ip_rip_receive_version_2,
1370 ip_rip_receive_version_2_cmd,
1371 "ip rip receive version 2 1",
1372 IP_STR
1373 "Routing Information Protocol\n"
1374 "Advertisement reception\n"
1375 "Version control\n"
1376 "RIP version 2\n"
1377 "RIP version 1\n")
1378{
1379 struct interface *ifp;
1380 struct rip_interface *ri;
1381
1382 ifp = (struct interface *)vty->index;
1383 ri = ifp->info;
1384
1385 /* Version 1 and 2. */
1386 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1387 return CMD_SUCCESS;
1388}
1389
1390DEFUN (no_ip_rip_receive_version,
1391 no_ip_rip_receive_version_cmd,
1392 "no ip rip receive version",
1393 NO_STR
1394 IP_STR
1395 "Routing Information Protocol\n"
1396 "Advertisement reception\n"
1397 "Version control\n")
1398{
1399 struct interface *ifp;
1400 struct rip_interface *ri;
1401
1402 ifp = (struct interface *)vty->index;
1403 ri = ifp->info;
1404
1405 ri->ri_receive = RI_RIP_UNSPEC;
1406 return CMD_SUCCESS;
1407}
1408
1409ALIAS (no_ip_rip_receive_version,
1410 no_ip_rip_receive_version_num_cmd,
1411 "no ip rip receive version (1|2)",
1412 NO_STR
1413 IP_STR
1414 "Routing Information Protocol\n"
1415 "Advertisement reception\n"
1416 "Version control\n"
1417 "Version 1\n"
1418 "Version 2\n")
1419
1420DEFUN (ip_rip_send_version,
1421 ip_rip_send_version_cmd,
1422 "ip rip send version (1|2)",
1423 IP_STR
1424 "Routing Information Protocol\n"
1425 "Advertisement transmission\n"
1426 "Version control\n"
1427 "RIP version 1\n"
1428 "RIP version 2\n")
1429{
1430 struct interface *ifp;
1431 struct rip_interface *ri;
1432
1433 ifp = (struct interface *)vty->index;
1434 ri = ifp->info;
1435
1436 /* Version 1. */
1437 if (atoi (argv[0]) == 1)
1438 {
1439 ri->ri_send = RI_RIP_VERSION_1;
1440 return CMD_SUCCESS;
1441 }
1442 if (atoi (argv[0]) == 2)
1443 {
1444 ri->ri_send = RI_RIP_VERSION_2;
1445 return CMD_SUCCESS;
1446 }
1447 return CMD_WARNING;
1448}
1449
1450DEFUN (ip_rip_send_version_1,
1451 ip_rip_send_version_1_cmd,
1452 "ip rip send version 1 2",
1453 IP_STR
1454 "Routing Information Protocol\n"
1455 "Advertisement transmission\n"
1456 "Version control\n"
1457 "RIP version 1\n"
1458 "RIP version 2\n")
1459{
1460 struct interface *ifp;
1461 struct rip_interface *ri;
1462
1463 ifp = (struct interface *)vty->index;
1464 ri = ifp->info;
1465
1466 /* Version 1 and 2. */
1467 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1468 return CMD_SUCCESS;
1469}
1470
1471DEFUN (ip_rip_send_version_2,
1472 ip_rip_send_version_2_cmd,
1473 "ip rip send version 2 1",
1474 IP_STR
1475 "Routing Information Protocol\n"
1476 "Advertisement transmission\n"
1477 "Version control\n"
1478 "RIP version 2\n"
1479 "RIP version 1\n")
1480{
1481 struct interface *ifp;
1482 struct rip_interface *ri;
1483
1484 ifp = (struct interface *)vty->index;
1485 ri = ifp->info;
1486
1487 /* Version 1 and 2. */
1488 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1489 return CMD_SUCCESS;
1490}
1491
1492DEFUN (no_ip_rip_send_version,
1493 no_ip_rip_send_version_cmd,
1494 "no ip rip send version",
1495 NO_STR
1496 IP_STR
1497 "Routing Information Protocol\n"
1498 "Advertisement transmission\n"
1499 "Version control\n")
1500{
1501 struct interface *ifp;
1502 struct rip_interface *ri;
1503
1504 ifp = (struct interface *)vty->index;
1505 ri = ifp->info;
1506
1507 ri->ri_send = RI_RIP_UNSPEC;
1508 return CMD_SUCCESS;
1509}
1510
1511ALIAS (no_ip_rip_send_version,
1512 no_ip_rip_send_version_num_cmd,
1513 "no ip rip send version (1|2)",
1514 NO_STR
1515 IP_STR
1516 "Routing Information Protocol\n"
1517 "Advertisement transmission\n"
1518 "Version control\n"
1519 "Version 1\n"
1520 "Version 2\n")
1521
1522DEFUN (ip_rip_authentication_mode,
1523 ip_rip_authentication_mode_cmd,
1524 "ip rip authentication mode (md5|text)",
1525 IP_STR
1526 "Routing Information Protocol\n"
1527 "Authentication control\n"
1528 "Authentication mode\n"
1529 "Keyed message digest\n"
1530 "Clear text authentication\n")
1531{
1532 struct interface *ifp;
1533 struct rip_interface *ri;
Paul Jakma15a2b082006-05-04 07:36:34 +00001534 int auth_type;
paul718e3742002-12-13 20:15:29 +00001535
1536 ifp = (struct interface *)vty->index;
1537 ri = ifp->info;
1538
paulca5e5162004-06-06 22:06:33 +00001539 if ( (argc < 1) || (argc > 2) )
1540 {
1541 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1542 return CMD_WARNING;
1543 }
1544
paul718e3742002-12-13 20:15:29 +00001545 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001546 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001547 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001548 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001549 else
1550 {
1551 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1552 return CMD_WARNING;
1553 }
1554
paulca5e5162004-06-06 22:06:33 +00001555 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001556 {
1557 ri->auth_type = auth_type;
1558 return CMD_SUCCESS;
1559 }
paulca5e5162004-06-06 22:06:33 +00001560
Paul Jakma15a2b082006-05-04 07:36:34 +00001561 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001562 {
1563 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1564 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001565 }
paulca5e5162004-06-06 22:06:33 +00001566
1567 if (strncmp ("r", argv[1], 1) == 0)
1568 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1569 else if (strncmp ("o", argv[1], 1) == 0)
1570 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1571 else
1572 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001573
1574 ri->auth_type = auth_type;
1575
paul718e3742002-12-13 20:15:29 +00001576 return CMD_SUCCESS;
1577}
1578
paulca5e5162004-06-06 22:06:33 +00001579ALIAS (ip_rip_authentication_mode,
1580 ip_rip_authentication_mode_authlen_cmd,
1581 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1582 IP_STR
1583 "Routing Information Protocol\n"
1584 "Authentication control\n"
1585 "Authentication mode\n"
1586 "Keyed message digest\n"
1587 "Clear text authentication\n"
1588 "MD5 authentication data length\n"
1589 "RFC compatible\n"
1590 "Old ripd compatible\n")
1591
paul718e3742002-12-13 20:15:29 +00001592DEFUN (no_ip_rip_authentication_mode,
1593 no_ip_rip_authentication_mode_cmd,
1594 "no ip rip authentication mode",
1595 NO_STR
1596 IP_STR
1597 "Routing Information Protocol\n"
1598 "Authentication control\n"
1599 "Authentication mode\n")
1600{
1601 struct interface *ifp;
1602 struct rip_interface *ri;
1603
1604 ifp = (struct interface *)vty->index;
1605 ri = ifp->info;
1606
paul7755a8c2005-06-02 08:20:53 +00001607 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001608 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001609
1610 return CMD_SUCCESS;
1611}
1612
1613ALIAS (no_ip_rip_authentication_mode,
1614 no_ip_rip_authentication_mode_type_cmd,
1615 "no ip rip authentication mode (md5|text)",
1616 NO_STR
1617 IP_STR
1618 "Routing Information Protocol\n"
1619 "Authentication control\n"
1620 "Authentication mode\n"
1621 "Keyed message digest\n"
1622 "Clear text authentication\n")
1623
paulca5e5162004-06-06 22:06:33 +00001624ALIAS (no_ip_rip_authentication_mode,
1625 no_ip_rip_authentication_mode_type_authlen_cmd,
1626 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1627 NO_STR
1628 IP_STR
1629 "Routing Information Protocol\n"
1630 "Authentication control\n"
1631 "Authentication mode\n"
1632 "Keyed message digest\n"
1633 "Clear text authentication\n"
1634 "MD5 authentication data length\n"
1635 "RFC compatible\n"
1636 "Old ripd compatible\n")
1637
paul718e3742002-12-13 20:15:29 +00001638DEFUN (ip_rip_authentication_string,
1639 ip_rip_authentication_string_cmd,
1640 "ip rip authentication string LINE",
1641 IP_STR
1642 "Routing Information Protocol\n"
1643 "Authentication control\n"
1644 "Authentication string\n"
1645 "Authentication string\n")
1646{
1647 struct interface *ifp;
1648 struct rip_interface *ri;
1649
1650 ifp = (struct interface *)vty->index;
1651 ri = ifp->info;
1652
1653 if (strlen (argv[0]) > 16)
1654 {
1655 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1656 VTY_NEWLINE);
1657 return CMD_WARNING;
1658 }
1659
1660 if (ri->key_chain)
1661 {
1662 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1663 return CMD_WARNING;
1664 }
1665
1666 if (ri->auth_str)
1667 free (ri->auth_str);
1668
1669 ri->auth_str = strdup (argv[0]);
1670
1671 return CMD_SUCCESS;
1672}
1673
1674DEFUN (no_ip_rip_authentication_string,
1675 no_ip_rip_authentication_string_cmd,
1676 "no ip rip authentication string",
1677 NO_STR
1678 IP_STR
1679 "Routing Information Protocol\n"
1680 "Authentication control\n"
1681 "Authentication string\n")
1682{
1683 struct interface *ifp;
1684 struct rip_interface *ri;
1685
1686 ifp = (struct interface *)vty->index;
1687 ri = ifp->info;
1688
1689 if (ri->auth_str)
1690 free (ri->auth_str);
1691
1692 ri->auth_str = NULL;
1693
1694 return CMD_SUCCESS;
1695}
1696
1697ALIAS (no_ip_rip_authentication_string,
1698 no_ip_rip_authentication_string2_cmd,
1699 "no ip rip authentication string LINE",
1700 NO_STR
1701 IP_STR
1702 "Routing Information Protocol\n"
1703 "Authentication control\n"
1704 "Authentication string\n"
1705 "Authentication string\n")
1706
1707DEFUN (ip_rip_authentication_key_chain,
1708 ip_rip_authentication_key_chain_cmd,
1709 "ip rip authentication key-chain LINE",
1710 IP_STR
1711 "Routing Information Protocol\n"
1712 "Authentication control\n"
1713 "Authentication key-chain\n"
1714 "name of key-chain\n")
1715{
1716 struct interface *ifp;
1717 struct rip_interface *ri;
1718
1719 ifp = (struct interface *) vty->index;
1720 ri = ifp->info;
1721
1722 if (ri->auth_str)
1723 {
1724 vty_out (vty, "%% authentication string configuration exists%s",
1725 VTY_NEWLINE);
1726 return CMD_WARNING;
1727 }
1728
1729 if (ri->key_chain)
1730 free (ri->key_chain);
1731
1732 ri->key_chain = strdup (argv[0]);
1733
1734 return CMD_SUCCESS;
1735}
1736
1737DEFUN (no_ip_rip_authentication_key_chain,
1738 no_ip_rip_authentication_key_chain_cmd,
1739 "no ip rip authentication key-chain",
1740 NO_STR
1741 IP_STR
1742 "Routing Information Protocol\n"
1743 "Authentication control\n"
1744 "Authentication key-chain\n")
1745{
1746 struct interface *ifp;
1747 struct rip_interface *ri;
1748
1749 ifp = (struct interface *) vty->index;
1750 ri = ifp->info;
1751
1752 if (ri->key_chain)
1753 free (ri->key_chain);
1754
1755 ri->key_chain = NULL;
1756
1757 return CMD_SUCCESS;
1758}
1759
1760ALIAS (no_ip_rip_authentication_key_chain,
1761 no_ip_rip_authentication_key_chain2_cmd,
1762 "no ip rip authentication key-chain LINE",
1763 NO_STR
1764 IP_STR
1765 "Routing Information Protocol\n"
1766 "Authentication control\n"
1767 "Authentication key-chain\n"
1768 "name of key-chain\n")
1769
hasso16705132003-05-25 14:49:19 +00001770/* CHANGED: ip rip split-horizon
1771 Cisco and Zebra's command is
1772 ip split-horizon
1773 */
1774DEFUN (ip_rip_split_horizon,
1775 ip_rip_split_horizon_cmd,
1776 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001777 IP_STR
hasso16705132003-05-25 14:49:19 +00001778 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001779 "Perform split horizon\n")
1780{
1781 struct interface *ifp;
1782 struct rip_interface *ri;
1783
1784 ifp = vty->index;
1785 ri = ifp->info;
1786
hasso16705132003-05-25 14:49:19 +00001787 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001788 return CMD_SUCCESS;
1789}
1790
hasso16705132003-05-25 14:49:19 +00001791DEFUN (ip_rip_split_horizon_poisoned_reverse,
1792 ip_rip_split_horizon_poisoned_reverse_cmd,
1793 "ip rip split-horizon poisoned-reverse",
1794 IP_STR
1795 "Routing Information Protocol\n"
1796 "Perform split horizon\n"
1797 "With poisoned-reverse\n")
1798{
1799 struct interface *ifp;
1800 struct rip_interface *ri;
1801
1802 ifp = vty->index;
1803 ri = ifp->info;
1804
1805 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1806 return CMD_SUCCESS;
1807}
1808
1809/* CHANGED: no ip rip split-horizon
1810 Cisco and Zebra's command is
1811 no ip split-horizon
1812 */
1813DEFUN (no_ip_rip_split_horizon,
1814 no_ip_rip_split_horizon_cmd,
1815 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001816 NO_STR
1817 IP_STR
hasso16705132003-05-25 14:49:19 +00001818 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001819 "Perform split horizon\n")
1820{
1821 struct interface *ifp;
1822 struct rip_interface *ri;
1823
1824 ifp = vty->index;
1825 ri = ifp->info;
1826
hasso16705132003-05-25 14:49:19 +00001827 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001828 return CMD_SUCCESS;
1829}
1830
vincentfac3e842005-10-06 07:45:43 +00001831DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001832 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1833 "no ip rip split-horizon poisoned-reverse",
1834 NO_STR
1835 IP_STR
1836 "Routing Information Protocol\n"
1837 "Perform split horizon\n"
1838 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001839{
1840 struct interface *ifp;
1841 struct rip_interface *ri;
1842
1843 ifp = vty->index;
1844 ri = ifp->info;
1845
1846 switch( ri->split_horizon )
1847 {
1848 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1849 ri->split_horizon = RIP_SPLIT_HORIZON;
1850 default:
1851 break;
1852 }
1853
1854 return CMD_SUCCESS;
1855}
hasso16705132003-05-25 14:49:19 +00001856
paul718e3742002-12-13 20:15:29 +00001857DEFUN (rip_passive_interface,
1858 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001859 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001860 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001861 "Interface name\n"
1862 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001863{
hasso98b718a2004-10-11 12:57:57 +00001864 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001865
1866 if (!strcmp(ifname,"default")) {
1867 passive_default = 1;
1868 rip_passive_nondefault_clean();
1869 return CMD_SUCCESS;
1870 }
1871 if (passive_default)
1872 return rip_passive_nondefault_unset (vty, ifname);
1873 else
1874 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001875}
1876
1877DEFUN (no_rip_passive_interface,
1878 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001879 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001880 NO_STR
1881 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001882 "Interface name\n"
1883 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001884{
hasso98b718a2004-10-11 12:57:57 +00001885 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001886
1887 if (!strcmp(ifname,"default")) {
1888 passive_default = 0;
1889 rip_passive_nondefault_clean();
1890 return CMD_SUCCESS;
1891 }
1892 if (passive_default)
1893 return rip_passive_nondefault_set (vty, ifname);
1894 else
1895 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001896}
David Lamparter6b0655a2014-06-04 06:53:35 +02001897
paul718e3742002-12-13 20:15:29 +00001898/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001899static int
paul718e3742002-12-13 20:15:29 +00001900rip_interface_config_write (struct vty *vty)
1901{
hasso52dc7ee2004-09-23 19:18:23 +00001902 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001903 struct interface *ifp;
1904
paul1eb8ef22005-04-07 07:30:20 +00001905 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001906 {
1907 struct rip_interface *ri;
1908
paul718e3742002-12-13 20:15:29 +00001909 ri = ifp->info;
1910
hasso16705132003-05-25 14:49:19 +00001911 /* Do not display the interface if there is no
1912 * configuration about it.
1913 **/
1914 if ((!ifp->desc) &&
1915 (ri->split_horizon == ri->split_horizon_default) &&
1916 (ri->ri_send == RI_RIP_UNSPEC) &&
1917 (ri->ri_receive == RI_RIP_UNSPEC) &&
1918 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001919 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001920 (!ri->auth_str) &&
1921 (!ri->key_chain) )
1922 continue;
1923
paul718e3742002-12-13 20:15:29 +00001924 vty_out (vty, "interface %s%s", ifp->name,
1925 VTY_NEWLINE);
1926
1927 if (ifp->desc)
1928 vty_out (vty, " description %s%s", ifp->desc,
1929 VTY_NEWLINE);
1930
1931 /* Split horizon. */
1932 if (ri->split_horizon != ri->split_horizon_default)
1933 {
hasso16705132003-05-25 14:49:19 +00001934 switch (ri->split_horizon) {
1935 case RIP_SPLIT_HORIZON:
1936 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1937 break;
1938 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1939 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1940 VTY_NEWLINE);
1941 break;
1942 case RIP_NO_SPLIT_HORIZON:
1943 default:
1944 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1945 break;
1946 }
paul718e3742002-12-13 20:15:29 +00001947 }
1948
1949 /* RIP version setting. */
1950 if (ri->ri_send != RI_RIP_UNSPEC)
1951 vty_out (vty, " ip rip send version %s%s",
1952 lookup (ri_version_msg, ri->ri_send),
1953 VTY_NEWLINE);
1954
1955 if (ri->ri_receive != RI_RIP_UNSPEC)
1956 vty_out (vty, " ip rip receive version %s%s",
1957 lookup (ri_version_msg, ri->ri_receive),
1958 VTY_NEWLINE);
1959
1960 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001961 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1962 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001963
paul718e3742002-12-13 20:15:29 +00001964 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001965 {
1966 vty_out (vty, " ip rip authentication mode md5");
1967 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1968 vty_out (vty, " auth-length old-ripd");
1969 else
1970 vty_out (vty, " auth-length rfc");
1971 vty_out (vty, "%s", VTY_NEWLINE);
1972 }
paul718e3742002-12-13 20:15:29 +00001973
1974 if (ri->auth_str)
1975 vty_out (vty, " ip rip authentication string %s%s",
1976 ri->auth_str, VTY_NEWLINE);
1977
1978 if (ri->key_chain)
1979 vty_out (vty, " ip rip authentication key-chain %s%s",
1980 ri->key_chain, VTY_NEWLINE);
1981
1982 vty_out (vty, "!%s", VTY_NEWLINE);
1983 }
1984 return 0;
1985}
1986
1987int
1988config_write_rip_network (struct vty *vty, int config_mode)
1989{
hasso8a676be2004-10-08 06:36:38 +00001990 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001991 char *ifname;
1992 struct route_node *node;
1993
1994 /* Network type RIP enable interface statement. */
1995 for (node = route_top (rip_enable_network); node; node = route_next (node))
1996 if (node->info)
1997 vty_out (vty, "%s%s/%d%s",
1998 config_mode ? " network " : " ",
1999 inet_ntoa (node->p.u.prefix4),
2000 node->p.prefixlen,
2001 VTY_NEWLINE);
2002
2003 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00002004 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00002005 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2006 vty_out (vty, "%s%s%s",
2007 config_mode ? " network " : " ",
2008 ifname,
2009 VTY_NEWLINE);
2010
2011 /* RIP neighbors listing. */
2012 for (node = route_top (rip->neighbor); node; node = route_next (node))
2013 if (node->info)
2014 vty_out (vty, "%s%s%s",
2015 config_mode ? " neighbor " : " ",
2016 inet_ntoa (node->p.u.prefix4),
2017 VTY_NEWLINE);
2018
2019 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002020 if (config_mode) {
2021 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002022 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002023 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002024 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2025 vty_out (vty, " %spassive-interface %s%s",
2026 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2027 }
paul718e3742002-12-13 20:15:29 +00002028
2029 return 0;
2030}
2031
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002032static struct cmd_node interface_node =
paul718e3742002-12-13 20:15:29 +00002033{
2034 INTERFACE_NODE,
2035 "%s(config-if)# ",
2036 1,
2037};
2038
2039/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002040static int
paul718e3742002-12-13 20:15:29 +00002041rip_interface_new_hook (struct interface *ifp)
2042{
2043 ifp->info = rip_interface_new ();
2044 return 0;
2045}
2046
2047/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002048static int
paul718e3742002-12-13 20:15:29 +00002049rip_interface_delete_hook (struct interface *ifp)
2050{
2051 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002052 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002053 return 0;
2054}
2055
2056/* Allocate and initialize interface vector. */
2057void
pauldc63bfd2005-10-25 23:31:05 +00002058rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002059{
2060 /* Default initial size of interface vector. */
paul718e3742002-12-13 20:15:29 +00002061 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2062 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2063
2064 /* RIP network init. */
2065 rip_enable_interface = vector_init (1);
2066 rip_enable_network = route_table_init ();
2067
2068 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002069 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002070
2071 /* Install interface node. */
2072 install_node (&interface_node, rip_interface_config_write);
2073
2074 /* Install commands. */
2075 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002076 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002077 install_default (INTERFACE_NODE);
2078 install_element (INTERFACE_NODE, &interface_desc_cmd);
2079 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2080 install_element (RIP_NODE, &rip_network_cmd);
2081 install_element (RIP_NODE, &no_rip_network_cmd);
2082 install_element (RIP_NODE, &rip_neighbor_cmd);
2083 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2084
2085 install_element (RIP_NODE, &rip_passive_interface_cmd);
2086 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2087
2088 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2089 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2090 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2091 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2092 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2093
2094 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2095 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2096 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2097 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2098 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2099
2100 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002101 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002102 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2103 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002104 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002105
2106 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2107 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2108 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2109
2110 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2111 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2112 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2113
hasso16705132003-05-25 14:49:19 +00002114 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2115 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2116 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2117 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002118}