blob: 3a1d81da923c8b9aea6f06b1f0bb703c7698becb [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. */
272 if (ri->ri_send == RI_RIP_UNSPEC)
273 {
274 if (rip->version == RIPv1)
275 rip_request_interface_send (ifp, RIPv1);
276 else
277 rip_request_interface_send (ifp, RIPv2);
278 }
279 /* If interface has RIP version configuration use it. */
280 else
281 {
282 if (ri->ri_send & RIPv1)
283 rip_request_interface_send (ifp, RIPv1);
284 if (ri->ri_send & RIPv2)
285 rip_request_interface_send (ifp, RIPv2);
286 }
287}
288
289/* Send RIP request to the neighbor. */
290void
291rip_request_neighbor (struct in_addr addr)
292{
293 struct sockaddr_in to;
294
295 memset (&to, 0, sizeof (struct sockaddr_in));
296 to.sin_port = htons (RIP_PORT_DEFAULT);
297 to.sin_addr = addr;
298
299 rip_request_send (&to, NULL, rip->version);
300}
301
302/* Request routes at all interfaces. */
303void
304rip_request_neighbor_all ()
305{
306 struct route_node *rp;
307
308 if (! rip)
309 return;
310
311 if (IS_RIP_DEBUG_EVENT)
312 zlog_info ("request to the all neighbor");
313
314 /* Send request to all neighbor. */
315 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
316 if (rp->info)
317 rip_request_neighbor (rp->p.u.prefix4);
318}
319
320/* Multicast packet receive socket. */
321int
322rip_multicast_join (struct interface *ifp, int sock)
323{
324 listnode cnode;
325
paul2e3b2e42002-12-13 21:03:13 +0000326 if (if_is_operative (ifp) && if_is_multicast (ifp))
paul718e3742002-12-13 20:15:29 +0000327 {
328 if (IS_RIP_DEBUG_EVENT)
329 zlog_info ("multicast join at %s", ifp->name);
330
331 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
332 {
333 struct prefix_ipv4 *p;
334 struct connected *connected;
335 struct in_addr group;
336
337 connected = getdata (cnode);
338 p = (struct prefix_ipv4 *) connected->address;
339
340 if (p->family != AF_INET)
341 continue;
342
343 group.s_addr = htonl (INADDR_RIP_GROUP);
344 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
345 return -1;
346 else
347 return 0;
348 }
349 }
350 return 0;
351}
352
353/* Leave from multicast group. */
354void
355rip_multicast_leave (struct interface *ifp, int sock)
356{
357 listnode cnode;
358
359 if (if_is_up (ifp) && if_is_multicast (ifp))
360 {
361 if (IS_RIP_DEBUG_EVENT)
362 zlog_info ("multicast leave from %s", ifp->name);
363
364 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
365 {
366 struct prefix_ipv4 *p;
367 struct connected *connected;
368 struct in_addr group;
369
370 connected = getdata (cnode);
371 p = (struct prefix_ipv4 *) connected->address;
372
373 if (p->family != AF_INET)
374 continue;
375
376 group.s_addr = htonl (INADDR_RIP_GROUP);
377 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
378 return;
379 }
380 }
381}
382
383/* Is there and address on interface that I could use ? */
384int
385rip_if_ipv4_address_check (struct interface *ifp)
386{
387 struct listnode *nn;
388 struct connected *connected;
389 int count = 0;
390
391 for (nn = listhead (ifp->connected); nn; nextnode (nn))
392 if ((connected = getdata (nn)) != NULL)
393 {
394 struct prefix *p;
395
396 p = connected->address;
397
398 if (p->family == AF_INET)
399 {
400 count++;
401 }
402 }
403
404 return count;
405}
paul718e3742002-12-13 20:15:29 +0000406
407/* Inteface link down message processing. */
408int
409rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
410{
411 struct interface *ifp;
412 struct stream *s;
413
414 s = zclient->ibuf;
415
416 /* zebra_interface_state_read() updates interface structure in
417 iflist. */
418 ifp = zebra_interface_state_read(s);
419
420 if (ifp == NULL)
421 return 0;
422
423 rip_if_down(ifp);
424
425 if (IS_RIP_DEBUG_ZEBRA)
426 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is down",
427 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
428
429 return 0;
430}
431
432/* Inteface link up message processing */
433int
434rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
435{
436 struct interface *ifp;
437
438 /* zebra_interface_state_read () updates interface structure in
439 iflist. */
440 ifp = zebra_interface_state_read (zclient->ibuf);
441
442 if (ifp == NULL)
443 return 0;
444
445 if (IS_RIP_DEBUG_ZEBRA)
446 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is up",
447 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
448
449 /* Check if this interface is RIP enabled or not.*/
450 rip_enable_apply (ifp);
451
452 /* Check for a passive interface */
453 rip_passive_interface_apply (ifp);
454
455 /* Apply distribute list to the all interface. */
456 rip_distribute_update_interface (ifp);
457
458 return 0;
459}
460
461/* Inteface addition message from zebra. */
462int
463rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
464{
465 struct interface *ifp;
466
467 ifp = zebra_interface_add_read (zclient->ibuf);
468
469 if (IS_RIP_DEBUG_ZEBRA)
470 zlog_info ("interface add %s index %d flags %ld metric %d mtu %d",
471 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
472
473 /* Check if this interface is RIP enabled or not.*/
474 rip_enable_apply (ifp);
475
476 /* Apply distribute list to the all interface. */
477 rip_distribute_update_interface (ifp);
478
479 /* rip_request_neighbor_all (); */
480
hasso16705132003-05-25 14:49:19 +0000481 /* Check interface routemap. */
482 rip_if_rmap_update_interface (ifp);
483
paul718e3742002-12-13 20:15:29 +0000484 return 0;
485}
486
487int
488rip_interface_delete (int command, struct zclient *zclient,
489 zebra_size_t length)
490{
491 struct interface *ifp;
492 struct stream *s;
493
494
495 s = zclient->ibuf;
496 /* zebra_interface_state_read() updates interface structure in iflist */
497 ifp = zebra_interface_state_read(s);
498
499 if (ifp == NULL)
500 return 0;
501
502 if (if_is_up (ifp)) {
503 rip_if_down(ifp);
504 }
505
506 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
507 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
508
509 /* To support pseudo interface do not free interface structure. */
510 /* if_delete(ifp); */
511
512 return 0;
513}
514
515void
516rip_interface_clean ()
517{
518 listnode node;
519 struct interface *ifp;
520 struct rip_interface *ri;
521
522 for (node = listhead (iflist); node; nextnode (node))
523 {
524 ifp = getdata (node);
525 ri = ifp->info;
526
527 ri->enable_network = 0;
528 ri->enable_interface = 0;
529 ri->running = 0;
530
531 if (ri->t_wakeup)
532 {
533 thread_cancel (ri->t_wakeup);
534 ri->t_wakeup = NULL;
535 }
536 }
537}
538
539void
540rip_interface_reset ()
541{
542 listnode node;
543 struct interface *ifp;
544 struct rip_interface *ri;
545
546 for (node = listhead (iflist); node; nextnode (node))
547 {
548 ifp = getdata (node);
549 ri = ifp->info;
550
551 ri->enable_network = 0;
552 ri->enable_interface = 0;
553 ri->running = 0;
554
555 ri->ri_send = RI_RIP_UNSPEC;
556 ri->ri_receive = RI_RIP_UNSPEC;
557
558 /* ri->auth_type = RIP_NO_AUTH; */
559 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
560
561 if (ri->auth_str)
562 {
563 free (ri->auth_str);
564 ri->auth_str = NULL;
565 }
566 if (ri->key_chain)
567 {
568 free (ri->key_chain);
569 ri->key_chain = NULL;
570 }
571
hasso16705132003-05-25 14:49:19 +0000572 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
573 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
paul718e3742002-12-13 20:15:29 +0000574
575 ri->list[RIP_FILTER_IN] = NULL;
576 ri->list[RIP_FILTER_OUT] = NULL;
577
578 ri->prefix[RIP_FILTER_IN] = NULL;
579 ri->prefix[RIP_FILTER_OUT] = NULL;
580
581 if (ri->t_wakeup)
582 {
583 thread_cancel (ri->t_wakeup);
584 ri->t_wakeup = NULL;
585 }
586
587 ri->recv_badpackets = 0;
588 ri->recv_badroutes = 0;
589 ri->sent_updates = 0;
590
591 ri->passive = 0;
592 }
593}
594
595int
596rip_if_down(struct interface *ifp)
597{
598 struct route_node *rp;
599 struct rip_info *rinfo;
600 struct rip_interface *ri = NULL;
601 if (rip)
602 {
603 for (rp = route_top (rip->table); rp; rp = route_next (rp))
604 if ((rinfo = rp->info) != NULL)
605 {
606 /* Routes got through this interface. */
607 if (rinfo->ifindex == ifp->ifindex &&
608 rinfo->type == ZEBRA_ROUTE_RIP &&
609 rinfo->sub_type == RIP_ROUTE_RTE)
610 {
611 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
612 &rinfo->nexthop,
613 rinfo->ifindex);
614
615 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
616 (struct prefix_ipv4 *)&rp->p,
617 rinfo->ifindex);
618 }
619 else
620 {
621 /* All redistributed routes but static and system */
622 if ((rinfo->ifindex == ifp->ifindex) &&
paul2e3b2e42002-12-13 21:03:13 +0000623 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
paul718e3742002-12-13 20:15:29 +0000624 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
625 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
626 (struct prefix_ipv4 *)&rp->p,
627 rinfo->ifindex);
628 }
629 }
630 }
631
632 ri = ifp->info;
633
634 if (ri->running)
635 {
636 if (IS_RIP_DEBUG_EVENT)
637 zlog_info ("turn off %s", ifp->name);
638
639 /* Leave from multicast group. */
640 rip_multicast_leave (ifp, rip->sock);
641
642 ri->running = 0;
643 }
644
645 return 0;
646}
647
648/* Needed for stop RIP process. */
649void
650rip_if_down_all ()
651{
652 struct interface *ifp;
653 listnode node;
654
655 for (node = listhead (iflist); node; nextnode (node))
656 {
657 ifp = getdata (node);
658 rip_if_down (ifp);
659 }
660}
661
hasso16705132003-05-25 14:49:19 +0000662static void
663rip_apply_address_add (struct connected *ifc) {
664 struct prefix_ipv4 address;
665 struct prefix *p;
666
667 if (!rip)
668 return;
669
670 if (! if_is_up(ifc->ifp))
671 return;
672
673 p = ifc->address;
674
675 memset (&address, 0, sizeof (address));
676 address.family = p->family;
677 address.prefix = p->u.prefix4;
678 address.prefixlen = p->prefixlen;
679 apply_mask_ipv4(&address);
680
681 /* Check if this interface is RIP enabled or not
682 or Check if this address's prefix is RIP enabled */
683 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
684 (rip_enable_network_lookup2(ifc) >= 0))
685 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
686 &address, ifc->ifp->ifindex, NULL);
687
688}
689
paul718e3742002-12-13 20:15:29 +0000690int
691rip_interface_address_add (int command, struct zclient *zclient,
692 zebra_size_t length)
693{
694 struct connected *ifc;
695 struct prefix *p;
696
697 ifc = zebra_interface_address_add_read (zclient->ibuf);
698
699 if (ifc == NULL)
700 return 0;
701
702 p = ifc->address;
703
704 if (p->family == AF_INET)
705 {
706 if (IS_RIP_DEBUG_ZEBRA)
707 zlog_info ("connected address %s/%d is added",
708 inet_ntoa (p->u.prefix4), p->prefixlen);
hasso16705132003-05-25 14:49:19 +0000709
710 /* Check if this prefix needs to be redistributed */
711 rip_apply_address_add(ifc);
paul718e3742002-12-13 20:15:29 +0000712
713#ifdef HAVE_SNMP
714 rip_ifaddr_add (ifc->ifp, ifc);
715#endif /* HAVE_SNMP */
716 }
717
718 return 0;
719}
720
hasso16705132003-05-25 14:49:19 +0000721static void
722rip_apply_address_del (struct connected *ifc) {
723 struct prefix_ipv4 address;
724 struct prefix *p;
725
726 if (!rip)
727 return;
728
729 if (! if_is_up(ifc->ifp))
730 return;
731
732 p = ifc->address;
733
734 memset (&address, 0, sizeof (address));
735 address.family = p->family;
736 address.prefix = p->u.prefix4;
737 address.prefixlen = p->prefixlen;
738 apply_mask_ipv4(&address);
739
740 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
741 &address, ifc->ifp->ifindex);
742}
743
paul718e3742002-12-13 20:15:29 +0000744int
745rip_interface_address_delete (int command, struct zclient *zclient,
746 zebra_size_t length)
747{
748 struct connected *ifc;
749 struct prefix *p;
750
751 ifc = zebra_interface_address_delete_read (zclient->ibuf);
752
753 if (ifc)
754 {
755 p = ifc->address;
756 if (p->family == AF_INET)
757 {
758 if (IS_RIP_DEBUG_ZEBRA)
759
760 zlog_info ("connected address %s/%d is deleted",
761 inet_ntoa (p->u.prefix4), p->prefixlen);
762
763#ifdef HAVE_SNMP
764 rip_ifaddr_delete (ifc->ifp, ifc);
765#endif /* HAVE_SNMP */
766
hasso16705132003-05-25 14:49:19 +0000767 /* Chech wether this prefix needs to be removed */
768 rip_apply_address_del(ifc);
769
paul718e3742002-12-13 20:15:29 +0000770 }
771
772 connected_free (ifc);
773
774 }
775
776 return 0;
777}
778
779/* Check interface is enabled by network statement. */
hasso16705132003-05-25 14:49:19 +0000780/* Check wether the interface has at least a connected prefix that
781 * is within the ripng_enable_network table. */
paul718e3742002-12-13 20:15:29 +0000782int
hasso16705132003-05-25 14:49:19 +0000783rip_enable_network_lookup_if (struct interface *ifp)
paul718e3742002-12-13 20:15:29 +0000784{
785 struct listnode *nn;
786 struct connected *connected;
787 struct prefix_ipv4 address;
788
789 for (nn = listhead (ifp->connected); nn; nextnode (nn))
790 if ((connected = getdata (nn)) != NULL)
791 {
792 struct prefix *p;
793 struct route_node *node;
794
795 p = connected->address;
796
797 if (p->family == AF_INET)
798 {
799 address.family = AF_INET;
800 address.prefix = p->u.prefix4;
801 address.prefixlen = IPV4_MAX_BITLEN;
802
803 node = route_node_match (rip_enable_network,
804 (struct prefix *)&address);
805 if (node)
806 {
807 route_unlock_node (node);
808 return 1;
809 }
810 }
811 }
812 return -1;
813}
814
hasso16705132003-05-25 14:49:19 +0000815/* Check wether connected is within the ripng_enable_network table. */
816int
817rip_enable_network_lookup2 (struct connected *connected)
818{
819 struct prefix_ipv4 address;
820 struct prefix *p;
821
822 p = connected->address;
823
824 if (p->family == AF_INET) {
825 struct route_node *node;
826
827 address.family = p->family;
828 address.prefix = p->u.prefix4;
829 address.prefixlen = IPV4_MAX_BITLEN;
830
831 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
832 node = route_node_match (rip_enable_network,
833 (struct prefix *)&address);
834
835 if (node) {
836 route_unlock_node (node);
837 return 1;
838 }
839 }
840
841 return -1;
842}
paul718e3742002-12-13 20:15:29 +0000843/* Add RIP enable network. */
844int
845rip_enable_network_add (struct prefix *p)
846{
847 struct route_node *node;
848
849 node = route_node_get (rip_enable_network, p);
850
851 if (node->info)
852 {
853 route_unlock_node (node);
854 return -1;
855 }
856 else
857 node->info = "enabled";
858
hasso16705132003-05-25 14:49:19 +0000859 /* XXX: One should find a better solution than a generic one */
860 rip_enable_apply_all();
861
paul718e3742002-12-13 20:15:29 +0000862 return 1;
863}
864
865/* Delete RIP enable network. */
866int
867rip_enable_network_delete (struct prefix *p)
868{
869 struct route_node *node;
870
871 node = route_node_lookup (rip_enable_network, p);
872 if (node)
873 {
874 node->info = NULL;
875
876 /* Unlock info lock. */
877 route_unlock_node (node);
878
879 /* Unlock lookup lock. */
880 route_unlock_node (node);
881
hasso16705132003-05-25 14:49:19 +0000882 /* XXX: One should find a better solution than a generic one */
883 rip_enable_apply_all ();
884
paul718e3742002-12-13 20:15:29 +0000885 return 1;
886 }
887 return -1;
888}
889
890/* Check interface is enabled by ifname statement. */
891int
892rip_enable_if_lookup (char *ifname)
893{
894 int i;
895 char *str;
896
897 for (i = 0; i < vector_max (rip_enable_interface); i++)
898 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
899 if (strcmp (str, ifname) == 0)
900 return i;
901 return -1;
902}
903
904/* Add interface to rip_enable_if. */
905int
906rip_enable_if_add (char *ifname)
907{
908 int ret;
909
910 ret = rip_enable_if_lookup (ifname);
911 if (ret >= 0)
912 return -1;
913
914 vector_set (rip_enable_interface, strdup (ifname));
915
hasso16705132003-05-25 14:49:19 +0000916 rip_enable_apply_all(); /* TODOVJ */
917
paul718e3742002-12-13 20:15:29 +0000918 return 1;
919}
920
921/* Delete interface from rip_enable_if. */
922int
923rip_enable_if_delete (char *ifname)
924{
925 int index;
926 char *str;
927
928 index = rip_enable_if_lookup (ifname);
929 if (index < 0)
930 return -1;
931
932 str = vector_slot (rip_enable_interface, index);
933 free (str);
934 vector_unset (rip_enable_interface, index);
935
hasso16705132003-05-25 14:49:19 +0000936 rip_enable_apply_all(); /* TODOVJ */
937
paul718e3742002-12-13 20:15:29 +0000938 return 1;
939}
940
941/* Join to multicast group and send request to the interface. */
942int
943rip_interface_wakeup (struct thread *t)
944{
945 struct interface *ifp;
946 struct rip_interface *ri;
947
948 /* Get interface. */
949 ifp = THREAD_ARG (t);
950
951 ri = ifp->info;
952 ri->t_wakeup = NULL;
953
954 /* Join to multicast group. */
955 if (rip_multicast_join (ifp, rip->sock) < 0)
956 {
957 zlog_err ("multicast join failed, interface %s not running", ifp->name);
958 return 0;
959 }
960
961 /* Set running flag. */
962 ri->running = 1;
963
964 /* Send RIP request to the interface. */
965 rip_request_interface (ifp);
966
967 return 0;
968}
969
970int rip_redistribute_check (int);
971
972void
973rip_connect_set (struct interface *ifp, int set)
974{
975 struct listnode *nn;
976 struct connected *connected;
977 struct prefix_ipv4 address;
978
979 for (nn = listhead (ifp->connected); nn; nextnode (nn))
980 if ((connected = getdata (nn)) != NULL)
981 {
982 struct prefix *p;
983 p = connected->address;
984
985 if (p->family != AF_INET)
986 continue;
987
988 address.family = AF_INET;
989 address.prefix = p->u.prefix4;
990 address.prefixlen = p->prefixlen;
991 apply_mask_ipv4 (&address);
992
hasso16705132003-05-25 14:49:19 +0000993 if (set) {
994 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
995 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
996 (rip_enable_network_lookup2(connected) >= 0))
997 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
998 &address, connected->ifp->ifindex, NULL);
999 } else
paul718e3742002-12-13 20:15:29 +00001000 {
1001 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1002 &address, connected->ifp->ifindex);
1003 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1004 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1005 &address, connected->ifp->ifindex, NULL);
1006 }
1007 }
1008}
1009
1010/* Update interface status. */
1011void
1012rip_enable_apply (struct interface *ifp)
1013{
1014 int ret;
1015 struct rip_interface *ri = NULL;
1016
1017 /* Check interface. */
paul2e3b2e42002-12-13 21:03:13 +00001018 if (! if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +00001019 return;
1020
1021 ri = ifp->info;
1022
1023 /* Check network configuration. */
hasso16705132003-05-25 14:49:19 +00001024 ret = rip_enable_network_lookup_if (ifp);
paul718e3742002-12-13 20:15:29 +00001025
1026 /* If the interface is matched. */
1027 if (ret > 0)
1028 ri->enable_network = 1;
1029 else
1030 ri->enable_network = 0;
1031
1032 /* Check interface name configuration. */
1033 ret = rip_enable_if_lookup (ifp->name);
1034 if (ret >= 0)
1035 ri->enable_interface = 1;
1036 else
1037 ri->enable_interface = 0;
1038
1039 /* any interface MUST have an IPv4 address */
1040 if ( ! rip_if_ipv4_address_check (ifp) )
1041 {
1042 ri->enable_network = 0;
1043 ri->enable_interface = 0;
1044 }
1045
1046 /* Update running status of the interface. */
1047 if (ri->enable_network || ri->enable_interface)
1048 {
paul718e3742002-12-13 20:15:29 +00001049 {
1050 if (IS_RIP_DEBUG_EVENT)
1051 zlog_info ("turn on %s", ifp->name);
1052
1053 /* Add interface wake up thread. */
1054 if (! ri->t_wakeup)
1055 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1056 ifp, 1);
1057 rip_connect_set (ifp, 1);
1058 }
1059 }
1060 else
1061 {
1062 if (ri->running)
1063 {
hasso16705132003-05-25 14:49:19 +00001064 /* Might as well clean up the route table as well
1065 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1066 **/
paul718e3742002-12-13 20:15:29 +00001067 rip_if_down(ifp);
1068
paul718e3742002-12-13 20:15:29 +00001069 rip_connect_set (ifp, 0);
1070 }
1071 }
1072}
1073
1074/* Apply network configuration to all interface. */
1075void
1076rip_enable_apply_all ()
1077{
1078 struct interface *ifp;
1079 listnode node;
1080
1081 /* Check each interface. */
1082 for (node = listhead (iflist); node; nextnode (node))
1083 {
1084 ifp = getdata (node);
1085 rip_enable_apply (ifp);
1086 }
1087}
1088
1089int
1090rip_neighbor_lookup (struct sockaddr_in *from)
1091{
1092 struct prefix_ipv4 p;
1093 struct route_node *node;
1094
1095 memset (&p, 0, sizeof (struct prefix_ipv4));
1096 p.family = AF_INET;
1097 p.prefix = from->sin_addr;
1098 p.prefixlen = IPV4_MAX_BITLEN;
1099
1100 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1101 if (node)
1102 {
1103 route_unlock_node (node);
1104 return 1;
1105 }
1106 return 0;
1107}
1108
1109/* Add new RIP neighbor to the neighbor tree. */
1110int
1111rip_neighbor_add (struct prefix_ipv4 *p)
1112{
1113 struct route_node *node;
1114
1115 node = route_node_get (rip->neighbor, (struct prefix *) p);
1116
1117 if (node->info)
1118 return -1;
1119
1120 node->info = rip->neighbor;
1121
1122 return 0;
1123}
1124
1125/* Delete RIP neighbor from the neighbor tree. */
1126int
1127rip_neighbor_delete (struct prefix_ipv4 *p)
1128{
1129 struct route_node *node;
1130
1131 /* Lock for look up. */
1132 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1133 if (! node)
1134 return -1;
1135
1136 node->info = NULL;
1137
1138 /* Unlock lookup lock. */
1139 route_unlock_node (node);
1140
1141 /* Unlock real neighbor information lock. */
1142 route_unlock_node (node);
1143
1144 return 0;
1145}
1146
1147/* Clear all network and neighbor configuration. */
1148void
1149rip_clean_network ()
1150{
1151 int i;
1152 char *str;
1153 struct route_node *rn;
1154
1155 /* rip_enable_network. */
1156 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1157 if (rn->info)
1158 {
1159 rn->info = NULL;
1160 route_unlock_node (rn);
1161 }
1162
1163 /* rip_enable_interface. */
1164 for (i = 0; i < vector_max (rip_enable_interface); i++)
1165 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1166 {
1167 free (str);
1168 vector_slot (rip_enable_interface, i) = NULL;
1169 }
1170}
1171
1172/* Utility function for looking up passive interface settings. */
1173int
paul4aaff3f2003-06-07 01:04:45 +00001174rip_passive_nondefault_lookup (char *ifname)
paul718e3742002-12-13 20:15:29 +00001175{
1176 int i;
1177 char *str;
1178
paul4aaff3f2003-06-07 01:04:45 +00001179 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1180 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001181 if (strcmp (str, ifname) == 0)
1182 return i;
1183 return -1;
1184}
1185
1186void
1187rip_passive_interface_apply (struct interface *ifp)
1188{
paul718e3742002-12-13 20:15:29 +00001189 struct rip_interface *ri;
1190
1191 ri = ifp->info;
1192
paul4aaff3f2003-06-07 01:04:45 +00001193 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1194 passive_default : !passive_default);
1195
1196 if (IS_RIP_DEBUG_ZEBRA)
1197 zlog_info ("interface %s: passive = %d",ifp->name,ri->passive);
paul718e3742002-12-13 20:15:29 +00001198}
1199
1200void
1201rip_passive_interface_apply_all ()
1202{
1203 struct interface *ifp;
1204 listnode node;
1205
1206 for (node = listhead (iflist); node; nextnode (node))
1207 {
1208 ifp = getdata (node);
1209 rip_passive_interface_apply (ifp);
1210 }
1211}
1212
1213/* Passive interface. */
1214int
paul4aaff3f2003-06-07 01:04:45 +00001215rip_passive_nondefault_set (struct vty *vty, char *ifname)
paul718e3742002-12-13 20:15:29 +00001216{
paul4aaff3f2003-06-07 01:04:45 +00001217 if (rip_passive_nondefault_lookup (ifname) >= 0)
paul718e3742002-12-13 20:15:29 +00001218 return CMD_WARNING;
1219
paul4aaff3f2003-06-07 01:04:45 +00001220 vector_set (Vrip_passive_nondefault, strdup (ifname));
paul718e3742002-12-13 20:15:29 +00001221
1222 rip_passive_interface_apply_all ();
1223
1224 return CMD_SUCCESS;
1225}
1226
1227int
paul4aaff3f2003-06-07 01:04:45 +00001228rip_passive_nondefault_unset (struct vty *vty, char *ifname)
paul718e3742002-12-13 20:15:29 +00001229{
1230 int i;
1231 char *str;
1232
paul4aaff3f2003-06-07 01:04:45 +00001233 i = rip_passive_nondefault_lookup (ifname);
paul718e3742002-12-13 20:15:29 +00001234 if (i < 0)
1235 return CMD_WARNING;
1236
paul4aaff3f2003-06-07 01:04:45 +00001237 str = vector_slot (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001238 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001239 vector_unset (Vrip_passive_nondefault, i);
paul718e3742002-12-13 20:15:29 +00001240
1241 rip_passive_interface_apply_all ();
1242
1243 return CMD_SUCCESS;
1244}
1245
1246/* Free all configured RIP passive-interface settings. */
1247void
paul4aaff3f2003-06-07 01:04:45 +00001248rip_passive_nondefault_clean ()
paul718e3742002-12-13 20:15:29 +00001249{
1250 int i;
1251 char *str;
1252
paul4aaff3f2003-06-07 01:04:45 +00001253 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1254 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
paul718e3742002-12-13 20:15:29 +00001255 {
1256 free (str);
paul4aaff3f2003-06-07 01:04:45 +00001257 vector_slot (Vrip_passive_nondefault, i) = NULL;
paul718e3742002-12-13 20:15:29 +00001258 }
1259 rip_passive_interface_apply_all ();
1260}
1261
1262/* RIP enable network or interface configuration. */
1263DEFUN (rip_network,
1264 rip_network_cmd,
1265 "network (A.B.C.D/M|WORD)",
1266 "Enable routing on an IP network\n"
1267 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1268 "Interface name\n")
1269{
1270 int ret;
1271 struct prefix_ipv4 p;
1272
1273 ret = str2prefix_ipv4 (argv[0], &p);
1274
1275 if (ret)
1276 ret = rip_enable_network_add ((struct prefix *) &p);
1277 else
1278 ret = rip_enable_if_add (argv[0]);
1279
1280 if (ret < 0)
1281 {
1282 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1283 VTY_NEWLINE);
1284 return CMD_WARNING;
1285 }
1286
paul718e3742002-12-13 20:15:29 +00001287 return CMD_SUCCESS;
1288}
1289
1290/* RIP enable network or interface configuration. */
1291DEFUN (no_rip_network,
1292 no_rip_network_cmd,
1293 "no network (A.B.C.D/M|WORD)",
1294 NO_STR
1295 "Enable routing on an IP network\n"
1296 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1297 "Interface name\n")
1298{
1299 int ret;
1300 struct prefix_ipv4 p;
1301
1302 ret = str2prefix_ipv4 (argv[0], &p);
1303
1304 if (ret)
1305 ret = rip_enable_network_delete ((struct prefix *) &p);
1306 else
1307 ret = rip_enable_if_delete (argv[0]);
1308
1309 if (ret < 0)
1310 {
1311 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1312 VTY_NEWLINE);
1313 return CMD_WARNING;
1314 }
1315
paul718e3742002-12-13 20:15:29 +00001316 return CMD_SUCCESS;
1317}
1318
1319/* RIP neighbor configuration set. */
1320DEFUN (rip_neighbor,
1321 rip_neighbor_cmd,
1322 "neighbor A.B.C.D",
1323 "Specify a neighbor router\n"
1324 "Neighbor address\n")
1325{
1326 int ret;
1327 struct prefix_ipv4 p;
1328
1329 ret = str2prefix_ipv4 (argv[0], &p);
1330
1331 if (ret <= 0)
1332 {
1333 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1334 return CMD_WARNING;
1335 }
1336
1337 rip_neighbor_add (&p);
1338
1339 return CMD_SUCCESS;
1340}
1341
1342/* RIP neighbor configuration unset. */
1343DEFUN (no_rip_neighbor,
1344 no_rip_neighbor_cmd,
1345 "no neighbor A.B.C.D",
1346 NO_STR
1347 "Specify a neighbor router\n"
1348 "Neighbor address\n")
1349{
1350 int ret;
1351 struct prefix_ipv4 p;
1352
1353 ret = str2prefix_ipv4 (argv[0], &p);
1354
1355 if (ret <= 0)
1356 {
1357 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1358 return CMD_WARNING;
1359 }
1360
1361 rip_neighbor_delete (&p);
1362
1363 return CMD_SUCCESS;
1364}
1365
1366DEFUN (ip_rip_receive_version,
1367 ip_rip_receive_version_cmd,
1368 "ip rip receive version (1|2)",
1369 IP_STR
1370 "Routing Information Protocol\n"
1371 "Advertisement reception\n"
1372 "Version control\n"
1373 "RIP version 1\n"
1374 "RIP version 2\n")
1375{
1376 struct interface *ifp;
1377 struct rip_interface *ri;
1378
1379 ifp = (struct interface *)vty->index;
1380 ri = ifp->info;
1381
1382 /* Version 1. */
1383 if (atoi (argv[0]) == 1)
1384 {
1385 ri->ri_receive = RI_RIP_VERSION_1;
1386 return CMD_SUCCESS;
1387 }
1388 if (atoi (argv[0]) == 2)
1389 {
1390 ri->ri_receive = RI_RIP_VERSION_2;
1391 return CMD_SUCCESS;
1392 }
1393 return CMD_WARNING;
1394}
1395
1396DEFUN (ip_rip_receive_version_1,
1397 ip_rip_receive_version_1_cmd,
1398 "ip rip receive version 1 2",
1399 IP_STR
1400 "Routing Information Protocol\n"
1401 "Advertisement reception\n"
1402 "Version control\n"
1403 "RIP version 1\n"
1404 "RIP version 2\n")
1405{
1406 struct interface *ifp;
1407 struct rip_interface *ri;
1408
1409 ifp = (struct interface *)vty->index;
1410 ri = ifp->info;
1411
1412 /* Version 1 and 2. */
1413 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1414 return CMD_SUCCESS;
1415}
1416
1417DEFUN (ip_rip_receive_version_2,
1418 ip_rip_receive_version_2_cmd,
1419 "ip rip receive version 2 1",
1420 IP_STR
1421 "Routing Information Protocol\n"
1422 "Advertisement reception\n"
1423 "Version control\n"
1424 "RIP version 2\n"
1425 "RIP version 1\n")
1426{
1427 struct interface *ifp;
1428 struct rip_interface *ri;
1429
1430 ifp = (struct interface *)vty->index;
1431 ri = ifp->info;
1432
1433 /* Version 1 and 2. */
1434 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1435 return CMD_SUCCESS;
1436}
1437
1438DEFUN (no_ip_rip_receive_version,
1439 no_ip_rip_receive_version_cmd,
1440 "no ip rip receive version",
1441 NO_STR
1442 IP_STR
1443 "Routing Information Protocol\n"
1444 "Advertisement reception\n"
1445 "Version control\n")
1446{
1447 struct interface *ifp;
1448 struct rip_interface *ri;
1449
1450 ifp = (struct interface *)vty->index;
1451 ri = ifp->info;
1452
1453 ri->ri_receive = RI_RIP_UNSPEC;
1454 return CMD_SUCCESS;
1455}
1456
1457ALIAS (no_ip_rip_receive_version,
1458 no_ip_rip_receive_version_num_cmd,
1459 "no ip rip receive version (1|2)",
1460 NO_STR
1461 IP_STR
1462 "Routing Information Protocol\n"
1463 "Advertisement reception\n"
1464 "Version control\n"
1465 "Version 1\n"
1466 "Version 2\n")
1467
1468DEFUN (ip_rip_send_version,
1469 ip_rip_send_version_cmd,
1470 "ip rip send version (1|2)",
1471 IP_STR
1472 "Routing Information Protocol\n"
1473 "Advertisement transmission\n"
1474 "Version control\n"
1475 "RIP version 1\n"
1476 "RIP version 2\n")
1477{
1478 struct interface *ifp;
1479 struct rip_interface *ri;
1480
1481 ifp = (struct interface *)vty->index;
1482 ri = ifp->info;
1483
1484 /* Version 1. */
1485 if (atoi (argv[0]) == 1)
1486 {
1487 ri->ri_send = RI_RIP_VERSION_1;
1488 return CMD_SUCCESS;
1489 }
1490 if (atoi (argv[0]) == 2)
1491 {
1492 ri->ri_send = RI_RIP_VERSION_2;
1493 return CMD_SUCCESS;
1494 }
1495 return CMD_WARNING;
1496}
1497
1498DEFUN (ip_rip_send_version_1,
1499 ip_rip_send_version_1_cmd,
1500 "ip rip send version 1 2",
1501 IP_STR
1502 "Routing Information Protocol\n"
1503 "Advertisement transmission\n"
1504 "Version control\n"
1505 "RIP version 1\n"
1506 "RIP version 2\n")
1507{
1508 struct interface *ifp;
1509 struct rip_interface *ri;
1510
1511 ifp = (struct interface *)vty->index;
1512 ri = ifp->info;
1513
1514 /* Version 1 and 2. */
1515 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1516 return CMD_SUCCESS;
1517}
1518
1519DEFUN (ip_rip_send_version_2,
1520 ip_rip_send_version_2_cmd,
1521 "ip rip send version 2 1",
1522 IP_STR
1523 "Routing Information Protocol\n"
1524 "Advertisement transmission\n"
1525 "Version control\n"
1526 "RIP version 2\n"
1527 "RIP version 1\n")
1528{
1529 struct interface *ifp;
1530 struct rip_interface *ri;
1531
1532 ifp = (struct interface *)vty->index;
1533 ri = ifp->info;
1534
1535 /* Version 1 and 2. */
1536 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1537 return CMD_SUCCESS;
1538}
1539
1540DEFUN (no_ip_rip_send_version,
1541 no_ip_rip_send_version_cmd,
1542 "no ip rip send version",
1543 NO_STR
1544 IP_STR
1545 "Routing Information Protocol\n"
1546 "Advertisement transmission\n"
1547 "Version control\n")
1548{
1549 struct interface *ifp;
1550 struct rip_interface *ri;
1551
1552 ifp = (struct interface *)vty->index;
1553 ri = ifp->info;
1554
1555 ri->ri_send = RI_RIP_UNSPEC;
1556 return CMD_SUCCESS;
1557}
1558
1559ALIAS (no_ip_rip_send_version,
1560 no_ip_rip_send_version_num_cmd,
1561 "no ip rip send version (1|2)",
1562 NO_STR
1563 IP_STR
1564 "Routing Information Protocol\n"
1565 "Advertisement transmission\n"
1566 "Version control\n"
1567 "Version 1\n"
1568 "Version 2\n")
1569
1570DEFUN (ip_rip_authentication_mode,
1571 ip_rip_authentication_mode_cmd,
1572 "ip rip authentication mode (md5|text)",
1573 IP_STR
1574 "Routing Information Protocol\n"
1575 "Authentication control\n"
1576 "Authentication mode\n"
1577 "Keyed message digest\n"
1578 "Clear text authentication\n")
1579{
1580 struct interface *ifp;
1581 struct rip_interface *ri;
1582
1583 ifp = (struct interface *)vty->index;
1584 ri = ifp->info;
1585
1586 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1587 ri->auth_type = RIP_AUTH_MD5;
1588 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1589 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1590 else
1591 {
1592 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1593 return CMD_WARNING;
1594 }
1595
1596 return CMD_SUCCESS;
1597}
1598
1599DEFUN (no_ip_rip_authentication_mode,
1600 no_ip_rip_authentication_mode_cmd,
1601 "no ip rip authentication mode",
1602 NO_STR
1603 IP_STR
1604 "Routing Information Protocol\n"
1605 "Authentication control\n"
1606 "Authentication mode\n")
1607{
1608 struct interface *ifp;
1609 struct rip_interface *ri;
1610
1611 ifp = (struct interface *)vty->index;
1612 ri = ifp->info;
1613
1614 /* ri->auth_type = RIP_NO_AUTH; */
1615 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1616
1617 return CMD_SUCCESS;
1618}
1619
1620ALIAS (no_ip_rip_authentication_mode,
1621 no_ip_rip_authentication_mode_type_cmd,
1622 "no ip rip authentication mode (md5|text)",
1623 NO_STR
1624 IP_STR
1625 "Routing Information Protocol\n"
1626 "Authentication control\n"
1627 "Authentication mode\n"
1628 "Keyed message digest\n"
1629 "Clear text authentication\n")
1630
1631DEFUN (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
hasso16705132003-05-25 14:49:19 +00001824ALIAS (no_ip_rip_split_horizon,
1825 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")
1832
paul718e3742002-12-13 20:15:29 +00001833DEFUN (rip_passive_interface,
1834 rip_passive_interface_cmd,
1835 "passive-interface IFNAME",
1836 "Suppress routing updates on an interface\n"
1837 "Interface name\n")
1838{
paul4aaff3f2003-06-07 01:04:45 +00001839 char *ifname = argv[0];
1840
1841 if (!strcmp(ifname,"default")) {
1842 passive_default = 1;
1843 rip_passive_nondefault_clean();
1844 return CMD_SUCCESS;
1845 }
1846 if (passive_default)
1847 return rip_passive_nondefault_unset (vty, ifname);
1848 else
1849 return rip_passive_nondefault_set (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001850}
1851
1852DEFUN (no_rip_passive_interface,
1853 no_rip_passive_interface_cmd,
1854 "no passive-interface IFNAME",
1855 NO_STR
1856 "Suppress routing updates on an interface\n"
1857 "Interface name\n")
1858{
paul4aaff3f2003-06-07 01:04:45 +00001859 char *ifname = argv[0];
1860
1861 if (!strcmp(ifname,"default")) {
1862 passive_default = 0;
1863 rip_passive_nondefault_clean();
1864 return CMD_SUCCESS;
1865 }
1866 if (passive_default)
1867 return rip_passive_nondefault_set (vty, ifname);
1868 else
1869 return rip_passive_nondefault_unset (vty, ifname);
paul718e3742002-12-13 20:15:29 +00001870}
1871
1872/* Write rip configuration of each interface. */
1873int
1874rip_interface_config_write (struct vty *vty)
1875{
1876 listnode node;
1877 struct interface *ifp;
1878
1879 for (node = listhead (iflist); node; nextnode (node))
1880 {
1881 struct rip_interface *ri;
1882
1883 ifp = getdata (node);
1884 ri = ifp->info;
1885
hasso16705132003-05-25 14:49:19 +00001886 /* Do not display the interface if there is no
1887 * configuration about it.
1888 **/
1889 if ((!ifp->desc) &&
1890 (ri->split_horizon == ri->split_horizon_default) &&
1891 (ri->ri_send == RI_RIP_UNSPEC) &&
1892 (ri->ri_receive == RI_RIP_UNSPEC) &&
1893 (ri->auth_type != RIP_AUTH_MD5) &&
1894 (!ri->auth_str) &&
1895 (!ri->key_chain) )
1896 continue;
1897
paul718e3742002-12-13 20:15:29 +00001898 vty_out (vty, "interface %s%s", ifp->name,
1899 VTY_NEWLINE);
1900
1901 if (ifp->desc)
1902 vty_out (vty, " description %s%s", ifp->desc,
1903 VTY_NEWLINE);
1904
1905 /* Split horizon. */
1906 if (ri->split_horizon != ri->split_horizon_default)
1907 {
hasso16705132003-05-25 14:49:19 +00001908 switch (ri->split_horizon) {
1909 case RIP_SPLIT_HORIZON:
1910 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
1911 break;
1912 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1913 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
1914 VTY_NEWLINE);
1915 break;
1916 case RIP_NO_SPLIT_HORIZON:
1917 default:
1918 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
1919 break;
1920 }
paul718e3742002-12-13 20:15:29 +00001921 }
1922
1923 /* RIP version setting. */
1924 if (ri->ri_send != RI_RIP_UNSPEC)
1925 vty_out (vty, " ip rip send version %s%s",
1926 lookup (ri_version_msg, ri->ri_send),
1927 VTY_NEWLINE);
1928
1929 if (ri->ri_receive != RI_RIP_UNSPEC)
1930 vty_out (vty, " ip rip receive version %s%s",
1931 lookup (ri_version_msg, ri->ri_receive),
1932 VTY_NEWLINE);
1933
1934 /* RIP authentication. */
1935#if 0
1936 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
1937 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1938 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
1939#endif /* 0 */
1940 if (ri->auth_type == RIP_AUTH_MD5)
1941 vty_out (vty, " ip rip authentication mode md5%s", VTY_NEWLINE);
1942
1943 if (ri->auth_str)
1944 vty_out (vty, " ip rip authentication string %s%s",
1945 ri->auth_str, VTY_NEWLINE);
1946
1947 if (ri->key_chain)
1948 vty_out (vty, " ip rip authentication key-chain %s%s",
1949 ri->key_chain, VTY_NEWLINE);
1950
1951 vty_out (vty, "!%s", VTY_NEWLINE);
1952 }
1953 return 0;
1954}
1955
1956int
1957config_write_rip_network (struct vty *vty, int config_mode)
1958{
1959 int i;
1960 char *ifname;
1961 struct route_node *node;
1962
1963 /* Network type RIP enable interface statement. */
1964 for (node = route_top (rip_enable_network); node; node = route_next (node))
1965 if (node->info)
1966 vty_out (vty, "%s%s/%d%s",
1967 config_mode ? " network " : " ",
1968 inet_ntoa (node->p.u.prefix4),
1969 node->p.prefixlen,
1970 VTY_NEWLINE);
1971
1972 /* Interface name RIP enable statement. */
1973 for (i = 0; i < vector_max (rip_enable_interface); i++)
1974 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
1975 vty_out (vty, "%s%s%s",
1976 config_mode ? " network " : " ",
1977 ifname,
1978 VTY_NEWLINE);
1979
1980 /* RIP neighbors listing. */
1981 for (node = route_top (rip->neighbor); node; node = route_next (node))
1982 if (node->info)
1983 vty_out (vty, "%s%s%s",
1984 config_mode ? " neighbor " : " ",
1985 inet_ntoa (node->p.u.prefix4),
1986 VTY_NEWLINE);
1987
1988 /* RIP passive interface listing. */
paul4aaff3f2003-06-07 01:04:45 +00001989 if (config_mode) {
1990 if (passive_default)
1991 vty_out (vty, " passive-interface default%s", ifname, VTY_NEWLINE);
1992 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1993 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
1994 vty_out (vty, " %spassive-interface %s%s",
1995 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
1996 }
paul718e3742002-12-13 20:15:29 +00001997
1998 return 0;
1999}
2000
2001struct cmd_node interface_node =
2002{
2003 INTERFACE_NODE,
2004 "%s(config-if)# ",
2005 1,
2006};
2007
2008/* Called when interface structure allocated. */
2009int
2010rip_interface_new_hook (struct interface *ifp)
2011{
2012 ifp->info = rip_interface_new ();
2013 return 0;
2014}
2015
2016/* Called when interface structure deleted. */
2017int
2018rip_interface_delete_hook (struct interface *ifp)
2019{
2020 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
hasso16705132003-05-25 14:49:19 +00002021 ifp->info = NULL;
paul718e3742002-12-13 20:15:29 +00002022 return 0;
2023}
2024
2025/* Allocate and initialize interface vector. */
2026void
2027rip_if_init ()
2028{
2029 /* Default initial size of interface vector. */
2030 if_init();
2031 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2032 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2033
2034 /* RIP network init. */
2035 rip_enable_interface = vector_init (1);
2036 rip_enable_network = route_table_init ();
2037
2038 /* RIP passive interface. */
paul4aaff3f2003-06-07 01:04:45 +00002039 Vrip_passive_nondefault = vector_init (1);
paul718e3742002-12-13 20:15:29 +00002040
2041 /* Install interface node. */
2042 install_node (&interface_node, rip_interface_config_write);
2043
2044 /* Install commands. */
2045 install_element (CONFIG_NODE, &interface_cmd);
hasso034489d2003-05-24 07:59:25 +00002046 install_element (CONFIG_NODE, &no_interface_cmd);
paul718e3742002-12-13 20:15:29 +00002047 install_default (INTERFACE_NODE);
2048 install_element (INTERFACE_NODE, &interface_desc_cmd);
2049 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2050 install_element (RIP_NODE, &rip_network_cmd);
2051 install_element (RIP_NODE, &no_rip_network_cmd);
2052 install_element (RIP_NODE, &rip_neighbor_cmd);
2053 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2054
2055 install_element (RIP_NODE, &rip_passive_interface_cmd);
2056 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2057
2058 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2059 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2060 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2061 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2062 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2063
2064 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2065 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2066 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2067 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2068 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2069
2070 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
2071 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2072 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
2073
2074 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2075 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2076 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2077
2078 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2079 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2080 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2081
hasso16705132003-05-25 14:49:19 +00002082 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2083 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2084 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2085 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
paul718e3742002-12-13 20:15:29 +00002086}