blob: 1aec0f09a7088fdfdef5995bca130eb2ece8fb95 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Interface related function for RIP.
2 * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "command.h"
25#include "if.h"
26#include "sockunion.h"
27#include "prefix.h"
28#include "memory.h"
29#include "network.h"
30#include "table.h"
31#include "log.h"
32#include "stream.h"
33#include "thread.h"
34#include "zclient.h"
35#include "filter.h"
36#include "sockopt.h"
pauledd7c242003-06-04 13:59:38 +000037#include "privs.h"
paul718e3742002-12-13 20:15:29 +000038
39#include "zebra/connected.h"
40
41#include "ripd/ripd.h"
42#include "ripd/rip_debug.h"
43
44void rip_enable_apply (struct interface *);
45void rip_passive_interface_apply (struct interface *);
46int rip_if_down(struct interface *ifp);
hasso16705132003-05-25 14:49:19 +000047int rip_enable_if_lookup (char *ifname);
48int rip_enable_network_lookup2 (struct connected *connected);
49void rip_enable_apply_all ();
50
paul718e3742002-12-13 20:15:29 +000051
52struct message ri_version_msg[] =
53{
54 {RI_RIP_VERSION_1, "1"},
55 {RI_RIP_VERSION_2, "2"},
56 {RI_RIP_VERSION_1_AND_2, "1 2"},
57 {0, NULL}
58};
59
pauledd7c242003-06-04 13:59:38 +000060extern struct zebra_privs_t ripd_privs;
61
paul718e3742002-12-13 20:15:29 +000062/* RIP enabled network vector. */
63vector rip_enable_interface;
64
65/* RIP enabled interface table. */
66struct route_table *rip_enable_network;
67
68/* Vector to store passive-interface name. */
paul4aaff3f2003-06-07 01:04:45 +000069static int passive_default; /* are we in passive-interface default mode? */
70vector Vrip_passive_nondefault;
paul718e3742002-12-13 20:15:29 +000071
72/* Join to the RIP version 2 multicast group. */
73int
74ipv4_multicast_join (int sock,
75 struct in_addr group,
76 struct in_addr ifa,
77 unsigned int ifindex)
78{
79 int ret;
80
81 ret = setsockopt_multicast_ipv4 (sock,
82 IP_ADD_MEMBERSHIP,
83 ifa,
84 group.s_addr,
85 ifindex);
86
87 if (ret < 0)
88 zlog (NULL, LOG_INFO, "can't setsockopt IP_ADD_MEMBERSHIP %s",
89 strerror (errno));
90
91 return ret;
92}
93
94/* Leave from the RIP version 2 multicast group. */
95int
96ipv4_multicast_leave (int sock,
97 struct in_addr group,
98 struct in_addr ifa,
99 unsigned int ifindex)
100{
101 int ret;
102
103 ret = setsockopt_multicast_ipv4 (sock,
104 IP_DROP_MEMBERSHIP,
105 ifa,
106 group.s_addr,
107 ifindex);
108
109 if (ret < 0)
110 zlog (NULL, LOG_INFO, "can't setsockopt IP_DROP_MEMBERSHIP");
111
112 return ret;
113}
114
115/* Allocate new RIP's interface configuration. */
116struct rip_interface *
117rip_interface_new ()
118{
119 struct rip_interface *ri;
120
121 ri = XMALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface));
122 memset (ri, 0, sizeof (struct rip_interface));
123
124 /* Default authentication type is simple password for Cisco
125 compatibility. */
126 /* ri->auth_type = RIP_NO_AUTH; */
127 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
128
129 /* Set default split-horizon behavior. If the interface is Frame
130 Relay or SMDS is enabled, the default value for split-horizon is
131 off. But currently Zebra does detect Frame Relay or SMDS
132 interface. So all interface is set to split horizon. */
hasso16705132003-05-25 14:49:19 +0000133 ri->split_horizon_default = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000134 ri->split_horizon = ri->split_horizon_default;
135
136 return ri;
137}
138
139void
140rip_interface_multicast_set (int sock, struct interface *ifp)
141{
142 int ret;
143 listnode node;
144 struct servent *sp;
145 struct sockaddr_in from;
146
147 for (node = listhead (ifp->connected); node; nextnode (node))
148 {
149 struct prefix_ipv4 *p;
150 struct connected *connected;
151 struct in_addr addr;
152
153 connected = getdata (node);
154 p = (struct prefix_ipv4 *) connected->address;
155
156 if (p->family == AF_INET)
157 {
158 addr = p->prefix;
159
160 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF,
161 addr, 0, ifp->ifindex) < 0)
162 {
163 zlog_warn ("Can't setsockopt IP_MULTICAST_IF to fd %d", sock);
164 return;
165 }
166
167 /* Bind myself. */
168 memset (&from, 0, sizeof (struct sockaddr_in));
169
170 /* Set RIP port. */
171 sp = getservbyname ("router", "udp");
172 if (sp)
173 from.sin_port = sp->s_port;
174 else
175 from.sin_port = htons (RIP_PORT_DEFAULT);
176
177 /* Address shoud be any address. */
178 from.sin_family = AF_INET;
179 from.sin_addr = addr;
180#ifdef HAVE_SIN_LEN
181 from.sin_len = sizeof (struct sockaddr_in);
182#endif /* HAVE_SIN_LEN */
183
pauledd7c242003-06-04 13:59:38 +0000184 if (ripd_privs.change (ZPRIVS_RAISE))
185 zlog_err ("rip_interface_multicast_set: could not raise privs");
186
paul718e3742002-12-13 20:15:29 +0000187 ret = bind (sock, (struct sockaddr *) & from,
188 sizeof (struct sockaddr_in));
189 if (ret < 0)
190 {
191 zlog_warn ("Can't bind socket: %s", strerror (errno));
192 return;
193 }
194
pauledd7c242003-06-04 13:59:38 +0000195 if (ripd_privs.change (ZPRIVS_LOWER))
196 zlog_err ("rip_interface_multicast_set: could not lower privs");
197
paul718e3742002-12-13 20:15:29 +0000198 return;
199
200 }
201 }
202}
203
204/* Send RIP request packet to specified interface. */
205void
206rip_request_interface_send (struct interface *ifp, u_char version)
207{
208 struct sockaddr_in to;
209
210 /* RIPv2 support multicast. */
211 if (version == RIPv2 && if_is_multicast (ifp))
212 {
213
214 if (IS_RIP_DEBUG_EVENT)
215 zlog_info ("multicast request on %s", ifp->name);
216
217 rip_request_send (NULL, ifp, version);
218 return;
219 }
220
221 /* RIPv1 and non multicast interface. */
222 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
223 {
224 listnode cnode;
225
226 if (IS_RIP_DEBUG_EVENT)
227 zlog_info ("broadcast request to %s", ifp->name);
228
229 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
230 {
231 struct prefix_ipv4 *p;
232 struct connected *connected;
233
234 connected = getdata (cnode);
235 p = (struct prefix_ipv4 *) connected->destination;
236
237 if (p->family == AF_INET)
238 {
239 memset (&to, 0, sizeof (struct sockaddr_in));
240 to.sin_port = htons (RIP_PORT_DEFAULT);
241 to.sin_addr = p->prefix;
242
paul718e3742002-12-13 20:15:29 +0000243 if (IS_RIP_DEBUG_EVENT)
244 zlog_info ("SEND request to %s", inet_ntoa (to.sin_addr));
paul718e3742002-12-13 20:15:29 +0000245
246 rip_request_send (&to, ifp, version);
247 }
248 }
249 }
250}
251
252/* This will be executed when interface goes up. */
253void
254rip_request_interface (struct interface *ifp)
255{
256 struct rip_interface *ri;
257
258 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
259 if (if_is_loopback (ifp))
260 return;
261
262 /* If interface is down, don't send RIP packet. */
paul2e3b2e42002-12-13 21:03:13 +0000263 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000264 return;
265
266 /* Fetch RIP interface information. */
267 ri = ifp->info;
268
269
270 /* If there is no version configuration in the interface,
271 use rip's version setting. */
paulf38a4712003-06-07 01:10:00 +0000272 {
273 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
274 rip->version_send : ri->ri_send);
275 if (vsend & RIPv1)
276 rip_request_interface_send (ifp, RIPv1);
277 if (vsend & RIPv2)
278 rip_request_interface_send (ifp, RIPv2);
279 }
paul718e3742002-12-13 20:15:29 +0000280}
281
282/* Send RIP request to the neighbor. */
283void
284rip_request_neighbor (struct in_addr addr)
285{
286 struct sockaddr_in to;
287
288 memset (&to, 0, sizeof (struct sockaddr_in));
289 to.sin_port = htons (RIP_PORT_DEFAULT);
290 to.sin_addr = addr;
291
paulf38a4712003-06-07 01:10:00 +0000292 rip_request_send (&to, NULL, rip->version_send);
paul718e3742002-12-13 20:15:29 +0000293}
294
295/* Request routes at all interfaces. */
296void
297rip_request_neighbor_all ()
298{
299 struct route_node *rp;
300
301 if (! rip)
302 return;
303
304 if (IS_RIP_DEBUG_EVENT)
305 zlog_info ("request to the all neighbor");
306
307 /* Send request to all neighbor. */
308 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
309 if (rp->info)
310 rip_request_neighbor (rp->p.u.prefix4);
311}
312
313/* Multicast packet receive socket. */
314int
315rip_multicast_join (struct interface *ifp, int sock)
316{
317 listnode cnode;
318
paul2e3b2e42002-12-13 21:03:13 +0000319 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000320 {
321 if (IS_RIP_DEBUG_EVENT)
322 zlog_info ("multicast join at %s", ifp->name);
323
324 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
325 {
326 struct prefix_ipv4 *p;
327 struct connected *connected;
328 struct in_addr group;
329
330 connected = getdata (cnode);
331 p = (struct prefix_ipv4 *) connected->address;
332
333 if (p->family != AF_INET)
334 continue;
335
336 group.s_addr = htonl (INADDR_RIP_GROUP);
337 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
338 return -1;
339 else
340 return 0;
341 }
342 }
343 return 0;
344}
345
346/* Leave from multicast group. */
347void
348rip_multicast_leave (struct interface *ifp, int sock)
349{
350 listnode cnode;
351
352 if (if_is_up (ifp) && if_is_multicast (ifp))
353 {
354 if (IS_RIP_DEBUG_EVENT)
355 zlog_info ("multicast leave from %s", ifp->name);
356
357 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
358 {
359 struct prefix_ipv4 *p;
360 struct connected *connected;
361 struct in_addr group;
362
363 connected = getdata (cnode);
364 p = (struct prefix_ipv4 *) connected->address;
365
366 if (p->family != AF_INET)
367 continue;
368
369 group.s_addr = htonl (INADDR_RIP_GROUP);
370 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
371 return;
372 }
373 }
374}
375
376/* Is there and address on interface that I could use ? */
377int
378rip_if_ipv4_address_check (struct interface *ifp)
379{
380 struct listnode *nn;
381 struct connected *connected;
382 int count = 0;
383
384 for (nn = listhead (ifp->connected); nn; nextnode (nn))
385 if ((connected = getdata (nn)) != NULL)
386 {
387 struct prefix *p;
388
389 p = connected->address;
390
391 if (p->family == AF_INET)
392 {
393 count++;
394 }
395 }
396
397 return count;
398}
paul718e3742002-12-13 20:15:29 +0000399
400/* Inteface link down message processing. */
401int
402rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
403{
404 struct interface *ifp;
405 struct stream *s;
406
407 s = zclient->ibuf;
408
409 /* zebra_interface_state_read() updates interface structure in
410 iflist. */
411 ifp = zebra_interface_state_read(s);
412
413 if (ifp == NULL)
414 return 0;
415
416 rip_if_down(ifp);
417
418 if (IS_RIP_DEBUG_ZEBRA)
419 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is down",
420 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
421
422 return 0;
423}
424
425/* Inteface link up message processing */
426int
427rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
428{
429 struct interface *ifp;
430
431 /* zebra_interface_state_read () updates interface structure in
432 iflist. */
433 ifp = zebra_interface_state_read (zclient->ibuf);
434
435 if (ifp == NULL)
436 return 0;
437
438 if (IS_RIP_DEBUG_ZEBRA)
439 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is up",
440 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
441
442 /* Check if this interface is RIP enabled or not.*/
443 rip_enable_apply (ifp);
444
445 /* Check for a passive interface */
446 rip_passive_interface_apply (ifp);
447
448 /* Apply distribute list to the all interface. */
449 rip_distribute_update_interface (ifp);
450
451 return 0;
452}
453
454/* Inteface addition message from zebra. */
455int
456rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
457{
458 struct interface *ifp;
459
460 ifp = zebra_interface_add_read (zclient->ibuf);
461
462 if (IS_RIP_DEBUG_ZEBRA)
463 zlog_info ("interface add %s index %d flags %ld metric %d mtu %d",
464 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
465
466 /* Check if this interface is RIP enabled or not.*/
467 rip_enable_apply (ifp);
468
469 /* Apply distribute list to the all interface. */
470 rip_distribute_update_interface (ifp);
471
472 /* rip_request_neighbor_all (); */
473
hasso16705132003-05-25 14:49:19 +0000474 /* Check interface routemap. */
475 rip_if_rmap_update_interface (ifp);
476
paul718e3742002-12-13 20:15:29 +0000477 return 0;
478}
479
480int
481rip_interface_delete (int command, struct zclient *zclient,
482 zebra_size_t length)
483{
484 struct interface *ifp;
485 struct stream *s;
486
487
488 s = zclient->ibuf;
489 /* zebra_interface_state_read() updates interface structure in iflist */
490 ifp = zebra_interface_state_read(s);
491
492 if (ifp == NULL)
493 return 0;
494
495 if (if_is_up (ifp)) {
496 rip_if_down(ifp);
497 }
498
499 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
500 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
501
502 /* To support pseudo interface do not free interface structure. */
503 /* if_delete(ifp); */
504
505 return 0;
506}
507
508void
509rip_interface_clean ()
510{
511 listnode node;
512 struct interface *ifp;
513 struct rip_interface *ri;
514
515 for (node = listhead (iflist); node; nextnode (node))
516 {
517 ifp = getdata (node);
518 ri = ifp->info;
519
520 ri->enable_network = 0;
521 ri->enable_interface = 0;
522 ri->running = 0;
523
524 if (ri->t_wakeup)
525 {
526 thread_cancel (ri->t_wakeup);
527 ri->t_wakeup = NULL;
528 }
529 }
530}
531
532void
533rip_interface_reset ()
534{
535 listnode node;
536 struct interface *ifp;
537 struct rip_interface *ri;
538
539 for (node = listhead (iflist); node; nextnode (node))
540 {
541 ifp = getdata (node);
542 ri = ifp->info;
543
544 ri->enable_network = 0;
545 ri->enable_interface = 0;
546 ri->running = 0;
547
548 ri->ri_send = RI_RIP_UNSPEC;
549 ri->ri_receive = RI_RIP_UNSPEC;
550
551 /* ri->auth_type = RIP_NO_AUTH; */
552 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
553
554 if (ri->auth_str)
555 {
556 free (ri->auth_str);
557 ri->auth_str = NULL;
558 }
559 if (ri->key_chain)
560 {
561 free (ri->key_chain);
562 ri->key_chain = NULL;
563 }
564
hasso16705132003-05-25 14:49:19 +0000565 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
566 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000567
568 ri->list[RIP_FILTER_IN] = NULL;
569 ri->list[RIP_FILTER_OUT] = NULL;
570
571 ri->prefix[RIP_FILTER_IN] = NULL;
572 ri->prefix[RIP_FILTER_OUT] = NULL;
573
574 if (ri->t_wakeup)
575 {
576 thread_cancel (ri->t_wakeup);
577 ri->t_wakeup = NULL;
578 }
579
580 ri->recv_badpackets = 0;
581 ri->recv_badroutes = 0;
582 ri->sent_updates = 0;
583
584 ri->passive = 0;
585 }
586}
587
588int
589rip_if_down(struct interface *ifp)
590{
591 struct route_node *rp;
592 struct rip_info *rinfo;
593 struct rip_interface *ri = NULL;
594 if (rip)
595 {
596 for (rp = route_top (rip->table); rp; rp = route_next (rp))
597 if ((rinfo = rp->info) != NULL)
598 {
599 /* Routes got through this interface. */
600 if (rinfo->ifindex == ifp->ifindex &&
601 rinfo->type == ZEBRA_ROUTE_RIP &&
602 rinfo->sub_type == RIP_ROUTE_RTE)
603 {
604 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
605 &rinfo->nexthop,
606 rinfo->ifindex);
607
608 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
609 (struct prefix_ipv4 *)&rp->p,
610 rinfo->ifindex);
611 }
612 else
613 {
614 /* All redistributed routes but static and system */
615 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000616 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000617 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
618 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
619 (struct prefix_ipv4 *)&rp->p,
620 rinfo->ifindex);
621 }
622 }
623 }
624
625 ri = ifp->info;
626
627 if (ri->running)
628 {
629 if (IS_RIP_DEBUG_EVENT)
630 zlog_info ("turn off %s", ifp->name);
631
632 /* Leave from multicast group. */
633 rip_multicast_leave (ifp, rip->sock);
634
635 ri->running = 0;
636 }
637
638 return 0;
639}
640
641/* Needed for stop RIP process. */
642void
643rip_if_down_all ()
644{
645 struct interface *ifp;
646 listnode node;
647
648 for (node = listhead (iflist); node; nextnode (node))
649 {
650 ifp = getdata (node);
651 rip_if_down (ifp);
652 }
653}
654
hasso16705132003-05-25 14:49:19 +0000655static void
656rip_apply_address_add (struct connected *ifc) {
657 struct prefix_ipv4 address;
658 struct prefix *p;
659
660 if (!rip)
661 return;
662
663 if (! if_is_up(ifc->ifp))
664 return;
665
666 p = ifc->address;
667
668 memset (&address, 0, sizeof (address));
669 address.family = p->family;
670 address.prefix = p->u.prefix4;
671 address.prefixlen = p->prefixlen;
672 apply_mask_ipv4(&address);
673
674 /* Check if this interface is RIP enabled or not
675 or Check if this address's prefix is RIP enabled */
676 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
677 (rip_enable_network_lookup2(ifc) >= 0))
678 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
679 &address, ifc->ifp->ifindex, NULL);
680
681}
682
paul718e3742002-12-13 20:15:29 +0000683int
684rip_interface_address_add (int command, struct zclient *zclient,
685 zebra_size_t length)
686{
687 struct connected *ifc;
688 struct prefix *p;
689
690 ifc = zebra_interface_address_add_read (zclient->ibuf);
691
692 if (ifc == NULL)
693 return 0;
694
695 p = ifc->address;
696
697 if (p->family == AF_INET)
698 {
699 if (IS_RIP_DEBUG_ZEBRA)
700 zlog_info ("connected address %s/%d is added",
701 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000702
703 /* Check if this prefix needs to be redistributed */
704 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000705
706#ifdef HAVE_SNMP
707 rip_ifaddr_add (ifc->ifp, ifc);
708#endif /* HAVE_SNMP */
709 }
710
711 return 0;
712}
713
hasso16705132003-05-25 14:49:19 +0000714static void
715rip_apply_address_del (struct connected *ifc) {
716 struct prefix_ipv4 address;
717 struct prefix *p;
718
719 if (!rip)
720 return;
721
722 if (! if_is_up(ifc->ifp))
723 return;
724
725 p = ifc->address;
726
727 memset (&address, 0, sizeof (address));
728 address.family = p->family;
729 address.prefix = p->u.prefix4;
730 address.prefixlen = p->prefixlen;
731 apply_mask_ipv4(&address);
732
733 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
734 &address, ifc->ifp->ifindex);
735}
736
paul718e3742002-12-13 20:15:29 +0000737int
738rip_interface_address_delete (int command, struct zclient *zclient,
739 zebra_size_t length)
740{
741 struct connected *ifc;
742 struct prefix *p;
743
744 ifc = zebra_interface_address_delete_read (zclient->ibuf);
745
746 if (ifc)
747 {
748 p = ifc->address;
749 if (p->family == AF_INET)
750 {
751 if (IS_RIP_DEBUG_ZEBRA)
752
753 zlog_info ("connected address %s/%d is deleted",
754 inet_ntoa (p->u.prefix4), p->prefixlen);
755
756#ifdef HAVE_SNMP
757 rip_ifaddr_delete (ifc->ifp, ifc);
758#endif /* HAVE_SNMP */
759
hasso16705132003-05-25 14:49:19 +0000760 /* Chech wether this prefix needs to be removed */
761 rip_apply_address_del(ifc);
762
paul718e3742002-12-13 20:15:29 +0000763 }
764
765 connected_free (ifc);
766
767 }
768
769 return 0;
770}
771
772/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000773/* Check wether the interface has at least a connected prefix that
774 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000775int
hasso16705132003-05-25 14:49:19 +0000776rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000777{
778 struct listnode *nn;
779 struct connected *connected;
780 struct prefix_ipv4 address;
781
782 for (nn = listhead (ifp->connected); nn; nextnode (nn))
783 if ((connected = getdata (nn)) != NULL)
784 {
785 struct prefix *p;
786 struct route_node *node;
787
788 p = connected->address;
789
790 if (p->family == AF_INET)
791 {
792 address.family = AF_INET;
793 address.prefix = p->u.prefix4;
794 address.prefixlen = IPV4_MAX_BITLEN;
795
796 node = route_node_match (rip_enable_network,
797 (struct prefix *)&address);
798 if (node)
799 {
800 route_unlock_node (node);
801 return 1;
802 }
803 }
804 }
805 return -1;
806}
807
hasso16705132003-05-25 14:49:19 +0000808/* Check wether connected is within the ripng_enable_network table. */
809int
810rip_enable_network_lookup2 (struct connected *connected)
811{
812 struct prefix_ipv4 address;
813 struct prefix *p;
814
815 p = connected->address;
816
817 if (p->family == AF_INET) {
818 struct route_node *node;
819
820 address.family = p->family;
821 address.prefix = p->u.prefix4;
822 address.prefixlen = IPV4_MAX_BITLEN;
823
824 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
825 node = route_node_match (rip_enable_network,
826 (struct prefix *)&address);
827
828 if (node) {
829 route_unlock_node (node);
830 return 1;
831 }
832 }
833
834 return -1;
835}
paul718e3742002-12-13 20:15:29 +0000836/* Add RIP enable network. */
837int
838rip_enable_network_add (struct prefix *p)
839{
840 struct route_node *node;
841
842 node = route_node_get (rip_enable_network, p);
843
844 if (node->info)
845 {
846 route_unlock_node (node);
847 return -1;
848 }
849 else
850 node->info = "enabled";
851
hasso16705132003-05-25 14:49:19 +0000852 /* XXX: One should find a better solution than a generic one */
853 rip_enable_apply_all();
854
paul718e3742002-12-13 20:15:29 +0000855 return 1;
856}
857
858/* Delete RIP enable network. */
859int
860rip_enable_network_delete (struct prefix *p)
861{
862 struct route_node *node;
863
864 node = route_node_lookup (rip_enable_network, p);
865 if (node)
866 {
867 node->info = NULL;
868
869 /* Unlock info lock. */
870 route_unlock_node (node);
871
872 /* Unlock lookup lock. */
873 route_unlock_node (node);
874
hasso16705132003-05-25 14:49:19 +0000875 /* XXX: One should find a better solution than a generic one */
876 rip_enable_apply_all ();
877
paul718e3742002-12-13 20:15:29 +0000878 return 1;
879 }
880 return -1;
881}
882
883/* Check interface is enabled by ifname statement. */
884int
885rip_enable_if_lookup (char *ifname)
886{
887 int i;
888 char *str;
889
890 for (i = 0; i < vector_max (rip_enable_interface); i++)
891 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
892 if (strcmp (str, ifname) == 0)
893 return i;
894 return -1;
895}
896
897/* Add interface to rip_enable_if. */
898int
899rip_enable_if_add (char *ifname)
900{
901 int ret;
902
903 ret = rip_enable_if_lookup (ifname);
904 if (ret >= 0)
905 return -1;
906
907 vector_set (rip_enable_interface, strdup (ifname));
908
hasso16705132003-05-25 14:49:19 +0000909 rip_enable_apply_all(); /* TODOVJ */
910
paul718e3742002-12-13 20:15:29 +0000911 return 1;
912}
913
914/* Delete interface from rip_enable_if. */
915int
916rip_enable_if_delete (char *ifname)
917{
918 int index;
919 char *str;
920
921 index = rip_enable_if_lookup (ifname);
922 if (index < 0)
923 return -1;
924
925 str = vector_slot (rip_enable_interface, index);
926 free (str);
927 vector_unset (rip_enable_interface, index);
928
hasso16705132003-05-25 14:49:19 +0000929 rip_enable_apply_all(); /* TODOVJ */
930
paul718e3742002-12-13 20:15:29 +0000931 return 1;
932}
933
934/* Join to multicast group and send request to the interface. */
935int
936rip_interface_wakeup (struct thread *t)
937{
938 struct interface *ifp;
939 struct rip_interface *ri;
940
941 /* Get interface. */
942 ifp = THREAD_ARG (t);
943
944 ri = ifp->info;
945 ri->t_wakeup = NULL;
946
947 /* Join to multicast group. */
948 if (rip_multicast_join (ifp, rip->sock) < 0)
949 {
950 zlog_err ("multicast join failed, interface %s not running", ifp->name);
951 return 0;
952 }
953
954 /* Set running flag. */
955 ri->running = 1;
956
957 /* Send RIP request to the interface. */
958 rip_request_interface (ifp);
959
960 return 0;
961}
962
963int rip_redistribute_check (int);
964
965void
966rip_connect_set (struct interface *ifp, int set)
967{
968 struct listnode *nn;
969 struct connected *connected;
970 struct prefix_ipv4 address;
971
972 for (nn = listhead (ifp->connected); nn; nextnode (nn))
973 if ((connected = getdata (nn)) != NULL)
974 {
975 struct prefix *p;
976 p = connected->address;
977
978 if (p->family != AF_INET)
979 continue;
980
981 address.family = AF_INET;
982 address.prefix = p->u.prefix4;
983 address.prefixlen = p->prefixlen;
984 apply_mask_ipv4 (&address);
985
hasso16705132003-05-25 14:49:19 +0000986 if (set) {
987 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
988 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
989 (rip_enable_network_lookup2(connected) >= 0))
990 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
991 &address, connected->ifp->ifindex, NULL);
992 } else
paul718e3742002-12-13 20:15:29 +0000993 {
994 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
995 &address, connected->ifp->ifindex);
996 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
997 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
998 &address, connected->ifp->ifindex, NULL);
999 }
1000 }
1001}
1002
1003/* Update interface status. */
1004void
1005rip_enable_apply (struct interface *ifp)
1006{
1007 int ret;
1008 struct rip_interface *ri = NULL;
1009
1010 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001011 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001012 return;
1013
1014 ri = ifp->info;
1015
1016 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001017 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001018
1019 /* If the interface is matched. */
1020 if (ret > 0)
1021 ri->enable_network = 1;
1022 else
1023 ri->enable_network = 0;
1024
1025 /* Check interface name configuration. */
1026 ret = rip_enable_if_lookup (ifp->name);
1027 if (ret >= 0)
1028 ri->enable_interface = 1;
1029 else
1030 ri->enable_interface = 0;
1031
1032 /* any interface MUST have an IPv4 address */
1033 if ( ! rip_if_ipv4_address_check (ifp) )
1034 {
1035 ri->enable_network = 0;
1036 ri->enable_interface = 0;
1037 }
1038
1039 /* Update running status of the interface. */
1040 if (ri->enable_network || ri->enable_interface)
1041 {
paul718e3742002-12-13 20:15:29 +00001042 {
1043 if (IS_RIP_DEBUG_EVENT)
1044 zlog_info ("turn on %s", ifp->name);
1045
1046 /* Add interface wake up thread. */
1047 if (! ri->t_wakeup)
1048 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1049 ifp, 1);
1050 rip_connect_set (ifp, 1);
1051 }
1052 }
1053 else
1054 {
1055 if (ri->running)
1056 {
hasso16705132003-05-25 14:49:19 +00001057 /* Might as well clean up the route table as well
1058 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1059 **/
paul718e3742002-12-13 20:15:29 +00001060 rip_if_down(ifp);
1061
paul718e3742002-12-13 20:15:29 +00001062 rip_connect_set (ifp, 0);
1063 }
1064 }
1065}
1066
1067/* Apply network configuration to all interface. */
1068void
1069rip_enable_apply_all ()
1070{
1071 struct interface *ifp;
1072 listnode node;
1073
1074 /* Check each interface. */
1075 for (node = listhead (iflist); node; nextnode (node))
1076 {
1077 ifp = getdata (node);
1078 rip_enable_apply (ifp);
1079 }
1080}
1081
1082int
1083rip_neighbor_lookup (struct sockaddr_in *from)
1084{
1085 struct prefix_ipv4 p;
1086 struct route_node *node;
1087
1088 memset (&p, 0, sizeof (struct prefix_ipv4));
1089 p.family = AF_INET;
1090 p.prefix = from->sin_addr;
1091 p.prefixlen = IPV4_MAX_BITLEN;
1092
1093 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1094 if (node)
1095 {
1096 route_unlock_node (node);
1097 return 1;
1098 }
1099 return 0;
1100}
1101
1102/* Add new RIP neighbor to the neighbor tree. */
1103int
1104rip_neighbor_add (struct prefix_ipv4 *p)
1105{
1106 struct route_node *node;
1107
1108 node = route_node_get (rip->neighbor, (struct prefix *) p);
1109
1110 if (node->info)
1111 return -1;
1112
1113 node->info = rip->neighbor;
1114
1115 return 0;
1116}
1117
1118/* Delete RIP neighbor from the neighbor tree. */
1119int
1120rip_neighbor_delete (struct prefix_ipv4 *p)
1121{
1122 struct route_node *node;
1123
1124 /* Lock for look up. */
1125 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1126 if (! node)
1127 return -1;
1128
1129 node->info = NULL;
1130
1131 /* Unlock lookup lock. */
1132 route_unlock_node (node);
1133
1134 /* Unlock real neighbor information lock. */
1135 route_unlock_node (node);
1136
1137 return 0;
1138}
1139
1140/* Clear all network and neighbor configuration. */
1141void
1142rip_clean_network ()
1143{
1144 int i;
1145 char *str;
1146 struct route_node *rn;
1147
1148 /* rip_enable_network. */
1149 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1150 if (rn->info)
1151 {
1152 rn->info = NULL;
1153 route_unlock_node (rn);
1154 }
1155
1156 /* rip_enable_interface. */
1157 for (i = 0; i < vector_max (rip_enable_interface); i++)
1158 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1159 {
1160 free (str);
1161 vector_slot (rip_enable_interface, i) = NULL;
1162 }
1163}
1164
1165/* Utility function for looking up passive interface settings. */
1166int
paul4aaff3f2003-06-07 01:04:45 +00001167rip_passive_nondefault_lookup (char *ifname)
paul718e3742002-12-13 20:15:29 +00001168{
1169 int i;
1170 char *str;
1171
paul4aaff3f2003-06-07 01:04:45 +00001172 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1173 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001174 if (strcmp (str, ifname) == 0)
1175 return i;
1176 return -1;
1177}
1178
1179void
1180rip_passive_interface_apply (struct interface *ifp)
1181{
paul718e3742002-12-13 20:15:29 +00001182 struct rip_interface *ri;
1183
1184 ri = ifp->info;
1185
paul4aaff3f2003-06-07 01:04:45 +00001186 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1187 passive_default : !passive_default);
1188
1189 if (IS_RIP_DEBUG_ZEBRA)
1190 zlog_info ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001191}
1192
1193void
1194rip_passive_interface_apply_all ()
1195{
1196 struct interface *ifp;
1197 listnode node;
1198
1199 for (node = listhead (iflist); node; nextnode (node))
1200 {
1201 ifp = getdata (node);
1202 rip_passive_interface_apply (ifp);
1203 }
1204}
1205
1206/* Passive interface. */
1207int
paul4aaff3f2003-06-07 01:04:45 +00001208rip_passive_nondefault_set (struct vty *vty, char *ifname)
paul718e3742002-12-13 20:15:29 +00001209{
paul4aaff3f2003-06-07 01:04:45 +00001210 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001211 return CMD_WARNING;
1212
paul4aaff3f2003-06-07 01:04:45 +00001213 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001214
1215 rip_passive_interface_apply_all ();
1216
1217 return CMD_SUCCESS;
1218}
1219
1220int
paul4aaff3f2003-06-07 01:04:45 +00001221rip_passive_nondefault_unset (struct vty *vty, char *ifname)
paul718e3742002-12-13 20:15:29 +00001222{
1223 int i;
1224 char *str;
1225
paul4aaff3f2003-06-07 01:04:45 +00001226 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001227 if (i < 0)
1228 return CMD_WARNING;
1229
paul4aaff3f2003-06-07 01:04:45 +00001230 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001231 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001232 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001233
1234 rip_passive_interface_apply_all ();
1235
1236 return CMD_SUCCESS;
1237}
1238
1239/* Free all configured RIP passive-interface settings. */
1240void
paul4aaff3f2003-06-07 01:04:45 +00001241rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001242{
1243 int i;
1244 char *str;
1245
paul4aaff3f2003-06-07 01:04:45 +00001246 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1247 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001248 {
1249 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001250 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001251 }
1252 rip_passive_interface_apply_all ();
1253}
1254
1255/* RIP enable network or interface configuration. */
1256DEFUN (rip_network,
1257 rip_network_cmd,
1258 "network (A.B.C.D/M|WORD)",
1259 "Enable routing on an IP network\n"
1260 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1261 "Interface name\n")
1262{
1263 int ret;
1264 struct prefix_ipv4 p;
1265
1266 ret = str2prefix_ipv4 (argv[0], &p);
1267
1268 if (ret)
1269 ret = rip_enable_network_add ((struct prefix *) &p);
1270 else
1271 ret = rip_enable_if_add (argv[0]);
1272
1273 if (ret < 0)
1274 {
1275 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1276 VTY_NEWLINE);
1277 return CMD_WARNING;
1278 }
1279
paul718e3742002-12-13 20:15:29 +00001280 return CMD_SUCCESS;
1281}
1282
1283/* RIP enable network or interface configuration. */
1284DEFUN (no_rip_network,
1285 no_rip_network_cmd,
1286 "no network (A.B.C.D/M|WORD)",
1287 NO_STR
1288 "Enable routing on an IP network\n"
1289 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1290 "Interface name\n")
1291{
1292 int ret;
1293 struct prefix_ipv4 p;
1294
1295 ret = str2prefix_ipv4 (argv[0], &p);
1296
1297 if (ret)
1298 ret = rip_enable_network_delete ((struct prefix *) &p);
1299 else
1300 ret = rip_enable_if_delete (argv[0]);
1301
1302 if (ret < 0)
1303 {
1304 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1305 VTY_NEWLINE);
1306 return CMD_WARNING;
1307 }
1308
paul718e3742002-12-13 20:15:29 +00001309 return CMD_SUCCESS;
1310}
1311
1312/* RIP neighbor configuration set. */
1313DEFUN (rip_neighbor,
1314 rip_neighbor_cmd,
1315 "neighbor A.B.C.D",
1316 "Specify a neighbor router\n"
1317 "Neighbor address\n")
1318{
1319 int ret;
1320 struct prefix_ipv4 p;
1321
1322 ret = str2prefix_ipv4 (argv[0], &p);
1323
1324 if (ret <= 0)
1325 {
1326 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1327 return CMD_WARNING;
1328 }
1329
1330 rip_neighbor_add (&p);
1331
1332 return CMD_SUCCESS;
1333}
1334
1335/* RIP neighbor configuration unset. */
1336DEFUN (no_rip_neighbor,
1337 no_rip_neighbor_cmd,
1338 "no neighbor A.B.C.D",
1339 NO_STR
1340 "Specify a neighbor router\n"
1341 "Neighbor address\n")
1342{
1343 int ret;
1344 struct prefix_ipv4 p;
1345
1346 ret = str2prefix_ipv4 (argv[0], &p);
1347
1348 if (ret <= 0)
1349 {
1350 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1351 return CMD_WARNING;
1352 }
1353
1354 rip_neighbor_delete (&p);
1355
1356 return CMD_SUCCESS;
1357}
1358
1359DEFUN (ip_rip_receive_version,
1360 ip_rip_receive_version_cmd,
1361 "ip rip receive version (1|2)",
1362 IP_STR
1363 "Routing Information Protocol\n"
1364 "Advertisement reception\n"
1365 "Version control\n"
1366 "RIP version 1\n"
1367 "RIP version 2\n")
1368{
1369 struct interface *ifp;
1370 struct rip_interface *ri;
1371
1372 ifp = (struct interface *)vty->index;
1373 ri = ifp->info;
1374
1375 /* Version 1. */
1376 if (atoi (argv[0]) == 1)
1377 {
1378 ri->ri_receive = RI_RIP_VERSION_1;
1379 return CMD_SUCCESS;
1380 }
1381 if (atoi (argv[0]) == 2)
1382 {
1383 ri->ri_receive = RI_RIP_VERSION_2;
1384 return CMD_SUCCESS;
1385 }
1386 return CMD_WARNING;
1387}
1388
1389DEFUN (ip_rip_receive_version_1,
1390 ip_rip_receive_version_1_cmd,
1391 "ip rip receive version 1 2",
1392 IP_STR
1393 "Routing Information Protocol\n"
1394 "Advertisement reception\n"
1395 "Version control\n"
1396 "RIP version 1\n"
1397 "RIP version 2\n")
1398{
1399 struct interface *ifp;
1400 struct rip_interface *ri;
1401
1402 ifp = (struct interface *)vty->index;
1403 ri = ifp->info;
1404
1405 /* Version 1 and 2. */
1406 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1407 return CMD_SUCCESS;
1408}
1409
1410DEFUN (ip_rip_receive_version_2,
1411 ip_rip_receive_version_2_cmd,
1412 "ip rip receive version 2 1",
1413 IP_STR
1414 "Routing Information Protocol\n"
1415 "Advertisement reception\n"
1416 "Version control\n"
1417 "RIP version 2\n"
1418 "RIP version 1\n")
1419{
1420 struct interface *ifp;
1421 struct rip_interface *ri;
1422
1423 ifp = (struct interface *)vty->index;
1424 ri = ifp->info;
1425
1426 /* Version 1 and 2. */
1427 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1428 return CMD_SUCCESS;
1429}
1430
1431DEFUN (no_ip_rip_receive_version,
1432 no_ip_rip_receive_version_cmd,
1433 "no ip rip receive version",
1434 NO_STR
1435 IP_STR
1436 "Routing Information Protocol\n"
1437 "Advertisement reception\n"
1438 "Version control\n")
1439{
1440 struct interface *ifp;
1441 struct rip_interface *ri;
1442
1443 ifp = (struct interface *)vty->index;
1444 ri = ifp->info;
1445
1446 ri->ri_receive = RI_RIP_UNSPEC;
1447 return CMD_SUCCESS;
1448}
1449
1450ALIAS (no_ip_rip_receive_version,
1451 no_ip_rip_receive_version_num_cmd,
1452 "no ip rip receive version (1|2)",
1453 NO_STR
1454 IP_STR
1455 "Routing Information Protocol\n"
1456 "Advertisement reception\n"
1457 "Version control\n"
1458 "Version 1\n"
1459 "Version 2\n")
1460
1461DEFUN (ip_rip_send_version,
1462 ip_rip_send_version_cmd,
1463 "ip rip send version (1|2)",
1464 IP_STR
1465 "Routing Information Protocol\n"
1466 "Advertisement transmission\n"
1467 "Version control\n"
1468 "RIP version 1\n"
1469 "RIP version 2\n")
1470{
1471 struct interface *ifp;
1472 struct rip_interface *ri;
1473
1474 ifp = (struct interface *)vty->index;
1475 ri = ifp->info;
1476
1477 /* Version 1. */
1478 if (atoi (argv[0]) == 1)
1479 {
1480 ri->ri_send = RI_RIP_VERSION_1;
1481 return CMD_SUCCESS;
1482 }
1483 if (atoi (argv[0]) == 2)
1484 {
1485 ri->ri_send = RI_RIP_VERSION_2;
1486 return CMD_SUCCESS;
1487 }
1488 return CMD_WARNING;
1489}
1490
1491DEFUN (ip_rip_send_version_1,
1492 ip_rip_send_version_1_cmd,
1493 "ip rip send version 1 2",
1494 IP_STR
1495 "Routing Information Protocol\n"
1496 "Advertisement transmission\n"
1497 "Version control\n"
1498 "RIP version 1\n"
1499 "RIP version 2\n")
1500{
1501 struct interface *ifp;
1502 struct rip_interface *ri;
1503
1504 ifp = (struct interface *)vty->index;
1505 ri = ifp->info;
1506
1507 /* Version 1 and 2. */
1508 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1509 return CMD_SUCCESS;
1510}
1511
1512DEFUN (ip_rip_send_version_2,
1513 ip_rip_send_version_2_cmd,
1514 "ip rip send version 2 1",
1515 IP_STR
1516 "Routing Information Protocol\n"
1517 "Advertisement transmission\n"
1518 "Version control\n"
1519 "RIP version 2\n"
1520 "RIP version 1\n")
1521{
1522 struct interface *ifp;
1523 struct rip_interface *ri;
1524
1525 ifp = (struct interface *)vty->index;
1526 ri = ifp->info;
1527
1528 /* Version 1 and 2. */
1529 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1530 return CMD_SUCCESS;
1531}
1532
1533DEFUN (no_ip_rip_send_version,
1534 no_ip_rip_send_version_cmd,
1535 "no ip rip send version",
1536 NO_STR
1537 IP_STR
1538 "Routing Information Protocol\n"
1539 "Advertisement transmission\n"
1540 "Version control\n")
1541{
1542 struct interface *ifp;
1543 struct rip_interface *ri;
1544
1545 ifp = (struct interface *)vty->index;
1546 ri = ifp->info;
1547
1548 ri->ri_send = RI_RIP_UNSPEC;
1549 return CMD_SUCCESS;
1550}
1551
1552ALIAS (no_ip_rip_send_version,
1553 no_ip_rip_send_version_num_cmd,
1554 "no ip rip send version (1|2)",
1555 NO_STR
1556 IP_STR
1557 "Routing Information Protocol\n"
1558 "Advertisement transmission\n"
1559 "Version control\n"
1560 "Version 1\n"
1561 "Version 2\n")
1562
1563DEFUN (ip_rip_authentication_mode,
1564 ip_rip_authentication_mode_cmd,
1565 "ip rip authentication mode (md5|text)",
1566 IP_STR
1567 "Routing Information Protocol\n"
1568 "Authentication control\n"
1569 "Authentication mode\n"
1570 "Keyed message digest\n"
1571 "Clear text authentication\n")
1572{
1573 struct interface *ifp;
1574 struct rip_interface *ri;
1575
1576 ifp = (struct interface *)vty->index;
1577 ri = ifp->info;
1578
1579 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1580 ri->auth_type = RIP_AUTH_MD5;
1581 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1582 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1583 else
1584 {
1585 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1586 return CMD_WARNING;
1587 }
1588
1589 return CMD_SUCCESS;
1590}
1591
1592DEFUN (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
1607 /* ri->auth_type = RIP_NO_AUTH; */
1608 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1609
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
1624DEFUN (ip_rip_authentication_string,
1625 ip_rip_authentication_string_cmd,
1626 "ip rip authentication string LINE",
1627 IP_STR
1628 "Routing Information Protocol\n"
1629 "Authentication control\n"
1630 "Authentication string\n"
1631 "Authentication string\n")
1632{
1633 struct interface *ifp;
1634 struct rip_interface *ri;
1635
1636 ifp = (struct interface *)vty->index;
1637 ri = ifp->info;
1638
1639 if (strlen (argv[0]) > 16)
1640 {
1641 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1642 VTY_NEWLINE);
1643 return CMD_WARNING;
1644 }
1645
1646 if (ri->key_chain)
1647 {
1648 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1649 return CMD_WARNING;
1650 }
1651
1652 if (ri->auth_str)
1653 free (ri->auth_str);
1654
1655 ri->auth_str = strdup (argv[0]);
1656
1657 return CMD_SUCCESS;
1658}
1659
1660DEFUN (no_ip_rip_authentication_string,
1661 no_ip_rip_authentication_string_cmd,
1662 "no ip rip authentication string",
1663 NO_STR
1664 IP_STR
1665 "Routing Information Protocol\n"
1666 "Authentication control\n"
1667 "Authentication string\n")
1668{
1669 struct interface *ifp;
1670 struct rip_interface *ri;
1671
1672 ifp = (struct interface *)vty->index;
1673 ri = ifp->info;
1674
1675 if (ri->auth_str)
1676 free (ri->auth_str);
1677
1678 ri->auth_str = NULL;
1679
1680 return CMD_SUCCESS;
1681}
1682
1683ALIAS (no_ip_rip_authentication_string,
1684 no_ip_rip_authentication_string2_cmd,
1685 "no ip rip authentication string LINE",
1686 NO_STR
1687 IP_STR
1688 "Routing Information Protocol\n"
1689 "Authentication control\n"
1690 "Authentication string\n"
1691 "Authentication string\n")
1692
1693DEFUN (ip_rip_authentication_key_chain,
1694 ip_rip_authentication_key_chain_cmd,
1695 "ip rip authentication key-chain LINE",
1696 IP_STR
1697 "Routing Information Protocol\n"
1698 "Authentication control\n"
1699 "Authentication key-chain\n"
1700 "name of key-chain\n")
1701{
1702 struct interface *ifp;
1703 struct rip_interface *ri;
1704
1705 ifp = (struct interface *) vty->index;
1706 ri = ifp->info;
1707
1708 if (ri->auth_str)
1709 {
1710 vty_out (vty, "%% authentication string configuration exists%s",
1711 VTY_NEWLINE);
1712 return CMD_WARNING;
1713 }
1714
1715 if (ri->key_chain)
1716 free (ri->key_chain);
1717
1718 ri->key_chain = strdup (argv[0]);
1719
1720 return CMD_SUCCESS;
1721}
1722
1723DEFUN (no_ip_rip_authentication_key_chain,
1724 no_ip_rip_authentication_key_chain_cmd,
1725 "no ip rip authentication key-chain",
1726 NO_STR
1727 IP_STR
1728 "Routing Information Protocol\n"
1729 "Authentication control\n"
1730 "Authentication key-chain\n")
1731{
1732 struct interface *ifp;
1733 struct rip_interface *ri;
1734
1735 ifp = (struct interface *) vty->index;
1736 ri = ifp->info;
1737
1738 if (ri->key_chain)
1739 free (ri->key_chain);
1740
1741 ri->key_chain = NULL;
1742
1743 return CMD_SUCCESS;
1744}
1745
1746ALIAS (no_ip_rip_authentication_key_chain,
1747 no_ip_rip_authentication_key_chain2_cmd,
1748 "no ip rip authentication key-chain LINE",
1749 NO_STR
1750 IP_STR
1751 "Routing Information Protocol\n"
1752 "Authentication control\n"
1753 "Authentication key-chain\n"
1754 "name of key-chain\n")
1755
hasso16705132003-05-25 14:49:19 +00001756/* CHANGED: ip rip split-horizon
1757 Cisco and Zebra's command is
1758 ip split-horizon
1759 */
1760DEFUN (ip_rip_split_horizon,
1761 ip_rip_split_horizon_cmd,
1762 "ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001763 IP_STR
hasso16705132003-05-25 14:49:19 +00001764 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001765 "Perform split horizon\n")
1766{
1767 struct interface *ifp;
1768 struct rip_interface *ri;
1769
1770 ifp = vty->index;
1771 ri = ifp->info;
1772
hasso16705132003-05-25 14:49:19 +00001773 ri->split_horizon = RIP_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001774 return CMD_SUCCESS;
1775}
1776
hasso16705132003-05-25 14:49:19 +00001777DEFUN (ip_rip_split_horizon_poisoned_reverse,
1778 ip_rip_split_horizon_poisoned_reverse_cmd,
1779 "ip rip split-horizon poisoned-reverse",
1780 IP_STR
1781 "Routing Information Protocol\n"
1782 "Perform split horizon\n"
1783 "With poisoned-reverse\n")
1784{
1785 struct interface *ifp;
1786 struct rip_interface *ri;
1787
1788 ifp = vty->index;
1789 ri = ifp->info;
1790
1791 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1792 return CMD_SUCCESS;
1793}
1794
1795/* CHANGED: no ip rip split-horizon
1796 Cisco and Zebra's command is
1797 no ip split-horizon
1798 */
1799DEFUN (no_ip_rip_split_horizon,
1800 no_ip_rip_split_horizon_cmd,
1801 "no ip rip split-horizon",
paul718e3742002-12-13 20:15:29 +00001802 NO_STR
1803 IP_STR
hasso16705132003-05-25 14:49:19 +00001804 "Routing Information Protocol\n"
paul718e3742002-12-13 20:15:29 +00001805 "Perform split horizon\n")
1806{
1807 struct interface *ifp;
1808 struct rip_interface *ri;
1809
1810 ifp = vty->index;
1811 ri = ifp->info;
1812
hasso16705132003-05-25 14:49:19 +00001813 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +00001814 return CMD_SUCCESS;
1815}
1816
hasso16705132003-05-25 14:49:19 +00001817ALIAS (no_ip_rip_split_horizon,
1818 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1819 "no ip rip split-horizon poisoned-reverse",
1820 NO_STR
1821 IP_STR
1822 "Routing Information Protocol\n"
1823 "Perform split horizon\n"
1824 "With poisoned-reverse\n")
1825
paul718e3742002-12-13 20:15:29 +00001826DEFUN (rip_passive_interface,
1827 rip_passive_interface_cmd,
1828 "passive-interface IFNAME",
1829 "Suppress routing updates on an interface\n"
1830 "Interface name\n")
1831{
paul4aaff3f2003-06-07 01:04:45 +00001832 char *ifname = argv[0];
1833
1834 if (!strcmp(ifname,"default")) {
1835 passive_default = 1;
1836 rip_passive_nondefault_clean();
1837 return CMD_SUCCESS;
1838 }
1839 if (passive_default)
1840 return rip_passive_nondefault_unset (vty, ifname);
1841 else
1842 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001843}
1844
1845DEFUN (no_rip_passive_interface,
1846 no_rip_passive_interface_cmd,
1847 "no passive-interface IFNAME",
1848 NO_STR
1849 "Suppress routing updates on an interface\n"
1850 "Interface name\n")
1851{
paul4aaff3f2003-06-07 01:04:45 +00001852 char *ifname = argv[0];
1853
1854 if (!strcmp(ifname,"default")) {
1855 passive_default = 0;
1856 rip_passive_nondefault_clean();
1857 return CMD_SUCCESS;
1858 }
1859 if (passive_default)
1860 return rip_passive_nondefault_set (vty, ifname);
1861 else
1862 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001863}
1864
1865/* Write rip configuration of each interface. */
1866int
1867rip_interface_config_write (struct vty *vty)
1868{
1869 listnode node;
1870 struct interface *ifp;
1871
1872 for (node = listhead (iflist); node; nextnode (node))
1873 {
1874 struct rip_interface *ri;
1875
1876 ifp = getdata (node);
1877 ri = ifp->info;
1878
hasso16705132003-05-25 14:49:19 +00001879 /* Do not display the interface if there is no
1880 * configuration about it.
1881 **/
1882 if ((!ifp->desc) &&
1883 (ri->split_horizon == ri->split_horizon_default) &&
1884 (ri->ri_send == RI_RIP_UNSPEC) &&
1885 (ri->ri_receive == RI_RIP_UNSPEC) &&
1886 (ri->auth_type != RIP_AUTH_MD5) &&
1887 (!ri->auth_str) &&
1888 (!ri->key_chain) )
1889 continue;
1890
paul718e3742002-12-13 20:15:29 +00001891 vty_out (vty, "interface %s%s", ifp->name,
1892 VTY_NEWLINE);
1893
1894 if (ifp->desc)
1895 vty_out (vty, " description %s%s", ifp->desc,
1896 VTY_NEWLINE);
1897
1898 /* Split horizon. */
1899 if (ri->split_horizon != ri->split_horizon_default)
1900 {
hasso16705132003-05-25 14:49:19 +00001901 switch (ri->split_horizon) {
1902 case RIP_SPLIT_HORIZON:
1903 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1904 break;
1905 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1906 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1907 VTY_NEWLINE);
1908 break;
1909 case RIP_NO_SPLIT_HORIZON:
1910 default:
1911 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1912 break;
1913 }
paul718e3742002-12-13 20:15:29 +00001914 }
1915
1916 /* RIP version setting. */
1917 if (ri->ri_send != RI_RIP_UNSPEC)
1918 vty_out (vty, " ip rip send version %s%s",
1919 lookup (ri_version_msg, ri->ri_send),
1920 VTY_NEWLINE);
1921
1922 if (ri->ri_receive != RI_RIP_UNSPEC)
1923 vty_out (vty, " ip rip receive version %s%s",
1924 lookup (ri_version_msg, ri->ri_receive),
1925 VTY_NEWLINE);
1926
1927 /* RIP authentication. */
1928#if 0
1929 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
1930 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1931 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
1932#endif /* 0 */
1933 if (ri->auth_type == RIP_AUTH_MD5)
1934 vty_out (vty, " ip rip authentication mode md5%s", VTY_NEWLINE);
1935
1936 if (ri->auth_str)
1937 vty_out (vty, " ip rip authentication string %s%s",
1938 ri->auth_str, VTY_NEWLINE);
1939
1940 if (ri->key_chain)
1941 vty_out (vty, " ip rip authentication key-chain %s%s",
1942 ri->key_chain, VTY_NEWLINE);
1943
1944 vty_out (vty, "!%s", VTY_NEWLINE);
1945 }
1946 return 0;
1947}
1948
1949int
1950config_write_rip_network (struct vty *vty, int config_mode)
1951{
1952 int i;
1953 char *ifname;
1954 struct route_node *node;
1955
1956 /* Network type RIP enable interface statement. */
1957 for (node = route_top (rip_enable_network); node; node = route_next (node))
1958 if (node->info)
1959 vty_out (vty, "%s%s/%d%s",
1960 config_mode ? " network " : " ",
1961 inet_ntoa (node->p.u.prefix4),
1962 node->p.prefixlen,
1963 VTY_NEWLINE);
1964
1965 /* Interface name RIP enable statement. */
1966 for (i = 0; i < vector_max (rip_enable_interface); i++)
1967 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
1968 vty_out (vty, "%s%s%s",
1969 config_mode ? " network " : " ",
1970 ifname,
1971 VTY_NEWLINE);
1972
1973 /* RIP neighbors listing. */
1974 for (node = route_top (rip->neighbor); node; node = route_next (node))
1975 if (node->info)
1976 vty_out (vty, "%s%s%s",
1977 config_mode ? " neighbor " : " ",
1978 inet_ntoa (node->p.u.prefix4),
1979 VTY_NEWLINE);
1980
1981 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00001982 if (config_mode) {
1983 if (passive_default)
1984 vty_out (vty, " passive-interface default%s", ifname, VTY_NEWLINE);
1985 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1986 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
1987 vty_out (vty, " %spassive-interface %s%s",
1988 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
1989 }
paul718e3742002-12-13 20:15:29 +00001990
1991 return 0;
1992}
1993
1994struct cmd_node interface_node =
1995{
1996 INTERFACE_NODE,
1997 "%s(config-if)# ",
1998 1,
1999};
2000
2001/* Called when interface structure allocated. */
2002int
2003rip_interface_new_hook (struct interface *ifp)
2004{
2005 ifp->info = rip_interface_new ();
2006 return 0;
2007}
2008
2009/* Called when interface structure deleted. */
2010int
2011rip_interface_delete_hook (struct interface *ifp)
2012{
2013 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002014 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002015 return 0;
2016}
2017
2018/* Allocate and initialize interface vector. */
2019void
2020rip_if_init ()
2021{
2022 /* Default initial size of interface vector. */
2023 if_init();
2024 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2025 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2026
2027 /* RIP network init. */
2028 rip_enable_interface = vector_init (1);
2029 rip_enable_network = route_table_init ();
2030
2031 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002032 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002033
2034 /* Install interface node. */
2035 install_node (&interface_node, rip_interface_config_write);
2036
2037 /* Install commands. */
2038 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002039 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002040 install_default (INTERFACE_NODE);
2041 install_element (INTERFACE_NODE, &interface_desc_cmd);
2042 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2043 install_element (RIP_NODE, &rip_network_cmd);
2044 install_element (RIP_NODE, &no_rip_network_cmd);
2045 install_element (RIP_NODE, &rip_neighbor_cmd);
2046 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2047
2048 install_element (RIP_NODE, &rip_passive_interface_cmd);
2049 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2050
2051 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2052 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2053 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2054 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2055 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2056
2057 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2058 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2059 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2060 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2061 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2062
2063 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
2064 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2065 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
2066
2067 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2068 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2069 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2070
2071 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2072 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2073 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2074
hasso16705132003-05-25 14:49:19 +00002075 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2076 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2077 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2078 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002079}