blob: 240c9688b4cd17fe333132d95aa73b650cc7c855 [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
Paul Jakmad319a3a2016-05-25 14:47:00 +0100113static void rip_interface_reset (struct rip_interface *);
114
paul718e3742002-12-13 20:15:29 +0000115/* Allocate new RIP's interface configuration. */
pauldc63bfd2005-10-25 23:31:05 +0000116static struct rip_interface *
117rip_interface_new (void)
paul718e3742002-12-13 20:15:29 +0000118{
119 struct rip_interface *ri;
120
Stephen Hemminger393deb92008-08-18 14:13:29 -0700121 ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
Paul Jakmad319a3a2016-05-25 14:47:00 +0100122
123 rip_interface_reset (ri);
124
paul718e3742002-12-13 20:15:29 +0000125 return ri;
126}
127
128void
paul1a517862004-08-19 04:03:08 +0000129rip_interface_multicast_set (int sock, struct connected *connected)
paul718e3742002-12-13 20:15:29 +0000130{
paulc49ad8f2004-10-22 10:27:28 +0000131 assert (connected != NULL);
132
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +0400133 if (setsockopt_ipv4_multicast_if (sock, connected->ifp->ifindex) < 0)
hasso3fb9cd62004-10-19 19:44:43 +0000134 {
135 zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
Dmitrij Tejblum69bf3a32011-08-18 20:22:17 +0400136 "ifindex %d for interface %s",
137 sock, connected->ifp->ifindex,
paulc49ad8f2004-10-22 10:27:28 +0000138 connected->ifp->name);
hasso3fb9cd62004-10-19 19:44:43 +0000139 }
paul2c61ae32005-08-16 15:22:14 +0000140
hasso3fb9cd62004-10-19 19:44:43 +0000141 return;
142}
paul718e3742002-12-13 20:15:29 +0000143
144/* Send RIP request packet to specified interface. */
pauldc63bfd2005-10-25 23:31:05 +0000145static void
paul718e3742002-12-13 20:15:29 +0000146rip_request_interface_send (struct interface *ifp, u_char version)
147{
148 struct sockaddr_in to;
149
150 /* RIPv2 support multicast. */
151 if (version == RIPv2 && if_is_multicast (ifp))
152 {
153
154 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000155 zlog_debug ("multicast request on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000156
paul931cd542004-01-23 15:31:42 +0000157 rip_request_send (NULL, ifp, version, NULL);
paul718e3742002-12-13 20:15:29 +0000158 return;
159 }
160
161 /* RIPv1 and non multicast interface. */
162 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
163 {
paul1eb8ef22005-04-07 07:30:20 +0000164 struct listnode *cnode, *cnnode;
165 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000166
167 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000168 zlog_debug ("broadcast request to %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000169
paul1eb8ef22005-04-07 07:30:20 +0000170 for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected))
paul718e3742002-12-13 20:15:29 +0000171 {
hasso3fb9cd62004-10-19 19:44:43 +0000172 if (connected->address->family == AF_INET)
paul718e3742002-12-13 20:15:29 +0000173 {
174 memset (&to, 0, sizeof (struct sockaddr_in));
175 to.sin_port = htons (RIP_PORT_DEFAULT);
hasso3fb9cd62004-10-19 19:44:43 +0000176 if (connected->destination)
Andrew J. Schorre4529632006-12-12 19:18:21 +0000177 /* use specified broadcast or peer destination addr */
hasso3fb9cd62004-10-19 19:44:43 +0000178 to.sin_addr = connected->destination->u.prefix4;
Andrew J. Schorre4529632006-12-12 19:18:21 +0000179 else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN)
hasso3fb9cd62004-10-19 19:44:43 +0000180 /* calculate the appropriate broadcast address */
181 to.sin_addr.s_addr =
182 ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
183 connected->address->prefixlen);
Andrew J. Schorre4529632006-12-12 19:18:21 +0000184 else
185 /* do not know where to send the packet */
186 continue;
paul718e3742002-12-13 20:15:29 +0000187
paul718e3742002-12-13 20:15:29 +0000188 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000189 zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000190
paul931cd542004-01-23 15:31:42 +0000191 rip_request_send (&to, ifp, version, connected);
paul718e3742002-12-13 20:15:29 +0000192 }
193 }
194 }
195}
196
197/* This will be executed when interface goes up. */
pauldc63bfd2005-10-25 23:31:05 +0000198static void
paul718e3742002-12-13 20:15:29 +0000199rip_request_interface (struct interface *ifp)
200{
201 struct rip_interface *ri;
202
203 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
204 if (if_is_loopback (ifp))
205 return;
206
207 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000208 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000209 return;
210
211 /* Fetch RIP interface information. */
212 ri = ifp->info;
213
214
215 /* If there is no version configuration in the interface,
216 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000217 {
218 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
219 rip->version_send : ri->ri_send);
220 if (vsend & RIPv1)
221 rip_request_interface_send (ifp, RIPv1);
222 if (vsend & RIPv2)
223 rip_request_interface_send (ifp, RIPv2);
224 }
paul718e3742002-12-13 20:15:29 +0000225}
226
Stephen Hemminger2c239702009-12-10 19:16:05 +0300227#if 0
paul718e3742002-12-13 20:15:29 +0000228/* Send RIP request to the neighbor. */
pauldc63bfd2005-10-25 23:31:05 +0000229static void
paul718e3742002-12-13 20:15:29 +0000230rip_request_neighbor (struct in_addr addr)
231{
232 struct sockaddr_in to;
233
234 memset (&to, 0, sizeof (struct sockaddr_in));
235 to.sin_port = htons (RIP_PORT_DEFAULT);
236 to.sin_addr = addr;
237
paul931cd542004-01-23 15:31:42 +0000238 rip_request_send (&to, NULL, rip->version_send, NULL);
paul718e3742002-12-13 20:15:29 +0000239}
240
241/* Request routes at all interfaces. */
pauldc63bfd2005-10-25 23:31:05 +0000242static void
243rip_request_neighbor_all (void)
paul718e3742002-12-13 20:15:29 +0000244{
245 struct route_node *rp;
246
247 if (! rip)
248 return;
249
250 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000251 zlog_debug ("request to the all neighbor");
paul718e3742002-12-13 20:15:29 +0000252
253 /* Send request to all neighbor. */
254 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
255 if (rp->info)
256 rip_request_neighbor (rp->p.u.prefix4);
257}
Stephen Hemminger2c239702009-12-10 19:16:05 +0300258#endif
paul718e3742002-12-13 20:15:29 +0000259
260/* Multicast packet receive socket. */
pauldc63bfd2005-10-25 23:31:05 +0000261static int
paul718e3742002-12-13 20:15:29 +0000262rip_multicast_join (struct interface *ifp, int sock)
263{
hasso52dc7ee2004-09-23 19:18:23 +0000264 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000265 struct connected *ifc;
paul718e3742002-12-13 20:15:29 +0000266
paul2e3b2e42002-12-13 21:03:13 +0000267 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000268 {
269 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000270 zlog_debug ("multicast join at %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000271
paul1eb8ef22005-04-07 07:30:20 +0000272 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc))
paul718e3742002-12-13 20:15:29 +0000273 {
274 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000275 struct in_addr group;
276
paul1eb8ef22005-04-07 07:30:20 +0000277 p = (struct prefix_ipv4 *) ifc->address;
paul718e3742002-12-13 20:15:29 +0000278
279 if (p->family != AF_INET)
280 continue;
281
282 group.s_addr = htonl (INADDR_RIP_GROUP);
283 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
284 return -1;
285 else
286 return 0;
287 }
288 }
289 return 0;
290}
291
292/* Leave from multicast group. */
pauldc63bfd2005-10-25 23:31:05 +0000293static void
paul718e3742002-12-13 20:15:29 +0000294rip_multicast_leave (struct interface *ifp, int sock)
295{
hasso52dc7ee2004-09-23 19:18:23 +0000296 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000297 struct connected *connected;
paul718e3742002-12-13 20:15:29 +0000298
299 if (if_is_up (ifp) && if_is_multicast (ifp))
300 {
301 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000302 zlog_debug ("multicast leave from %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000303
paul1eb8ef22005-04-07 07:30:20 +0000304 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul718e3742002-12-13 20:15:29 +0000305 {
306 struct prefix_ipv4 *p;
paul718e3742002-12-13 20:15:29 +0000307 struct in_addr group;
paul1eb8ef22005-04-07 07:30:20 +0000308
paul718e3742002-12-13 20:15:29 +0000309 p = (struct prefix_ipv4 *) connected->address;
paul1eb8ef22005-04-07 07:30:20 +0000310
paul718e3742002-12-13 20:15:29 +0000311 if (p->family != AF_INET)
312 continue;
313
314 group.s_addr = htonl (INADDR_RIP_GROUP);
315 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
316 return;
317 }
318 }
319}
320
321/* Is there and address on interface that I could use ? */
pauldc63bfd2005-10-25 23:31:05 +0000322static int
paul718e3742002-12-13 20:15:29 +0000323rip_if_ipv4_address_check (struct interface *ifp)
324{
325 struct listnode *nn;
326 struct connected *connected;
327 int count = 0;
328
paul1eb8ef22005-04-07 07:30:20 +0000329 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected))
330 {
331 struct prefix *p;
paul718e3742002-12-13 20:15:29 +0000332
paul1eb8ef22005-04-07 07:30:20 +0000333 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000334
paul1eb8ef22005-04-07 07:30:20 +0000335 if (p->family == AF_INET)
336 count++;
337 }
paul718e3742002-12-13 20:15:29 +0000338
339 return count;
340}
paul31a476c2003-09-29 19:54:53 +0000341
342
343
344
345/* Does this address belongs to me ? */
346int
347if_check_address (struct in_addr addr)
348{
hasso52dc7ee2004-09-23 19:18:23 +0000349 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000350 struct interface *ifp;
351
352 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul31a476c2003-09-29 19:54:53 +0000353 {
hasso52dc7ee2004-09-23 19:18:23 +0000354 struct listnode *cnode;
paul1eb8ef22005-04-07 07:30:20 +0000355 struct connected *connected;
paul31a476c2003-09-29 19:54:53 +0000356
paul1eb8ef22005-04-07 07:30:20 +0000357 for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
paul31a476c2003-09-29 19:54:53 +0000358 {
paul31a476c2003-09-29 19:54:53 +0000359 struct prefix_ipv4 *p;
360
paul31a476c2003-09-29 19:54:53 +0000361 p = (struct prefix_ipv4 *) connected->address;
362
363 if (p->family != AF_INET)
364 continue;
365
366 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
367 return 1;
368 }
369 }
370 return 0;
371}
372
paul718e3742002-12-13 20:15:29 +0000373/* Inteface link down message processing. */
374int
Feng Luc99f3482014-10-16 09:52:36 +0800375rip_interface_down (int command, struct zclient *zclient, zebra_size_t length,
376 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000377{
378 struct interface *ifp;
379 struct stream *s;
380
381 s = zclient->ibuf;
382
383 /* zebra_interface_state_read() updates interface structure in
384 iflist. */
Feng Luc99f3482014-10-16 09:52:36 +0800385 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000386
387 if (ifp == NULL)
388 return 0;
389
390 rip_if_down(ifp);
391
392 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger30d20592009-07-28 11:58:51 +0100393 zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down",
394 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
395 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000396
397 return 0;
398}
399
400/* Inteface link up message processing */
401int
Feng Luc99f3482014-10-16 09:52:36 +0800402rip_interface_up (int command, struct zclient *zclient, zebra_size_t length,
403 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000404{
405 struct interface *ifp;
406
407 /* zebra_interface_state_read () updates interface structure in
408 iflist. */
Feng Luc99f3482014-10-16 09:52:36 +0800409 ifp = zebra_interface_state_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000410
411 if (ifp == NULL)
412 return 0;
413
414 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300415 zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up",
416 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
417 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000418
419 /* Check if this interface is RIP enabled or not.*/
420 rip_enable_apply (ifp);
421
422 /* Check for a passive interface */
423 rip_passive_interface_apply (ifp);
424
425 /* Apply distribute list to the all interface. */
426 rip_distribute_update_interface (ifp);
427
428 return 0;
429}
430
431/* Inteface addition message from zebra. */
432int
Feng Luc99f3482014-10-16 09:52:36 +0800433rip_interface_add (int command, struct zclient *zclient, zebra_size_t length,
434 vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000435{
436 struct interface *ifp;
437
Feng Luc99f3482014-10-16 09:52:36 +0800438 ifp = zebra_interface_add_read (zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000439
440 if (IS_RIP_DEBUG_ZEBRA)
Stephen Hemminger2c239702009-12-10 19:16:05 +0300441 zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d",
442 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
443 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000444
445 /* Check if this interface is RIP enabled or not.*/
446 rip_enable_apply (ifp);
ajsd4e47282005-05-11 15:56:21 +0000447
448 /* Check for a passive interface */
449 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +0000450
451 /* Apply distribute list to the all interface. */
452 rip_distribute_update_interface (ifp);
453
454 /* rip_request_neighbor_all (); */
455
hasso16705132003-05-25 14:49:19 +0000456 /* Check interface routemap. */
457 rip_if_rmap_update_interface (ifp);
458
paul718e3742002-12-13 20:15:29 +0000459 return 0;
460}
461
462int
463rip_interface_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800464 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000465{
466 struct interface *ifp;
467 struct stream *s;
468
469
470 s = zclient->ibuf;
471 /* zebra_interface_state_read() updates interface structure in iflist */
Feng Luc99f3482014-10-16 09:52:36 +0800472 ifp = zebra_interface_state_read (s, vrf_id);
paul718e3742002-12-13 20:15:29 +0000473
474 if (ifp == NULL)
475 return 0;
476
477 if (if_is_up (ifp)) {
478 rip_if_down(ifp);
479 }
480
Stephen Hemminger2c239702009-12-10 19:16:05 +0300481 zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
482 ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
483 ifp->metric, ifp->mtu);
paul718e3742002-12-13 20:15:29 +0000484
485 /* To support pseudo interface do not free interface structure. */
486 /* if_delete(ifp); */
ajsd2fc8892005-04-02 18:38:43 +0000487 ifp->ifindex = IFINDEX_INTERNAL;
paul718e3742002-12-13 20:15:29 +0000488
489 return 0;
490}
491
Paul Jakmad319a3a2016-05-25 14:47:00 +0100492static void
493rip_interface_clean (struct rip_interface *ri)
paul718e3742002-12-13 20:15:29 +0000494{
Paul Jakmad319a3a2016-05-25 14:47:00 +0100495 ri->enable_network = 0;
496 ri->enable_interface = 0;
497 ri->running = 0;
paul718e3742002-12-13 20:15:29 +0000498
Paul Jakmad319a3a2016-05-25 14:47:00 +0100499 if (ri->t_wakeup)
paul718e3742002-12-13 20:15:29 +0000500 {
Paul Jakmad319a3a2016-05-25 14:47:00 +0100501 thread_cancel (ri->t_wakeup);
502 ri->t_wakeup = NULL;
paul718e3742002-12-13 20:15:29 +0000503 }
504}
505
506void
Paul Jakmad319a3a2016-05-25 14:47:00 +0100507rip_interfaces_clean (void)
paul718e3742002-12-13 20:15:29 +0000508{
hasso52dc7ee2004-09-23 19:18:23 +0000509 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000510 struct interface *ifp;
paul718e3742002-12-13 20:15:29 +0000511
paul1eb8ef22005-04-07 07:30:20 +0000512 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
Paul Jakmad319a3a2016-05-25 14:47:00 +0100513 rip_interface_clean (ifp->info);
514}
515
516static void
517rip_interface_reset (struct rip_interface *ri)
518{
519 /* Default authentication type is simple password for Cisco
520 compatibility. */
521 ri->auth_type = RIP_NO_AUTH;
522 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
523
524 /* Set default split-horizon behavior. If the interface is Frame
525 Relay or SMDS is enabled, the default value for split-horizon is
526 off. But currently Zebra does detect Frame Relay or SMDS
527 interface. So all interface is set to split horizon. */
528 ri->split_horizon_default = RIP_SPLIT_HORIZON;
529 ri->split_horizon = ri->split_horizon_default;
530
531 ri->ri_send = RI_RIP_UNSPEC;
532 ri->ri_receive = RI_RIP_UNSPEC;
533
534 if (ri->auth_str)
paul718e3742002-12-13 20:15:29 +0000535 {
Paul Jakmad319a3a2016-05-25 14:47:00 +0100536 free (ri->auth_str);
537 ri->auth_str = NULL;
paul718e3742002-12-13 20:15:29 +0000538 }
Paul Jakmad319a3a2016-05-25 14:47:00 +0100539 if (ri->key_chain)
540 {
541 free (ri->key_chain);
542 ri->key_chain = NULL;
543 }
544
545 ri->list[RIP_FILTER_IN] = NULL;
546 ri->list[RIP_FILTER_OUT] = NULL;
547
548 ri->prefix[RIP_FILTER_IN] = NULL;
549 ri->prefix[RIP_FILTER_OUT] = NULL;
550
551 ri->recv_badpackets = 0;
552 ri->recv_badroutes = 0;
553 ri->sent_updates = 0;
554
555 ri->passive = 0;
556
557 rip_interface_clean (ri);
558}
559
560void
561rip_interfaces_reset (void)
562{
563 struct listnode *node;
564 struct interface *ifp;
565
566 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
567 rip_interface_reset (ifp->info);
paul718e3742002-12-13 20:15:29 +0000568}
569
570int
571rip_if_down(struct interface *ifp)
572{
573 struct route_node *rp;
574 struct rip_info *rinfo;
575 struct rip_interface *ri = NULL;
Lu Fengb397cf42014-07-18 06:13:18 +0000576 struct list *list = NULL;
577 struct listnode *listnode = NULL, *nextnode = NULL;
paul718e3742002-12-13 20:15:29 +0000578 if (rip)
Lu Fengb397cf42014-07-18 06:13:18 +0000579 for (rp = route_top (rip->table); rp; rp = route_next (rp))
580 if ((list = rp->info) != NULL)
581 for (ALL_LIST_ELEMENTS (list, listnode, nextnode, rinfo))
582 if (rinfo->ifindex == ifp->ifindex)
583 rip_ecmp_delete (rinfo);
paul718e3742002-12-13 20:15:29 +0000584
paul718e3742002-12-13 20:15:29 +0000585 ri = ifp->info;
586
587 if (ri->running)
588 {
589 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +0000590 zlog_debug ("turn off %s", ifp->name);
paul718e3742002-12-13 20:15:29 +0000591
592 /* Leave from multicast group. */
593 rip_multicast_leave (ifp, rip->sock);
594
595 ri->running = 0;
596 }
597
598 return 0;
599}
600
601/* Needed for stop RIP process. */
602void
603rip_if_down_all ()
604{
605 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +0000606 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000607
paul1eb8ef22005-04-07 07:30:20 +0000608 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
609 rip_if_down (ifp);
paul718e3742002-12-13 20:15:29 +0000610}
611
hasso16705132003-05-25 14:49:19 +0000612static void
pauldc63bfd2005-10-25 23:31:05 +0000613rip_apply_address_add (struct connected *ifc)
614{
hasso16705132003-05-25 14:49:19 +0000615 struct prefix_ipv4 address;
616 struct prefix *p;
617
618 if (!rip)
619 return;
620
621 if (! if_is_up(ifc->ifp))
622 return;
623
624 p = ifc->address;
625
626 memset (&address, 0, sizeof (address));
627 address.family = p->family;
628 address.prefix = p->u.prefix4;
629 address.prefixlen = p->prefixlen;
630 apply_mask_ipv4(&address);
631
632 /* Check if this interface is RIP enabled or not
633 or Check if this address's prefix is RIP enabled */
634 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
635 (rip_enable_network_lookup2(ifc) >= 0))
636 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000637 &address, ifc->ifp->ifindex, NULL, 0, 0);
hasso16705132003-05-25 14:49:19 +0000638
639}
640
paul718e3742002-12-13 20:15:29 +0000641int
642rip_interface_address_add (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800643 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000644{
645 struct connected *ifc;
646 struct prefix *p;
647
paul0a589352004-05-08 11:48:26 +0000648 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
Feng Luc99f3482014-10-16 09:52:36 +0800649 zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000650
651 if (ifc == NULL)
652 return 0;
653
654 p = ifc->address;
655
656 if (p->family == AF_INET)
657 {
658 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000659 zlog_debug ("connected address %s/%d is added",
paul718e3742002-12-13 20:15:29 +0000660 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000661
paul878ef2e2003-09-23 23:41:50 +0000662 rip_enable_apply(ifc->ifp);
hasso16705132003-05-25 14:49:19 +0000663 /* Check if this prefix needs to be redistributed */
664 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000665
666#ifdef HAVE_SNMP
667 rip_ifaddr_add (ifc->ifp, ifc);
668#endif /* HAVE_SNMP */
669 }
670
671 return 0;
672}
673
hasso16705132003-05-25 14:49:19 +0000674static void
675rip_apply_address_del (struct connected *ifc) {
676 struct prefix_ipv4 address;
677 struct prefix *p;
678
679 if (!rip)
680 return;
681
682 if (! if_is_up(ifc->ifp))
683 return;
684
685 p = ifc->address;
686
687 memset (&address, 0, sizeof (address));
688 address.family = p->family;
689 address.prefix = p->u.prefix4;
690 address.prefixlen = p->prefixlen;
691 apply_mask_ipv4(&address);
692
693 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
694 &address, ifc->ifp->ifindex);
695}
696
paul718e3742002-12-13 20:15:29 +0000697int
698rip_interface_address_delete (int command, struct zclient *zclient,
Feng Luc99f3482014-10-16 09:52:36 +0800699 zebra_size_t length, vrf_id_t vrf_id)
paul718e3742002-12-13 20:15:29 +0000700{
701 struct connected *ifc;
702 struct prefix *p;
703
paul0a589352004-05-08 11:48:26 +0000704 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
Feng Luc99f3482014-10-16 09:52:36 +0800705 zclient->ibuf, vrf_id);
paul718e3742002-12-13 20:15:29 +0000706
707 if (ifc)
708 {
709 p = ifc->address;
710 if (p->family == AF_INET)
711 {
712 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +0000713 zlog_debug ("connected address %s/%d is deleted",
paul718e3742002-12-13 20:15:29 +0000714 inet_ntoa (p->u.prefix4), p->prefixlen);
715
716#ifdef HAVE_SNMP
717 rip_ifaddr_delete (ifc->ifp, ifc);
718#endif /* HAVE_SNMP */
719
hasso16705132003-05-25 14:49:19 +0000720 /* Chech wether this prefix needs to be removed */
721 rip_apply_address_del(ifc);
722
paul718e3742002-12-13 20:15:29 +0000723 }
724
725 connected_free (ifc);
726
727 }
728
729 return 0;
730}
David Lamparter6b0655a2014-06-04 06:53:35 +0200731
paul718e3742002-12-13 20:15:29 +0000732/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000733/* Check wether the interface has at least a connected prefix that
734 * is within the ripng_enable_network table. */
pauldc63bfd2005-10-25 23:31:05 +0000735static int
hasso16705132003-05-25 14:49:19 +0000736rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000737{
paul1eb8ef22005-04-07 07:30:20 +0000738 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000739 struct connected *connected;
740 struct prefix_ipv4 address;
741
paul1eb8ef22005-04-07 07:30:20 +0000742 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
743 {
744 struct prefix *p;
745 struct route_node *node;
paul718e3742002-12-13 20:15:29 +0000746
paul1eb8ef22005-04-07 07:30:20 +0000747 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000748
paul1eb8ef22005-04-07 07:30:20 +0000749 if (p->family == AF_INET)
750 {
751 address.family = AF_INET;
752 address.prefix = p->u.prefix4;
753 address.prefixlen = IPV4_MAX_BITLEN;
754
755 node = route_node_match (rip_enable_network,
756 (struct prefix *)&address);
757 if (node)
758 {
759 route_unlock_node (node);
760 return 1;
761 }
762 }
763 }
paul718e3742002-12-13 20:15:29 +0000764 return -1;
765}
766
hasso16705132003-05-25 14:49:19 +0000767/* Check wether connected is within the ripng_enable_network table. */
768int
769rip_enable_network_lookup2 (struct connected *connected)
770{
771 struct prefix_ipv4 address;
772 struct prefix *p;
773
774 p = connected->address;
775
776 if (p->family == AF_INET) {
777 struct route_node *node;
778
779 address.family = p->family;
780 address.prefix = p->u.prefix4;
781 address.prefixlen = IPV4_MAX_BITLEN;
782
783 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
784 node = route_node_match (rip_enable_network,
785 (struct prefix *)&address);
786
787 if (node) {
788 route_unlock_node (node);
789 return 1;
790 }
791 }
792
793 return -1;
794}
paul718e3742002-12-13 20:15:29 +0000795/* Add RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000796static int
paul718e3742002-12-13 20:15:29 +0000797rip_enable_network_add (struct prefix *p)
798{
799 struct route_node *node;
800
801 node = route_node_get (rip_enable_network, p);
802
803 if (node->info)
804 {
805 route_unlock_node (node);
806 return -1;
807 }
808 else
hasso8a676be2004-10-08 06:36:38 +0000809 node->info = (char *) "enabled";
paul718e3742002-12-13 20:15:29 +0000810
hasso16705132003-05-25 14:49:19 +0000811 /* XXX: One should find a better solution than a generic one */
812 rip_enable_apply_all();
813
paul718e3742002-12-13 20:15:29 +0000814 return 1;
815}
816
817/* Delete RIP enable network. */
pauldc63bfd2005-10-25 23:31:05 +0000818static int
paul718e3742002-12-13 20:15:29 +0000819rip_enable_network_delete (struct prefix *p)
820{
821 struct route_node *node;
822
823 node = route_node_lookup (rip_enable_network, p);
824 if (node)
825 {
826 node->info = NULL;
827
828 /* Unlock info lock. */
829 route_unlock_node (node);
830
831 /* Unlock lookup lock. */
832 route_unlock_node (node);
833
hasso16705132003-05-25 14:49:19 +0000834 /* XXX: One should find a better solution than a generic one */
835 rip_enable_apply_all ();
836
paul718e3742002-12-13 20:15:29 +0000837 return 1;
838 }
839 return -1;
840}
841
842/* Check interface is enabled by ifname statement. */
pauldc63bfd2005-10-25 23:31:05 +0000843static int
hasso98b718a2004-10-11 12:57:57 +0000844rip_enable_if_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000845{
hasso8a676be2004-10-08 06:36:38 +0000846 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000847 char *str;
848
paul55468c82005-03-14 20:19:01 +0000849 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +0000850 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
851 if (strcmp (str, ifname) == 0)
852 return i;
853 return -1;
854}
855
856/* Add interface to rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000857static int
hasso98b718a2004-10-11 12:57:57 +0000858rip_enable_if_add (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000859{
860 int ret;
861
862 ret = rip_enable_if_lookup (ifname);
863 if (ret >= 0)
864 return -1;
865
866 vector_set (rip_enable_interface, strdup (ifname));
867
hasso16705132003-05-25 14:49:19 +0000868 rip_enable_apply_all(); /* TODOVJ */
869
paul718e3742002-12-13 20:15:29 +0000870 return 1;
871}
872
873/* Delete interface from rip_enable_if. */
pauldc63bfd2005-10-25 23:31:05 +0000874static int
hasso98b718a2004-10-11 12:57:57 +0000875rip_enable_if_delete (const char *ifname)
paul718e3742002-12-13 20:15:29 +0000876{
877 int index;
878 char *str;
879
880 index = rip_enable_if_lookup (ifname);
881 if (index < 0)
882 return -1;
883
884 str = vector_slot (rip_enable_interface, index);
885 free (str);
886 vector_unset (rip_enable_interface, index);
887
hasso16705132003-05-25 14:49:19 +0000888 rip_enable_apply_all(); /* TODOVJ */
889
paul718e3742002-12-13 20:15:29 +0000890 return 1;
891}
892
893/* Join to multicast group and send request to the interface. */
pauldc63bfd2005-10-25 23:31:05 +0000894static int
paul718e3742002-12-13 20:15:29 +0000895rip_interface_wakeup (struct thread *t)
896{
897 struct interface *ifp;
898 struct rip_interface *ri;
899
900 /* Get interface. */
901 ifp = THREAD_ARG (t);
902
903 ri = ifp->info;
904 ri->t_wakeup = NULL;
905
906 /* Join to multicast group. */
907 if (rip_multicast_join (ifp, rip->sock) < 0)
908 {
909 zlog_err ("multicast join failed, interface %s not running", ifp->name);
910 return 0;
911 }
912
913 /* Set running flag. */
914 ri->running = 1;
915
916 /* Send RIP request to the interface. */
917 rip_request_interface (ifp);
918
919 return 0;
920}
921
pauldc63bfd2005-10-25 23:31:05 +0000922static void
paul718e3742002-12-13 20:15:29 +0000923rip_connect_set (struct interface *ifp, int set)
924{
paul1eb8ef22005-04-07 07:30:20 +0000925 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +0000926 struct connected *connected;
927 struct prefix_ipv4 address;
928
paul1eb8ef22005-04-07 07:30:20 +0000929 for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected))
930 {
931 struct prefix *p;
932 p = connected->address;
paul718e3742002-12-13 20:15:29 +0000933
paul1eb8ef22005-04-07 07:30:20 +0000934 if (p->family != AF_INET)
935 continue;
paul718e3742002-12-13 20:15:29 +0000936
paul1eb8ef22005-04-07 07:30:20 +0000937 address.family = AF_INET;
938 address.prefix = p->u.prefix4;
939 address.prefixlen = p->prefixlen;
940 apply_mask_ipv4 (&address);
paul718e3742002-12-13 20:15:29 +0000941
paul1eb8ef22005-04-07 07:30:20 +0000942 if (set) {
943 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
944 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
945 (rip_enable_network_lookup2(connected) >= 0))
946 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
vincentfbf5d032005-09-29 11:25:50 +0000947 &address, connected->ifp->ifindex,
948 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000949 } else
950 {
951 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
952 &address, connected->ifp->ifindex);
953 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
954 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
vincentfbf5d032005-09-29 11:25:50 +0000955 &address, connected->ifp->ifindex,
956 NULL, 0, 0);
paul1eb8ef22005-04-07 07:30:20 +0000957 }
958 }
paul718e3742002-12-13 20:15:29 +0000959}
960
961/* Update interface status. */
962void
963rip_enable_apply (struct interface *ifp)
964{
965 int ret;
966 struct rip_interface *ri = NULL;
967
968 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +0000969 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000970 return;
971
972 ri = ifp->info;
973
974 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +0000975 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +0000976
977 /* If the interface is matched. */
978 if (ret > 0)
979 ri->enable_network = 1;
980 else
981 ri->enable_network = 0;
982
983 /* Check interface name configuration. */
984 ret = rip_enable_if_lookup (ifp->name);
985 if (ret >= 0)
986 ri->enable_interface = 1;
987 else
988 ri->enable_interface = 0;
989
990 /* any interface MUST have an IPv4 address */
991 if ( ! rip_if_ipv4_address_check (ifp) )
992 {
993 ri->enable_network = 0;
994 ri->enable_interface = 0;
995 }
996
997 /* Update running status of the interface. */
998 if (ri->enable_network || ri->enable_interface)
999 {
paul718e3742002-12-13 20:15:29 +00001000 {
1001 if (IS_RIP_DEBUG_EVENT)
ajs5d6c3772004-12-08 19:24:06 +00001002 zlog_debug ("turn on %s", ifp->name);
paul718e3742002-12-13 20:15:29 +00001003
1004 /* Add interface wake up thread. */
1005 if (! ri->t_wakeup)
1006 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1007 ifp, 1);
1008 rip_connect_set (ifp, 1);
1009 }
1010 }
1011 else
1012 {
1013 if (ri->running)
1014 {
hasso16705132003-05-25 14:49:19 +00001015 /* Might as well clean up the route table as well
1016 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1017 **/
paul718e3742002-12-13 20:15:29 +00001018 rip_if_down(ifp);
1019
paul718e3742002-12-13 20:15:29 +00001020 rip_connect_set (ifp, 0);
1021 }
1022 }
1023}
1024
1025/* Apply network configuration to all interface. */
1026void
1027rip_enable_apply_all ()
1028{
1029 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001030 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001031
1032 /* Check each interface. */
paul1eb8ef22005-04-07 07:30:20 +00001033 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1034 rip_enable_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001035}
1036
1037int
1038rip_neighbor_lookup (struct sockaddr_in *from)
1039{
1040 struct prefix_ipv4 p;
1041 struct route_node *node;
1042
1043 memset (&p, 0, sizeof (struct prefix_ipv4));
1044 p.family = AF_INET;
1045 p.prefix = from->sin_addr;
1046 p.prefixlen = IPV4_MAX_BITLEN;
1047
1048 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1049 if (node)
1050 {
1051 route_unlock_node (node);
1052 return 1;
1053 }
1054 return 0;
1055}
1056
1057/* Add new RIP neighbor to the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001058static int
paul718e3742002-12-13 20:15:29 +00001059rip_neighbor_add (struct prefix_ipv4 *p)
1060{
1061 struct route_node *node;
1062
1063 node = route_node_get (rip->neighbor, (struct prefix *) p);
1064
1065 if (node->info)
1066 return -1;
1067
1068 node->info = rip->neighbor;
1069
1070 return 0;
1071}
1072
1073/* Delete RIP neighbor from the neighbor tree. */
pauldc63bfd2005-10-25 23:31:05 +00001074static int
paul718e3742002-12-13 20:15:29 +00001075rip_neighbor_delete (struct prefix_ipv4 *p)
1076{
1077 struct route_node *node;
1078
1079 /* Lock for look up. */
1080 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1081 if (! node)
1082 return -1;
1083
1084 node->info = NULL;
1085
1086 /* Unlock lookup lock. */
1087 route_unlock_node (node);
1088
1089 /* Unlock real neighbor information lock. */
1090 route_unlock_node (node);
1091
1092 return 0;
1093}
1094
1095/* Clear all network and neighbor configuration. */
1096void
1097rip_clean_network ()
1098{
hasso8a676be2004-10-08 06:36:38 +00001099 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001100 char *str;
1101 struct route_node *rn;
1102
1103 /* rip_enable_network. */
1104 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1105 if (rn->info)
1106 {
1107 rn->info = NULL;
1108 route_unlock_node (rn);
1109 }
1110
1111 /* rip_enable_interface. */
paul55468c82005-03-14 20:19:01 +00001112 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001113 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1114 {
1115 free (str);
1116 vector_slot (rip_enable_interface, i) = NULL;
1117 }
1118}
David Lamparter6b0655a2014-06-04 06:53:35 +02001119
paul718e3742002-12-13 20:15:29 +00001120/* Utility function for looking up passive interface settings. */
pauldc63bfd2005-10-25 23:31:05 +00001121static int
hasso98b718a2004-10-11 12:57:57 +00001122rip_passive_nondefault_lookup (const char *ifname)
paul718e3742002-12-13 20:15:29 +00001123{
hasso8a676be2004-10-08 06:36:38 +00001124 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001125 char *str;
1126
paul55468c82005-03-14 20:19:01 +00001127 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001128 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001129 if (strcmp (str, ifname) == 0)
1130 return i;
1131 return -1;
1132}
1133
1134void
1135rip_passive_interface_apply (struct interface *ifp)
1136{
paul718e3742002-12-13 20:15:29 +00001137 struct rip_interface *ri;
1138
1139 ri = ifp->info;
1140
paul4aaff3f2003-06-07 01:04:45 +00001141 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1142 passive_default : !passive_default);
1143
1144 if (IS_RIP_DEBUG_ZEBRA)
ajs5d6c3772004-12-08 19:24:06 +00001145 zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001146}
1147
pauldc63bfd2005-10-25 23:31:05 +00001148static void
1149rip_passive_interface_apply_all (void)
paul718e3742002-12-13 20:15:29 +00001150{
1151 struct interface *ifp;
paul1eb8ef22005-04-07 07:30:20 +00001152 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001153
paul1eb8ef22005-04-07 07:30:20 +00001154 for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
1155 rip_passive_interface_apply (ifp);
paul718e3742002-12-13 20:15:29 +00001156}
1157
1158/* Passive interface. */
pauldc63bfd2005-10-25 23:31:05 +00001159static int
hasso98b718a2004-10-11 12:57:57 +00001160rip_passive_nondefault_set (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001161{
paul4aaff3f2003-06-07 01:04:45 +00001162 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001163 return CMD_WARNING;
1164
paul4aaff3f2003-06-07 01:04:45 +00001165 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001166
1167 rip_passive_interface_apply_all ();
1168
1169 return CMD_SUCCESS;
1170}
1171
pauldc63bfd2005-10-25 23:31:05 +00001172static int
hasso98b718a2004-10-11 12:57:57 +00001173rip_passive_nondefault_unset (struct vty *vty, const char *ifname)
paul718e3742002-12-13 20:15:29 +00001174{
1175 int i;
1176 char *str;
1177
paul4aaff3f2003-06-07 01:04:45 +00001178 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001179 if (i < 0)
1180 return CMD_WARNING;
1181
paul4aaff3f2003-06-07 01:04:45 +00001182 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001183 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001184 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001185
1186 rip_passive_interface_apply_all ();
1187
1188 return CMD_SUCCESS;
1189}
1190
1191/* Free all configured RIP passive-interface settings. */
1192void
pauldc63bfd2005-10-25 23:31:05 +00001193rip_passive_nondefault_clean (void)
paul718e3742002-12-13 20:15:29 +00001194{
hasso8a676be2004-10-08 06:36:38 +00001195 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001196 char *str;
1197
paul55468c82005-03-14 20:19:01 +00001198 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00001199 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001200 {
1201 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001202 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001203 }
1204 rip_passive_interface_apply_all ();
1205}
David Lamparter6b0655a2014-06-04 06:53:35 +02001206
paul718e3742002-12-13 20:15:29 +00001207/* RIP enable network or interface configuration. */
1208DEFUN (rip_network,
1209 rip_network_cmd,
1210 "network (A.B.C.D/M|WORD)",
1211 "Enable routing on an IP network\n"
1212 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1213 "Interface name\n")
1214{
1215 int ret;
1216 struct prefix_ipv4 p;
1217
1218 ret = str2prefix_ipv4 (argv[0], &p);
1219
1220 if (ret)
1221 ret = rip_enable_network_add ((struct prefix *) &p);
1222 else
1223 ret = rip_enable_if_add (argv[0]);
1224
1225 if (ret < 0)
1226 {
1227 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1228 VTY_NEWLINE);
1229 return CMD_WARNING;
1230 }
1231
paul718e3742002-12-13 20:15:29 +00001232 return CMD_SUCCESS;
1233}
1234
1235/* RIP enable network or interface configuration. */
1236DEFUN (no_rip_network,
1237 no_rip_network_cmd,
1238 "no network (A.B.C.D/M|WORD)",
1239 NO_STR
1240 "Enable routing on an IP network\n"
1241 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1242 "Interface name\n")
1243{
1244 int ret;
1245 struct prefix_ipv4 p;
1246
1247 ret = str2prefix_ipv4 (argv[0], &p);
1248
1249 if (ret)
1250 ret = rip_enable_network_delete ((struct prefix *) &p);
1251 else
1252 ret = rip_enable_if_delete (argv[0]);
1253
1254 if (ret < 0)
1255 {
1256 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1257 VTY_NEWLINE);
1258 return CMD_WARNING;
1259 }
1260
paul718e3742002-12-13 20:15:29 +00001261 return CMD_SUCCESS;
1262}
1263
1264/* RIP neighbor configuration set. */
1265DEFUN (rip_neighbor,
1266 rip_neighbor_cmd,
1267 "neighbor A.B.C.D",
1268 "Specify a neighbor router\n"
1269 "Neighbor address\n")
1270{
1271 int ret;
1272 struct prefix_ipv4 p;
1273
1274 ret = str2prefix_ipv4 (argv[0], &p);
1275
1276 if (ret <= 0)
1277 {
1278 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1279 return CMD_WARNING;
1280 }
1281
1282 rip_neighbor_add (&p);
1283
1284 return CMD_SUCCESS;
1285}
1286
1287/* RIP neighbor configuration unset. */
1288DEFUN (no_rip_neighbor,
1289 no_rip_neighbor_cmd,
1290 "no neighbor A.B.C.D",
1291 NO_STR
1292 "Specify a neighbor router\n"
1293 "Neighbor address\n")
1294{
1295 int ret;
1296 struct prefix_ipv4 p;
1297
1298 ret = str2prefix_ipv4 (argv[0], &p);
1299
1300 if (ret <= 0)
1301 {
1302 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1303 return CMD_WARNING;
1304 }
1305
1306 rip_neighbor_delete (&p);
1307
1308 return CMD_SUCCESS;
1309}
1310
1311DEFUN (ip_rip_receive_version,
1312 ip_rip_receive_version_cmd,
1313 "ip rip receive version (1|2)",
1314 IP_STR
1315 "Routing Information Protocol\n"
1316 "Advertisement reception\n"
1317 "Version control\n"
1318 "RIP version 1\n"
1319 "RIP version 2\n")
1320{
1321 struct interface *ifp;
1322 struct rip_interface *ri;
1323
1324 ifp = (struct interface *)vty->index;
1325 ri = ifp->info;
1326
1327 /* Version 1. */
1328 if (atoi (argv[0]) == 1)
1329 {
1330 ri->ri_receive = RI_RIP_VERSION_1;
1331 return CMD_SUCCESS;
1332 }
1333 if (atoi (argv[0]) == 2)
1334 {
1335 ri->ri_receive = RI_RIP_VERSION_2;
1336 return CMD_SUCCESS;
1337 }
1338 return CMD_WARNING;
1339}
1340
1341DEFUN (ip_rip_receive_version_1,
1342 ip_rip_receive_version_1_cmd,
1343 "ip rip receive version 1 2",
1344 IP_STR
1345 "Routing Information Protocol\n"
1346 "Advertisement reception\n"
1347 "Version control\n"
1348 "RIP version 1\n"
1349 "RIP version 2\n")
1350{
1351 struct interface *ifp;
1352 struct rip_interface *ri;
1353
1354 ifp = (struct interface *)vty->index;
1355 ri = ifp->info;
1356
1357 /* Version 1 and 2. */
1358 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1359 return CMD_SUCCESS;
1360}
1361
1362DEFUN (ip_rip_receive_version_2,
1363 ip_rip_receive_version_2_cmd,
1364 "ip rip receive version 2 1",
1365 IP_STR
1366 "Routing Information Protocol\n"
1367 "Advertisement reception\n"
1368 "Version control\n"
1369 "RIP version 2\n"
1370 "RIP version 1\n")
1371{
1372 struct interface *ifp;
1373 struct rip_interface *ri;
1374
1375 ifp = (struct interface *)vty->index;
1376 ri = ifp->info;
1377
1378 /* Version 1 and 2. */
1379 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1380 return CMD_SUCCESS;
1381}
1382
1383DEFUN (no_ip_rip_receive_version,
1384 no_ip_rip_receive_version_cmd,
1385 "no ip rip receive version",
1386 NO_STR
1387 IP_STR
1388 "Routing Information Protocol\n"
1389 "Advertisement reception\n"
1390 "Version control\n")
1391{
1392 struct interface *ifp;
1393 struct rip_interface *ri;
1394
1395 ifp = (struct interface *)vty->index;
1396 ri = ifp->info;
1397
1398 ri->ri_receive = RI_RIP_UNSPEC;
1399 return CMD_SUCCESS;
1400}
1401
1402ALIAS (no_ip_rip_receive_version,
1403 no_ip_rip_receive_version_num_cmd,
1404 "no ip rip receive version (1|2)",
1405 NO_STR
1406 IP_STR
1407 "Routing Information Protocol\n"
1408 "Advertisement reception\n"
1409 "Version control\n"
1410 "Version 1\n"
1411 "Version 2\n")
1412
1413DEFUN (ip_rip_send_version,
1414 ip_rip_send_version_cmd,
1415 "ip rip send version (1|2)",
1416 IP_STR
1417 "Routing Information Protocol\n"
1418 "Advertisement transmission\n"
1419 "Version control\n"
1420 "RIP version 1\n"
1421 "RIP version 2\n")
1422{
1423 struct interface *ifp;
1424 struct rip_interface *ri;
1425
1426 ifp = (struct interface *)vty->index;
1427 ri = ifp->info;
1428
1429 /* Version 1. */
1430 if (atoi (argv[0]) == 1)
1431 {
1432 ri->ri_send = RI_RIP_VERSION_1;
1433 return CMD_SUCCESS;
1434 }
1435 if (atoi (argv[0]) == 2)
1436 {
1437 ri->ri_send = RI_RIP_VERSION_2;
1438 return CMD_SUCCESS;
1439 }
1440 return CMD_WARNING;
1441}
1442
1443DEFUN (ip_rip_send_version_1,
1444 ip_rip_send_version_1_cmd,
1445 "ip rip send version 1 2",
1446 IP_STR
1447 "Routing Information Protocol\n"
1448 "Advertisement transmission\n"
1449 "Version control\n"
1450 "RIP version 1\n"
1451 "RIP version 2\n")
1452{
1453 struct interface *ifp;
1454 struct rip_interface *ri;
1455
1456 ifp = (struct interface *)vty->index;
1457 ri = ifp->info;
1458
1459 /* Version 1 and 2. */
1460 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1461 return CMD_SUCCESS;
1462}
1463
1464DEFUN (ip_rip_send_version_2,
1465 ip_rip_send_version_2_cmd,
1466 "ip rip send version 2 1",
1467 IP_STR
1468 "Routing Information Protocol\n"
1469 "Advertisement transmission\n"
1470 "Version control\n"
1471 "RIP version 2\n"
1472 "RIP version 1\n")
1473{
1474 struct interface *ifp;
1475 struct rip_interface *ri;
1476
1477 ifp = (struct interface *)vty->index;
1478 ri = ifp->info;
1479
1480 /* Version 1 and 2. */
1481 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1482 return CMD_SUCCESS;
1483}
1484
1485DEFUN (no_ip_rip_send_version,
1486 no_ip_rip_send_version_cmd,
1487 "no ip rip send version",
1488 NO_STR
1489 IP_STR
1490 "Routing Information Protocol\n"
1491 "Advertisement transmission\n"
1492 "Version control\n")
1493{
1494 struct interface *ifp;
1495 struct rip_interface *ri;
1496
1497 ifp = (struct interface *)vty->index;
1498 ri = ifp->info;
1499
1500 ri->ri_send = RI_RIP_UNSPEC;
1501 return CMD_SUCCESS;
1502}
1503
1504ALIAS (no_ip_rip_send_version,
1505 no_ip_rip_send_version_num_cmd,
1506 "no ip rip send version (1|2)",
1507 NO_STR
1508 IP_STR
1509 "Routing Information Protocol\n"
1510 "Advertisement transmission\n"
1511 "Version control\n"
1512 "Version 1\n"
1513 "Version 2\n")
1514
1515DEFUN (ip_rip_authentication_mode,
1516 ip_rip_authentication_mode_cmd,
1517 "ip rip authentication mode (md5|text)",
1518 IP_STR
1519 "Routing Information Protocol\n"
1520 "Authentication control\n"
1521 "Authentication mode\n"
1522 "Keyed message digest\n"
1523 "Clear text authentication\n")
1524{
1525 struct interface *ifp;
1526 struct rip_interface *ri;
Paul Jakma15a2b082006-05-04 07:36:34 +00001527 int auth_type;
paul718e3742002-12-13 20:15:29 +00001528
1529 ifp = (struct interface *)vty->index;
1530 ri = ifp->info;
1531
paulca5e5162004-06-06 22:06:33 +00001532 if ( (argc < 1) || (argc > 2) )
1533 {
1534 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1535 return CMD_WARNING;
1536 }
1537
paul718e3742002-12-13 20:15:29 +00001538 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001539 auth_type = RIP_AUTH_MD5;
paul718e3742002-12-13 20:15:29 +00001540 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
Paul Jakma15a2b082006-05-04 07:36:34 +00001541 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
paul718e3742002-12-13 20:15:29 +00001542 else
1543 {
1544 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1545 return CMD_WARNING;
1546 }
1547
paulca5e5162004-06-06 22:06:33 +00001548 if (argc == 1)
Paul Jakma15a2b082006-05-04 07:36:34 +00001549 {
1550 ri->auth_type = auth_type;
1551 return CMD_SUCCESS;
1552 }
paulca5e5162004-06-06 22:06:33 +00001553
Paul Jakma15a2b082006-05-04 07:36:34 +00001554 if ( (argc == 2) && (auth_type != RIP_AUTH_MD5) )
paulca5e5162004-06-06 22:06:33 +00001555 {
1556 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1557 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001558 }
paulca5e5162004-06-06 22:06:33 +00001559
1560 if (strncmp ("r", argv[1], 1) == 0)
1561 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1562 else if (strncmp ("o", argv[1], 1) == 0)
1563 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1564 else
1565 return CMD_WARNING;
Paul Jakma15a2b082006-05-04 07:36:34 +00001566
1567 ri->auth_type = auth_type;
1568
paul718e3742002-12-13 20:15:29 +00001569 return CMD_SUCCESS;
1570}
1571
paulca5e5162004-06-06 22:06:33 +00001572ALIAS (ip_rip_authentication_mode,
1573 ip_rip_authentication_mode_authlen_cmd,
1574 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1575 IP_STR
1576 "Routing Information Protocol\n"
1577 "Authentication control\n"
1578 "Authentication mode\n"
1579 "Keyed message digest\n"
1580 "Clear text authentication\n"
1581 "MD5 authentication data length\n"
1582 "RFC compatible\n"
1583 "Old ripd compatible\n")
1584
paul718e3742002-12-13 20:15:29 +00001585DEFUN (no_ip_rip_authentication_mode,
1586 no_ip_rip_authentication_mode_cmd,
1587 "no ip rip authentication mode",
1588 NO_STR
1589 IP_STR
1590 "Routing Information Protocol\n"
1591 "Authentication control\n"
1592 "Authentication mode\n")
1593{
1594 struct interface *ifp;
1595 struct rip_interface *ri;
1596
1597 ifp = (struct interface *)vty->index;
1598 ri = ifp->info;
1599
paul7755a8c2005-06-02 08:20:53 +00001600 ri->auth_type = RIP_NO_AUTH;
paulca5e5162004-06-06 22:06:33 +00001601 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
paul718e3742002-12-13 20:15:29 +00001602
1603 return CMD_SUCCESS;
1604}
1605
1606ALIAS (no_ip_rip_authentication_mode,
1607 no_ip_rip_authentication_mode_type_cmd,
1608 "no ip rip authentication mode (md5|text)",
1609 NO_STR
1610 IP_STR
1611 "Routing Information Protocol\n"
1612 "Authentication control\n"
1613 "Authentication mode\n"
1614 "Keyed message digest\n"
1615 "Clear text authentication\n")
1616
paulca5e5162004-06-06 22:06:33 +00001617ALIAS (no_ip_rip_authentication_mode,
1618 no_ip_rip_authentication_mode_type_authlen_cmd,
1619 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1620 NO_STR
1621 IP_STR
1622 "Routing Information Protocol\n"
1623 "Authentication control\n"
1624 "Authentication mode\n"
1625 "Keyed message digest\n"
1626 "Clear text authentication\n"
1627 "MD5 authentication data length\n"
1628 "RFC compatible\n"
1629 "Old ripd compatible\n")
1630
paul718e3742002-12-13 20:15:29 +00001631DEFUN (ip_rip_authentication_string,
1632 ip_rip_authentication_string_cmd,
1633 "ip rip authentication string LINE",
1634 IP_STR
1635 "Routing Information Protocol\n"
1636 "Authentication control\n"
1637 "Authentication string\n"
1638 "Authentication string\n")
1639{
1640 struct interface *ifp;
1641 struct rip_interface *ri;
1642
1643 ifp = (struct interface *)vty->index;
1644 ri = ifp->info;
1645
1646 if (strlen (argv[0]) > 16)
1647 {
1648 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1649 VTY_NEWLINE);
1650 return CMD_WARNING;
1651 }
1652
1653 if (ri->key_chain)
1654 {
1655 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1656 return CMD_WARNING;
1657 }
1658
1659 if (ri->auth_str)
1660 free (ri->auth_str);
1661
1662 ri->auth_str = strdup (argv[0]);
1663
1664 return CMD_SUCCESS;
1665}
1666
1667DEFUN (no_ip_rip_authentication_string,
1668 no_ip_rip_authentication_string_cmd,
1669 "no ip rip authentication string",
1670 NO_STR
1671 IP_STR
1672 "Routing Information Protocol\n"
1673 "Authentication control\n"
1674 "Authentication string\n")
1675{
1676 struct interface *ifp;
1677 struct rip_interface *ri;
1678
1679 ifp = (struct interface *)vty->index;
1680 ri = ifp->info;
1681
1682 if (ri->auth_str)
1683 free (ri->auth_str);
1684
1685 ri->auth_str = NULL;
1686
1687 return CMD_SUCCESS;
1688}
1689
1690ALIAS (no_ip_rip_authentication_string,
1691 no_ip_rip_authentication_string2_cmd,
1692 "no ip rip authentication string LINE",
1693 NO_STR
1694 IP_STR
1695 "Routing Information Protocol\n"
1696 "Authentication control\n"
1697 "Authentication string\n"
1698 "Authentication string\n")
1699
1700DEFUN (ip_rip_authentication_key_chain,
1701 ip_rip_authentication_key_chain_cmd,
1702 "ip rip authentication key-chain LINE",
1703 IP_STR
1704 "Routing Information Protocol\n"
1705 "Authentication control\n"
1706 "Authentication key-chain\n"
1707 "name of key-chain\n")
1708{
1709 struct interface *ifp;
1710 struct rip_interface *ri;
1711
1712 ifp = (struct interface *) vty->index;
1713 ri = ifp->info;
1714
1715 if (ri->auth_str)
1716 {
1717 vty_out (vty, "%% authentication string configuration exists%s",
1718 VTY_NEWLINE);
1719 return CMD_WARNING;
1720 }
1721
1722 if (ri->key_chain)
1723 free (ri->key_chain);
1724
1725 ri->key_chain = strdup (argv[0]);
1726
1727 return CMD_SUCCESS;
1728}
1729
1730DEFUN (no_ip_rip_authentication_key_chain,
1731 no_ip_rip_authentication_key_chain_cmd,
1732 "no ip rip authentication key-chain",
1733 NO_STR
1734 IP_STR
1735 "Routing Information Protocol\n"
1736 "Authentication control\n"
1737 "Authentication key-chain\n")
1738{
1739 struct interface *ifp;
1740 struct rip_interface *ri;
1741
1742 ifp = (struct interface *) vty->index;
1743 ri = ifp->info;
1744
1745 if (ri->key_chain)
1746 free (ri->key_chain);
1747
1748 ri->key_chain = NULL;
1749
1750 return CMD_SUCCESS;
1751}
1752
1753ALIAS (no_ip_rip_authentication_key_chain,
1754 no_ip_rip_authentication_key_chain2_cmd,
1755 "no ip rip authentication key-chain LINE",
1756 NO_STR
1757 IP_STR
1758 "Routing Information Protocol\n"
1759 "Authentication control\n"
1760 "Authentication key-chain\n"
1761 "name of key-chain\n")
1762
hasso16705132003-05-25 14:49:19 +00001763/* CHANGED: ip rip split-horizon
1764 Cisco and Zebra's command is
1765 ip split-horizon
1766 */
1767DEFUN (ip_rip_split_horizon,
1768 ip_rip_split_horizon_cmd,
1769 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001770 IP_STR
hasso16705132003-05-25 14:49:19 +00001771 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001772 "Perform split horizon\n")
1773{
1774 struct interface *ifp;
1775 struct rip_interface *ri;
1776
1777 ifp = vty->index;
1778 ri = ifp->info;
1779
hasso16705132003-05-25 14:49:19 +00001780 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001781 return CMD_SUCCESS;
1782}
1783
hasso16705132003-05-25 14:49:19 +00001784DEFUN (ip_rip_split_horizon_poisoned_reverse,
1785 ip_rip_split_horizon_poisoned_reverse_cmd,
1786 "ip rip split-horizon poisoned-reverse",
1787 IP_STR
1788 "Routing Information Protocol\n"
1789 "Perform split horizon\n"
1790 "With poisoned-reverse\n")
1791{
1792 struct interface *ifp;
1793 struct rip_interface *ri;
1794
1795 ifp = vty->index;
1796 ri = ifp->info;
1797
1798 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1799 return CMD_SUCCESS;
1800}
1801
1802/* CHANGED: no ip rip split-horizon
1803 Cisco and Zebra's command is
1804 no ip split-horizon
1805 */
1806DEFUN (no_ip_rip_split_horizon,
1807 no_ip_rip_split_horizon_cmd,
1808 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001809 NO_STR
1810 IP_STR
hasso16705132003-05-25 14:49:19 +00001811 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001812 "Perform split horizon\n")
1813{
1814 struct interface *ifp;
1815 struct rip_interface *ri;
1816
1817 ifp = vty->index;
1818 ri = ifp->info;
1819
hasso16705132003-05-25 14:49:19 +00001820 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001821 return CMD_SUCCESS;
1822}
1823
vincentfac3e842005-10-06 07:45:43 +00001824DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
hasso16705132003-05-25 14:49:19 +00001825 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1826 "no ip rip split-horizon poisoned-reverse",
1827 NO_STR
1828 IP_STR
1829 "Routing Information Protocol\n"
1830 "Perform split horizon\n"
1831 "With poisoned-reverse\n")
vincentfac3e842005-10-06 07:45:43 +00001832{
1833 struct interface *ifp;
1834 struct rip_interface *ri;
1835
1836 ifp = vty->index;
1837 ri = ifp->info;
1838
1839 switch( ri->split_horizon )
1840 {
1841 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1842 ri->split_horizon = RIP_SPLIT_HORIZON;
1843 default:
1844 break;
1845 }
1846
1847 return CMD_SUCCESS;
1848}
hasso16705132003-05-25 14:49:19 +00001849
paul718e3742002-12-13 20:15:29 +00001850DEFUN (rip_passive_interface,
1851 rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001852 "passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001853 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001854 "Interface name\n"
1855 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001856{
hasso98b718a2004-10-11 12:57:57 +00001857 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001858
1859 if (!strcmp(ifname,"default")) {
1860 passive_default = 1;
1861 rip_passive_nondefault_clean();
1862 return CMD_SUCCESS;
1863 }
1864 if (passive_default)
1865 return rip_passive_nondefault_unset (vty, ifname);
1866 else
1867 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001868}
1869
1870DEFUN (no_rip_passive_interface,
1871 no_rip_passive_interface_cmd,
paul56e475c2003-06-20 00:23:27 +00001872 "no passive-interface (IFNAME|default)",
paul718e3742002-12-13 20:15:29 +00001873 NO_STR
1874 "Suppress routing updates on an interface\n"
paul56e475c2003-06-20 00:23:27 +00001875 "Interface name\n"
1876 "default for all interfaces\n")
paul718e3742002-12-13 20:15:29 +00001877{
hasso98b718a2004-10-11 12:57:57 +00001878 const char *ifname = argv[0];
paul4aaff3f2003-06-07 01:04:45 +00001879
1880 if (!strcmp(ifname,"default")) {
1881 passive_default = 0;
1882 rip_passive_nondefault_clean();
1883 return CMD_SUCCESS;
1884 }
1885 if (passive_default)
1886 return rip_passive_nondefault_set (vty, ifname);
1887 else
1888 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001889}
David Lamparter6b0655a2014-06-04 06:53:35 +02001890
paul718e3742002-12-13 20:15:29 +00001891/* Write rip configuration of each interface. */
pauldc63bfd2005-10-25 23:31:05 +00001892static int
paul718e3742002-12-13 20:15:29 +00001893rip_interface_config_write (struct vty *vty)
1894{
hasso52dc7ee2004-09-23 19:18:23 +00001895 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001896 struct interface *ifp;
1897
paul1eb8ef22005-04-07 07:30:20 +00001898 for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp))
paul718e3742002-12-13 20:15:29 +00001899 {
1900 struct rip_interface *ri;
1901
paul718e3742002-12-13 20:15:29 +00001902 ri = ifp->info;
1903
hasso16705132003-05-25 14:49:19 +00001904 /* Do not display the interface if there is no
1905 * configuration about it.
1906 **/
1907 if ((!ifp->desc) &&
1908 (ri->split_horizon == ri->split_horizon_default) &&
1909 (ri->ri_send == RI_RIP_UNSPEC) &&
1910 (ri->ri_receive == RI_RIP_UNSPEC) &&
1911 (ri->auth_type != RIP_AUTH_MD5) &&
paulca5e5162004-06-06 22:06:33 +00001912 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
hasso16705132003-05-25 14:49:19 +00001913 (!ri->auth_str) &&
1914 (!ri->key_chain) )
1915 continue;
1916
paul718e3742002-12-13 20:15:29 +00001917 vty_out (vty, "interface %s%s", ifp->name,
1918 VTY_NEWLINE);
1919
1920 if (ifp->desc)
1921 vty_out (vty, " description %s%s", ifp->desc,
1922 VTY_NEWLINE);
1923
1924 /* Split horizon. */
1925 if (ri->split_horizon != ri->split_horizon_default)
1926 {
hasso16705132003-05-25 14:49:19 +00001927 switch (ri->split_horizon) {
1928 case RIP_SPLIT_HORIZON:
1929 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1930 break;
1931 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1932 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1933 VTY_NEWLINE);
1934 break;
1935 case RIP_NO_SPLIT_HORIZON:
1936 default:
1937 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1938 break;
1939 }
paul718e3742002-12-13 20:15:29 +00001940 }
1941
1942 /* RIP version setting. */
1943 if (ri->ri_send != RI_RIP_UNSPEC)
1944 vty_out (vty, " ip rip send version %s%s",
1945 lookup (ri_version_msg, ri->ri_send),
1946 VTY_NEWLINE);
1947
1948 if (ri->ri_receive != RI_RIP_UNSPEC)
1949 vty_out (vty, " ip rip receive version %s%s",
1950 lookup (ri_version_msg, ri->ri_receive),
1951 VTY_NEWLINE);
1952
1953 /* RIP authentication. */
paul718e3742002-12-13 20:15:29 +00001954 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1955 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
paulca5e5162004-06-06 22:06:33 +00001956
paul718e3742002-12-13 20:15:29 +00001957 if (ri->auth_type == RIP_AUTH_MD5)
paulca5e5162004-06-06 22:06:33 +00001958 {
1959 vty_out (vty, " ip rip authentication mode md5");
1960 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1961 vty_out (vty, " auth-length old-ripd");
1962 else
1963 vty_out (vty, " auth-length rfc");
1964 vty_out (vty, "%s", VTY_NEWLINE);
1965 }
paul718e3742002-12-13 20:15:29 +00001966
1967 if (ri->auth_str)
1968 vty_out (vty, " ip rip authentication string %s%s",
1969 ri->auth_str, VTY_NEWLINE);
1970
1971 if (ri->key_chain)
1972 vty_out (vty, " ip rip authentication key-chain %s%s",
1973 ri->key_chain, VTY_NEWLINE);
1974
1975 vty_out (vty, "!%s", VTY_NEWLINE);
1976 }
1977 return 0;
1978}
1979
1980int
1981config_write_rip_network (struct vty *vty, int config_mode)
1982{
hasso8a676be2004-10-08 06:36:38 +00001983 unsigned int i;
paul718e3742002-12-13 20:15:29 +00001984 char *ifname;
1985 struct route_node *node;
1986
1987 /* Network type RIP enable interface statement. */
1988 for (node = route_top (rip_enable_network); node; node = route_next (node))
1989 if (node->info)
1990 vty_out (vty, "%s%s/%d%s",
1991 config_mode ? " network " : " ",
1992 inet_ntoa (node->p.u.prefix4),
1993 node->p.prefixlen,
1994 VTY_NEWLINE);
1995
1996 /* Interface name RIP enable statement. */
paul55468c82005-03-14 20:19:01 +00001997 for (i = 0; i < vector_active (rip_enable_interface); i++)
paul718e3742002-12-13 20:15:29 +00001998 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
1999 vty_out (vty, "%s%s%s",
2000 config_mode ? " network " : " ",
2001 ifname,
2002 VTY_NEWLINE);
2003
2004 /* RIP neighbors listing. */
2005 for (node = route_top (rip->neighbor); node; node = route_next (node))
2006 if (node->info)
2007 vty_out (vty, "%s%s%s",
2008 config_mode ? " neighbor " : " ",
2009 inet_ntoa (node->p.u.prefix4),
2010 VTY_NEWLINE);
2011
2012 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00002013 if (config_mode) {
2014 if (passive_default)
paul01d09082003-06-08 21:22:18 +00002015 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
paul55468c82005-03-14 20:19:01 +00002016 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
paul4aaff3f2003-06-07 01:04:45 +00002017 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2018 vty_out (vty, " %spassive-interface %s%s",
2019 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2020 }
paul718e3742002-12-13 20:15:29 +00002021
2022 return 0;
2023}
2024
Stephen Hemminger7fc626d2008-12-01 11:10:34 -08002025static struct cmd_node interface_node =
paul718e3742002-12-13 20:15:29 +00002026{
2027 INTERFACE_NODE,
2028 "%s(config-if)# ",
2029 1,
2030};
2031
2032/* Called when interface structure allocated. */
pauldc63bfd2005-10-25 23:31:05 +00002033static int
paul718e3742002-12-13 20:15:29 +00002034rip_interface_new_hook (struct interface *ifp)
2035{
2036 ifp->info = rip_interface_new ();
2037 return 0;
2038}
2039
2040/* Called when interface structure deleted. */
pauldc63bfd2005-10-25 23:31:05 +00002041static int
paul718e3742002-12-13 20:15:29 +00002042rip_interface_delete_hook (struct interface *ifp)
2043{
2044 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002045 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002046 return 0;
2047}
2048
2049/* Allocate and initialize interface vector. */
2050void
pauldc63bfd2005-10-25 23:31:05 +00002051rip_if_init (void)
paul718e3742002-12-13 20:15:29 +00002052{
2053 /* Default initial size of interface vector. */
paul718e3742002-12-13 20:15:29 +00002054 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2055 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2056
2057 /* RIP network init. */
2058 rip_enable_interface = vector_init (1);
2059 rip_enable_network = route_table_init ();
2060
2061 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002062 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002063
2064 /* Install interface node. */
2065 install_node (&interface_node, rip_interface_config_write);
2066
2067 /* Install commands. */
2068 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002069 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002070 install_default (INTERFACE_NODE);
2071 install_element (INTERFACE_NODE, &interface_desc_cmd);
2072 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2073 install_element (RIP_NODE, &rip_network_cmd);
2074 install_element (RIP_NODE, &no_rip_network_cmd);
2075 install_element (RIP_NODE, &rip_neighbor_cmd);
2076 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2077
2078 install_element (RIP_NODE, &rip_passive_interface_cmd);
2079 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2080
2081 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2082 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2083 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2084 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2085 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2086
2087 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2088 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2089 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2090 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2091 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2092
2093 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
paulca5e5162004-06-06 22:06:33 +00002094 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002095 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2096 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
paulca5e5162004-06-06 22:06:33 +00002097 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
paul718e3742002-12-13 20:15:29 +00002098
2099 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2100 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2101 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2102
2103 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2104 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2105 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2106
hasso16705132003-05-25 14:49:19 +00002107 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2108 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2109 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2110 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002111}