]> git.proxmox.com Git - mirror_frr.git/blame - ripd/rip_interface.c
2004-08-19 Paul Jakma <paul@dishone.st>
[mirror_frr.git] / ripd / rip_interface.c
CommitLineData
718e3744 1/* 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"
edd7c245 37#include "privs.h"
718e3744 38
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);
16705130 47int rip_enable_if_lookup (char *ifname);
48int rip_enable_network_lookup2 (struct connected *connected);
49void rip_enable_apply_all ();
50
718e3744 51
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
edd7c245 60extern struct zebra_privs_t ripd_privs;
61
718e3744 62/* 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. */
4aaff3f8 69static int passive_default; /* are we in passive-interface default mode? */
70vector Vrip_passive_nondefault;
718e3744 71\f
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\f
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;
ca5e516c 128 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
718e3744 129
130 /* Set default split-horizon behavior. If the interface is Frame
131 Relay or SMDS is enabled, the default value for split-horizon is
132 off. But currently Zebra does detect Frame Relay or SMDS
133 interface. So all interface is set to split horizon. */
16705130 134 ri->split_horizon_default = RIP_SPLIT_HORIZON;
718e3744 135 ri->split_horizon = ri->split_horizon_default;
136
137 return ri;
138}
139
140void
1a51786a 141rip_interface_multicast_set (int sock, struct connected *connected)
718e3744 142{
143 int ret;
718e3744 144 struct servent *sp;
145 struct sockaddr_in from;
718e3744 146 struct in_addr addr;
cc1131ab 147 struct prefix_ipv4 *p;
718e3744 148
931cd54d 149 if (connected != NULL)
150 {
1a51786a 151 if (if_is_pointopoint(connected->ifp))
cc1131ab 152 p = (struct prefix_ipv4 *) connected->destination;
153 else
718e3744 154 p = (struct prefix_ipv4 *) connected->address;
718e3744 155 addr = p->prefix;
931cd54d 156 }
157 else
158 {
159 addr.s_addr = INADDR_ANY;
160 }
718e3744 161
1a51786a 162 if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
163 connected->ifp->ifindex) < 0)
718e3744 164 {
1a51786a 165 zlog_warn ("Can't setsockopt IP_MULTICAST_IF to fd %d, ifindex %d",
166 sock, connected->ifp->ifindex);
718e3744 167 return;
168 }
169
170 /* Bind myself. */
171 memset (&from, 0, sizeof (struct sockaddr_in));
172
173 /* Set RIP port. */
174 sp = getservbyname ("router", "udp");
175 if (sp)
176 from.sin_port = sp->s_port;
177 else
178 from.sin_port = htons (RIP_PORT_DEFAULT);
179
931cd54d 180 /* Address should be any address. */
718e3744 181 from.sin_family = AF_INET;
931cd54d 182 if (connected)
cc1131ab 183 addr = ((struct prefix_ipv4 *) connected->address)->prefix;
718e3744 184 from.sin_addr = addr;
185#ifdef HAVE_SIN_LEN
186 from.sin_len = sizeof (struct sockaddr_in);
187#endif /* HAVE_SIN_LEN */
188
edd7c245 189 if (ripd_privs.change (ZPRIVS_RAISE))
190 zlog_err ("rip_interface_multicast_set: could not raise privs");
191
cc1131ab 192 ret = bind (sock, (struct sockaddr *) & from, sizeof (struct sockaddr_in));
718e3744 193 if (ret < 0)
194 {
195 zlog_warn ("Can't bind socket: %s", strerror (errno));
718e3744 196 }
197
edd7c245 198 if (ripd_privs.change (ZPRIVS_LOWER))
199 zlog_err ("rip_interface_multicast_set: could not lower privs");
200
718e3744 201 return;
202
203 }
718e3744 204
205/* Send RIP request packet to specified interface. */
206void
207rip_request_interface_send (struct interface *ifp, u_char version)
208{
209 struct sockaddr_in to;
210
211 /* RIPv2 support multicast. */
212 if (version == RIPv2 && if_is_multicast (ifp))
213 {
214
215 if (IS_RIP_DEBUG_EVENT)
216 zlog_info ("multicast request on %s", ifp->name);
217
931cd54d 218 rip_request_send (NULL, ifp, version, NULL);
718e3744 219 return;
220 }
221
222 /* RIPv1 and non multicast interface. */
223 if (if_is_pointopoint (ifp) || if_is_broadcast (ifp))
224 {
225 listnode cnode;
226
227 if (IS_RIP_DEBUG_EVENT)
228 zlog_info ("broadcast request to %s", ifp->name);
229
230 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
231 {
232 struct prefix_ipv4 *p;
233 struct connected *connected;
234
235 connected = getdata (cnode);
236 p = (struct prefix_ipv4 *) connected->destination;
237
238 if (p->family == AF_INET)
239 {
240 memset (&to, 0, sizeof (struct sockaddr_in));
241 to.sin_port = htons (RIP_PORT_DEFAULT);
242 to.sin_addr = p->prefix;
243
718e3744 244 if (IS_RIP_DEBUG_EVENT)
245 zlog_info ("SEND request to %s", inet_ntoa (to.sin_addr));
718e3744 246
931cd54d 247 rip_request_send (&to, ifp, version, connected);
718e3744 248 }
249 }
250 }
251}
252
253/* This will be executed when interface goes up. */
254void
255rip_request_interface (struct interface *ifp)
256{
257 struct rip_interface *ri;
258
259 /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */
260 if (if_is_loopback (ifp))
261 return;
262
263 /* If interface is down, don't send RIP packet. */
2e3b2e47 264 if (! if_is_operative (ifp))
718e3744 265 return;
266
267 /* Fetch RIP interface information. */
268 ri = ifp->info;
269
270
271 /* If there is no version configuration in the interface,
272 use rip's version setting. */
f38a471c 273 {
274 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
275 rip->version_send : ri->ri_send);
276 if (vsend & RIPv1)
277 rip_request_interface_send (ifp, RIPv1);
278 if (vsend & RIPv2)
279 rip_request_interface_send (ifp, RIPv2);
280 }
718e3744 281}
282
283/* Send RIP request to the neighbor. */
284void
285rip_request_neighbor (struct in_addr addr)
286{
287 struct sockaddr_in to;
288
289 memset (&to, 0, sizeof (struct sockaddr_in));
290 to.sin_port = htons (RIP_PORT_DEFAULT);
291 to.sin_addr = addr;
292
931cd54d 293 rip_request_send (&to, NULL, rip->version_send, NULL);
718e3744 294}
295
296/* Request routes at all interfaces. */
297void
298rip_request_neighbor_all ()
299{
300 struct route_node *rp;
301
302 if (! rip)
303 return;
304
305 if (IS_RIP_DEBUG_EVENT)
306 zlog_info ("request to the all neighbor");
307
308 /* Send request to all neighbor. */
309 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
310 if (rp->info)
311 rip_request_neighbor (rp->p.u.prefix4);
312}
313
314/* Multicast packet receive socket. */
315int
316rip_multicast_join (struct interface *ifp, int sock)
317{
318 listnode cnode;
319
2e3b2e47 320 if (if_is_operative (ifp) && if_is_multicast (ifp))
718e3744 321 {
322 if (IS_RIP_DEBUG_EVENT)
323 zlog_info ("multicast join at %s", ifp->name);
324
325 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
326 {
327 struct prefix_ipv4 *p;
328 struct connected *connected;
329 struct in_addr group;
330
331 connected = getdata (cnode);
332 p = (struct prefix_ipv4 *) connected->address;
333
334 if (p->family != AF_INET)
335 continue;
336
337 group.s_addr = htonl (INADDR_RIP_GROUP);
338 if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0)
339 return -1;
340 else
341 return 0;
342 }
343 }
344 return 0;
345}
346
347/* Leave from multicast group. */
348void
349rip_multicast_leave (struct interface *ifp, int sock)
350{
351 listnode cnode;
352
353 if (if_is_up (ifp) && if_is_multicast (ifp))
354 {
355 if (IS_RIP_DEBUG_EVENT)
356 zlog_info ("multicast leave from %s", ifp->name);
357
358 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
359 {
360 struct prefix_ipv4 *p;
361 struct connected *connected;
362 struct in_addr group;
363
364 connected = getdata (cnode);
365 p = (struct prefix_ipv4 *) connected->address;
366
367 if (p->family != AF_INET)
368 continue;
369
370 group.s_addr = htonl (INADDR_RIP_GROUP);
371 if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0)
372 return;
373 }
374 }
375}
376
377/* Is there and address on interface that I could use ? */
378int
379rip_if_ipv4_address_check (struct interface *ifp)
380{
381 struct listnode *nn;
382 struct connected *connected;
383 int count = 0;
384
385 for (nn = listhead (ifp->connected); nn; nextnode (nn))
386 if ((connected = getdata (nn)) != NULL)
387 {
388 struct prefix *p;
389
390 p = connected->address;
391
392 if (p->family == AF_INET)
393 {
394 count++;
395 }
396 }
397
398 return count;
399}
31a476c7 400
401
402
403
404/* Does this address belongs to me ? */
405int
406if_check_address (struct in_addr addr)
407{
408 listnode node;
409
410 for (node = listhead (iflist); node; nextnode (node))
411 {
412 listnode cnode;
413 struct interface *ifp;
414
415 ifp = getdata (node);
416
417 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
418 {
419 struct connected *connected;
420 struct prefix_ipv4 *p;
421
422 connected = getdata (cnode);
423 p = (struct prefix_ipv4 *) connected->address;
424
425 if (p->family != AF_INET)
426 continue;
427
428 if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0)
429 return 1;
430 }
431 }
432 return 0;
433}
434
435/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */
436int
437if_valid_neighbor (struct in_addr addr)
438{
439 listnode node;
440 struct connected *connected = NULL;
441 struct prefix_ipv4 *p;
442
443 for (node = listhead (iflist); node; nextnode (node))
444 {
445 listnode cnode;
446 struct interface *ifp;
447
448 ifp = getdata (node);
449
450 for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
451 {
452 struct prefix *pxn = NULL; /* Prefix of the neighbor */
453 struct prefix *pxc = NULL; /* Prefix of the connected network */
454
455 connected = getdata (cnode);
456
457 if (if_is_pointopoint (ifp))
458 {
459 p = (struct prefix_ipv4 *) connected->address;
460
461 if (p && p->family == AF_INET)
462 {
463 if (IPV4_ADDR_SAME (&p->prefix, &addr))
464 return 1;
465
466 p = (struct prefix_ipv4 *) connected->destination;
467 if (p && IPV4_ADDR_SAME (&p->prefix, &addr))
468 return 1;
469 }
470 }
471 else
472 {
473 p = (struct prefix_ipv4 *) connected->address;
474
475 if (p->family != AF_INET)
476 continue;
477
478 pxn = prefix_new();
479 pxn->family = AF_INET;
480 pxn->prefixlen = 32;
481 pxn->u.prefix4 = addr;
482
483 pxc = prefix_new();
484 prefix_copy(pxc, (struct prefix *) p);
485 apply_mask(pxc);
486
487 if (prefix_match (pxc, pxn))
488 {
489 prefix_free (pxn);
490 prefix_free (pxc);
491 return 1;
492 }
493 prefix_free(pxc);
494 prefix_free(pxn);
495 }
496 }
497 }
498 return 0;
499}
718e3744 500
501/* Inteface link down message processing. */
502int
503rip_interface_down (int command, struct zclient *zclient, zebra_size_t length)
504{
505 struct interface *ifp;
506 struct stream *s;
507
508 s = zclient->ibuf;
509
510 /* zebra_interface_state_read() updates interface structure in
511 iflist. */
512 ifp = zebra_interface_state_read(s);
513
514 if (ifp == NULL)
515 return 0;
516
517 rip_if_down(ifp);
518
519 if (IS_RIP_DEBUG_ZEBRA)
520 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is down",
521 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
522
523 return 0;
524}
525
526/* Inteface link up message processing */
527int
528rip_interface_up (int command, struct zclient *zclient, zebra_size_t length)
529{
530 struct interface *ifp;
531
532 /* zebra_interface_state_read () updates interface structure in
533 iflist. */
534 ifp = zebra_interface_state_read (zclient->ibuf);
535
536 if (ifp == NULL)
537 return 0;
538
539 if (IS_RIP_DEBUG_ZEBRA)
540 zlog_info ("interface %s index %d flags %ld metric %d mtu %d is up",
541 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
542
543 /* Check if this interface is RIP enabled or not.*/
544 rip_enable_apply (ifp);
545
546 /* Check for a passive interface */
547 rip_passive_interface_apply (ifp);
548
549 /* Apply distribute list to the all interface. */
550 rip_distribute_update_interface (ifp);
551
552 return 0;
553}
554
555/* Inteface addition message from zebra. */
556int
557rip_interface_add (int command, struct zclient *zclient, zebra_size_t length)
558{
559 struct interface *ifp;
560
561 ifp = zebra_interface_add_read (zclient->ibuf);
562
563 if (IS_RIP_DEBUG_ZEBRA)
564 zlog_info ("interface add %s index %d flags %ld metric %d mtu %d",
565 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
566
567 /* Check if this interface is RIP enabled or not.*/
568 rip_enable_apply (ifp);
569
570 /* Apply distribute list to the all interface. */
571 rip_distribute_update_interface (ifp);
572
573 /* rip_request_neighbor_all (); */
574
16705130 575 /* Check interface routemap. */
576 rip_if_rmap_update_interface (ifp);
577
718e3744 578 return 0;
579}
580
581int
582rip_interface_delete (int command, struct zclient *zclient,
583 zebra_size_t length)
584{
585 struct interface *ifp;
586 struct stream *s;
587
588
589 s = zclient->ibuf;
590 /* zebra_interface_state_read() updates interface structure in iflist */
591 ifp = zebra_interface_state_read(s);
592
593 if (ifp == NULL)
594 return 0;
595
596 if (if_is_up (ifp)) {
597 rip_if_down(ifp);
598 }
599
600 zlog_info("interface delete %s index %d flags %ld metric %d mtu %d",
601 ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
602
603 /* To support pseudo interface do not free interface structure. */
604 /* if_delete(ifp); */
605
606 return 0;
607}
608
609void
610rip_interface_clean ()
611{
612 listnode node;
613 struct interface *ifp;
614 struct rip_interface *ri;
615
616 for (node = listhead (iflist); node; nextnode (node))
617 {
618 ifp = getdata (node);
619 ri = ifp->info;
620
621 ri->enable_network = 0;
622 ri->enable_interface = 0;
623 ri->running = 0;
624
625 if (ri->t_wakeup)
626 {
627 thread_cancel (ri->t_wakeup);
628 ri->t_wakeup = NULL;
629 }
630 }
631}
632
633void
634rip_interface_reset ()
635{
636 listnode node;
637 struct interface *ifp;
638 struct rip_interface *ri;
639
640 for (node = listhead (iflist); node; nextnode (node))
641 {
642 ifp = getdata (node);
643 ri = ifp->info;
644
645 ri->enable_network = 0;
646 ri->enable_interface = 0;
647 ri->running = 0;
648
649 ri->ri_send = RI_RIP_UNSPEC;
650 ri->ri_receive = RI_RIP_UNSPEC;
651
652 /* ri->auth_type = RIP_NO_AUTH; */
653 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
654
655 if (ri->auth_str)
656 {
657 free (ri->auth_str);
658 ri->auth_str = NULL;
659 }
660 if (ri->key_chain)
661 {
662 free (ri->key_chain);
663 ri->key_chain = NULL;
664 }
665
16705130 666 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
667 ri->split_horizon_default = RIP_NO_SPLIT_HORIZON;
718e3744 668
669 ri->list[RIP_FILTER_IN] = NULL;
670 ri->list[RIP_FILTER_OUT] = NULL;
671
672 ri->prefix[RIP_FILTER_IN] = NULL;
673 ri->prefix[RIP_FILTER_OUT] = NULL;
674
675 if (ri->t_wakeup)
676 {
677 thread_cancel (ri->t_wakeup);
678 ri->t_wakeup = NULL;
679 }
680
681 ri->recv_badpackets = 0;
682 ri->recv_badroutes = 0;
683 ri->sent_updates = 0;
684
685 ri->passive = 0;
686 }
687}
688
689int
690rip_if_down(struct interface *ifp)
691{
692 struct route_node *rp;
693 struct rip_info *rinfo;
694 struct rip_interface *ri = NULL;
695 if (rip)
696 {
697 for (rp = route_top (rip->table); rp; rp = route_next (rp))
698 if ((rinfo = rp->info) != NULL)
699 {
700 /* Routes got through this interface. */
701 if (rinfo->ifindex == ifp->ifindex &&
702 rinfo->type == ZEBRA_ROUTE_RIP &&
703 rinfo->sub_type == RIP_ROUTE_RTE)
704 {
705 rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,
706 &rinfo->nexthop,
707 rinfo->ifindex);
708
709 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
710 (struct prefix_ipv4 *)&rp->p,
711 rinfo->ifindex);
712 }
713 else
714 {
715 /* All redistributed routes but static and system */
716 if ((rinfo->ifindex == ifp->ifindex) &&
2e3b2e47 717 /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
718e3744 718 (rinfo->type != ZEBRA_ROUTE_SYSTEM))
719 rip_redistribute_delete (rinfo->type,rinfo->sub_type,
720 (struct prefix_ipv4 *)&rp->p,
721 rinfo->ifindex);
722 }
723 }
724 }
725
726 ri = ifp->info;
727
728 if (ri->running)
729 {
730 if (IS_RIP_DEBUG_EVENT)
731 zlog_info ("turn off %s", ifp->name);
732
733 /* Leave from multicast group. */
734 rip_multicast_leave (ifp, rip->sock);
735
736 ri->running = 0;
737 }
738
739 return 0;
740}
741
742/* Needed for stop RIP process. */
743void
744rip_if_down_all ()
745{
746 struct interface *ifp;
747 listnode node;
748
749 for (node = listhead (iflist); node; nextnode (node))
750 {
751 ifp = getdata (node);
752 rip_if_down (ifp);
753 }
754}
755
16705130 756static void
757rip_apply_address_add (struct connected *ifc) {
758 struct prefix_ipv4 address;
759 struct prefix *p;
760
761 if (!rip)
762 return;
763
764 if (! if_is_up(ifc->ifp))
765 return;
766
767 p = ifc->address;
768
769 memset (&address, 0, sizeof (address));
770 address.family = p->family;
771 address.prefix = p->u.prefix4;
772 address.prefixlen = p->prefixlen;
773 apply_mask_ipv4(&address);
774
775 /* Check if this interface is RIP enabled or not
776 or Check if this address's prefix is RIP enabled */
777 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) ||
778 (rip_enable_network_lookup2(ifc) >= 0))
779 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
780 &address, ifc->ifp->ifindex, NULL);
781
782}
783
718e3744 784int
785rip_interface_address_add (int command, struct zclient *zclient,
786 zebra_size_t length)
787{
788 struct connected *ifc;
789 struct prefix *p;
790
0a589359 791 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,
792 zclient->ibuf);
718e3744 793
794 if (ifc == NULL)
795 return 0;
796
797 p = ifc->address;
798
799 if (p->family == AF_INET)
800 {
801 if (IS_RIP_DEBUG_ZEBRA)
802 zlog_info ("connected address %s/%d is added",
803 inet_ntoa (p->u.prefix4), p->prefixlen);
16705130 804
878ef2e7 805 rip_enable_apply(ifc->ifp);
16705130 806 /* Check if this prefix needs to be redistributed */
807 rip_apply_address_add(ifc);
718e3744 808
809#ifdef HAVE_SNMP
810 rip_ifaddr_add (ifc->ifp, ifc);
811#endif /* HAVE_SNMP */
812 }
813
814 return 0;
815}
816
16705130 817static void
818rip_apply_address_del (struct connected *ifc) {
819 struct prefix_ipv4 address;
820 struct prefix *p;
821
822 if (!rip)
823 return;
824
825 if (! if_is_up(ifc->ifp))
826 return;
827
828 p = ifc->address;
829
830 memset (&address, 0, sizeof (address));
831 address.family = p->family;
832 address.prefix = p->u.prefix4;
833 address.prefixlen = p->prefixlen;
834 apply_mask_ipv4(&address);
835
836 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
837 &address, ifc->ifp->ifindex);
838}
839
718e3744 840int
841rip_interface_address_delete (int command, struct zclient *zclient,
842 zebra_size_t length)
843{
844 struct connected *ifc;
845 struct prefix *p;
846
0a589359 847 ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE,
848 zclient->ibuf);
718e3744 849
850 if (ifc)
851 {
852 p = ifc->address;
853 if (p->family == AF_INET)
854 {
855 if (IS_RIP_DEBUG_ZEBRA)
856
857 zlog_info ("connected address %s/%d is deleted",
858 inet_ntoa (p->u.prefix4), p->prefixlen);
859
860#ifdef HAVE_SNMP
861 rip_ifaddr_delete (ifc->ifp, ifc);
862#endif /* HAVE_SNMP */
863
16705130 864 /* Chech wether this prefix needs to be removed */
865 rip_apply_address_del(ifc);
866
718e3744 867 }
868
869 connected_free (ifc);
870
871 }
872
873 return 0;
874}
875\f
876/* Check interface is enabled by network statement. */
16705130 877/* Check wether the interface has at least a connected prefix that
878 * is within the ripng_enable_network table. */
718e3744 879int
16705130 880rip_enable_network_lookup_if (struct interface *ifp)
718e3744 881{
882 struct listnode *nn;
883 struct connected *connected;
884 struct prefix_ipv4 address;
885
886 for (nn = listhead (ifp->connected); nn; nextnode (nn))
887 if ((connected = getdata (nn)) != NULL)
888 {
889 struct prefix *p;
890 struct route_node *node;
891
892 p = connected->address;
893
894 if (p->family == AF_INET)
895 {
896 address.family = AF_INET;
897 address.prefix = p->u.prefix4;
898 address.prefixlen = IPV4_MAX_BITLEN;
899
900 node = route_node_match (rip_enable_network,
901 (struct prefix *)&address);
902 if (node)
903 {
904 route_unlock_node (node);
905 return 1;
906 }
907 }
908 }
909 return -1;
910}
911
16705130 912/* Check wether connected is within the ripng_enable_network table. */
913int
914rip_enable_network_lookup2 (struct connected *connected)
915{
916 struct prefix_ipv4 address;
917 struct prefix *p;
918
919 p = connected->address;
920
921 if (p->family == AF_INET) {
922 struct route_node *node;
923
924 address.family = p->family;
925 address.prefix = p->u.prefix4;
926 address.prefixlen = IPV4_MAX_BITLEN;
927
928 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */
929 node = route_node_match (rip_enable_network,
930 (struct prefix *)&address);
931
932 if (node) {
933 route_unlock_node (node);
934 return 1;
935 }
936 }
937
938 return -1;
939}
718e3744 940/* Add RIP enable network. */
941int
942rip_enable_network_add (struct prefix *p)
943{
944 struct route_node *node;
945
946 node = route_node_get (rip_enable_network, p);
947
948 if (node->info)
949 {
950 route_unlock_node (node);
951 return -1;
952 }
953 else
954 node->info = "enabled";
955
16705130 956 /* XXX: One should find a better solution than a generic one */
957 rip_enable_apply_all();
958
718e3744 959 return 1;
960}
961
962/* Delete RIP enable network. */
963int
964rip_enable_network_delete (struct prefix *p)
965{
966 struct route_node *node;
967
968 node = route_node_lookup (rip_enable_network, p);
969 if (node)
970 {
971 node->info = NULL;
972
973 /* Unlock info lock. */
974 route_unlock_node (node);
975
976 /* Unlock lookup lock. */
977 route_unlock_node (node);
978
16705130 979 /* XXX: One should find a better solution than a generic one */
980 rip_enable_apply_all ();
981
718e3744 982 return 1;
983 }
984 return -1;
985}
986
987/* Check interface is enabled by ifname statement. */
988int
989rip_enable_if_lookup (char *ifname)
990{
991 int i;
992 char *str;
993
994 for (i = 0; i < vector_max (rip_enable_interface); i++)
995 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
996 if (strcmp (str, ifname) == 0)
997 return i;
998 return -1;
999}
1000
1001/* Add interface to rip_enable_if. */
1002int
1003rip_enable_if_add (char *ifname)
1004{
1005 int ret;
1006
1007 ret = rip_enable_if_lookup (ifname);
1008 if (ret >= 0)
1009 return -1;
1010
1011 vector_set (rip_enable_interface, strdup (ifname));
1012
16705130 1013 rip_enable_apply_all(); /* TODOVJ */
1014
718e3744 1015 return 1;
1016}
1017
1018/* Delete interface from rip_enable_if. */
1019int
1020rip_enable_if_delete (char *ifname)
1021{
1022 int index;
1023 char *str;
1024
1025 index = rip_enable_if_lookup (ifname);
1026 if (index < 0)
1027 return -1;
1028
1029 str = vector_slot (rip_enable_interface, index);
1030 free (str);
1031 vector_unset (rip_enable_interface, index);
1032
16705130 1033 rip_enable_apply_all(); /* TODOVJ */
1034
718e3744 1035 return 1;
1036}
1037
1038/* Join to multicast group and send request to the interface. */
1039int
1040rip_interface_wakeup (struct thread *t)
1041{
1042 struct interface *ifp;
1043 struct rip_interface *ri;
1044
1045 /* Get interface. */
1046 ifp = THREAD_ARG (t);
1047
1048 ri = ifp->info;
1049 ri->t_wakeup = NULL;
1050
1051 /* Join to multicast group. */
1052 if (rip_multicast_join (ifp, rip->sock) < 0)
1053 {
1054 zlog_err ("multicast join failed, interface %s not running", ifp->name);
1055 return 0;
1056 }
1057
1058 /* Set running flag. */
1059 ri->running = 1;
1060
1061 /* Send RIP request to the interface. */
1062 rip_request_interface (ifp);
1063
1064 return 0;
1065}
1066
1067int rip_redistribute_check (int);
1068
1069void
1070rip_connect_set (struct interface *ifp, int set)
1071{
1072 struct listnode *nn;
1073 struct connected *connected;
1074 struct prefix_ipv4 address;
1075
1076 for (nn = listhead (ifp->connected); nn; nextnode (nn))
1077 if ((connected = getdata (nn)) != NULL)
1078 {
1079 struct prefix *p;
1080 p = connected->address;
1081
1082 if (p->family != AF_INET)
1083 continue;
1084
1085 address.family = AF_INET;
1086 address.prefix = p->u.prefix4;
1087 address.prefixlen = p->prefixlen;
1088 apply_mask_ipv4 (&address);
1089
16705130 1090 if (set) {
1091 /* Check once more wether this prefix is within a "network IF_OR_PREF" one */
1092 if ((rip_enable_if_lookup(connected->ifp->name) >= 0) ||
1093 (rip_enable_network_lookup2(connected) >= 0))
1094 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1095 &address, connected->ifp->ifindex, NULL);
1096 } else
718e3744 1097 {
1098 rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
1099 &address, connected->ifp->ifindex);
1100 if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))
1101 rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,
1102 &address, connected->ifp->ifindex, NULL);
1103 }
1104 }
1105}
1106
1107/* Update interface status. */
1108void
1109rip_enable_apply (struct interface *ifp)
1110{
1111 int ret;
1112 struct rip_interface *ri = NULL;
1113
1114 /* Check interface. */
2e3b2e47 1115 if (! if_is_operative (ifp))
718e3744 1116 return;
1117
1118 ri = ifp->info;
1119
1120 /* Check network configuration. */
16705130 1121 ret = rip_enable_network_lookup_if (ifp);
718e3744 1122
1123 /* If the interface is matched. */
1124 if (ret > 0)
1125 ri->enable_network = 1;
1126 else
1127 ri->enable_network = 0;
1128
1129 /* Check interface name configuration. */
1130 ret = rip_enable_if_lookup (ifp->name);
1131 if (ret >= 0)
1132 ri->enable_interface = 1;
1133 else
1134 ri->enable_interface = 0;
1135
1136 /* any interface MUST have an IPv4 address */
1137 if ( ! rip_if_ipv4_address_check (ifp) )
1138 {
1139 ri->enable_network = 0;
1140 ri->enable_interface = 0;
1141 }
1142
1143 /* Update running status of the interface. */
1144 if (ri->enable_network || ri->enable_interface)
1145 {
718e3744 1146 {
1147 if (IS_RIP_DEBUG_EVENT)
1148 zlog_info ("turn on %s", ifp->name);
1149
1150 /* Add interface wake up thread. */
1151 if (! ri->t_wakeup)
1152 ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,
1153 ifp, 1);
1154 rip_connect_set (ifp, 1);
1155 }
1156 }
1157 else
1158 {
1159 if (ri->running)
1160 {
16705130 1161 /* Might as well clean up the route table as well
1162 * rip_if_down sets to 0 ri->running, and displays "turn off %s"
1163 **/
718e3744 1164 rip_if_down(ifp);
1165
718e3744 1166 rip_connect_set (ifp, 0);
1167 }
1168 }
1169}
1170
1171/* Apply network configuration to all interface. */
1172void
1173rip_enable_apply_all ()
1174{
1175 struct interface *ifp;
1176 listnode node;
1177
1178 /* Check each interface. */
1179 for (node = listhead (iflist); node; nextnode (node))
1180 {
1181 ifp = getdata (node);
1182 rip_enable_apply (ifp);
1183 }
1184}
1185
1186int
1187rip_neighbor_lookup (struct sockaddr_in *from)
1188{
1189 struct prefix_ipv4 p;
1190 struct route_node *node;
1191
1192 memset (&p, 0, sizeof (struct prefix_ipv4));
1193 p.family = AF_INET;
1194 p.prefix = from->sin_addr;
1195 p.prefixlen = IPV4_MAX_BITLEN;
1196
1197 node = route_node_lookup (rip->neighbor, (struct prefix *) &p);
1198 if (node)
1199 {
1200 route_unlock_node (node);
1201 return 1;
1202 }
1203 return 0;
1204}
1205
1206/* Add new RIP neighbor to the neighbor tree. */
1207int
1208rip_neighbor_add (struct prefix_ipv4 *p)
1209{
1210 struct route_node *node;
1211
1212 node = route_node_get (rip->neighbor, (struct prefix *) p);
1213
1214 if (node->info)
1215 return -1;
1216
1217 node->info = rip->neighbor;
1218
1219 return 0;
1220}
1221
1222/* Delete RIP neighbor from the neighbor tree. */
1223int
1224rip_neighbor_delete (struct prefix_ipv4 *p)
1225{
1226 struct route_node *node;
1227
1228 /* Lock for look up. */
1229 node = route_node_lookup (rip->neighbor, (struct prefix *) p);
1230 if (! node)
1231 return -1;
1232
1233 node->info = NULL;
1234
1235 /* Unlock lookup lock. */
1236 route_unlock_node (node);
1237
1238 /* Unlock real neighbor information lock. */
1239 route_unlock_node (node);
1240
1241 return 0;
1242}
1243
1244/* Clear all network and neighbor configuration. */
1245void
1246rip_clean_network ()
1247{
1248 int i;
1249 char *str;
1250 struct route_node *rn;
1251
1252 /* rip_enable_network. */
1253 for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))
1254 if (rn->info)
1255 {
1256 rn->info = NULL;
1257 route_unlock_node (rn);
1258 }
1259
1260 /* rip_enable_interface. */
1261 for (i = 0; i < vector_max (rip_enable_interface); i++)
1262 if ((str = vector_slot (rip_enable_interface, i)) != NULL)
1263 {
1264 free (str);
1265 vector_slot (rip_enable_interface, i) = NULL;
1266 }
1267}
1268\f
1269/* Utility function for looking up passive interface settings. */
1270int
4aaff3f8 1271rip_passive_nondefault_lookup (char *ifname)
718e3744 1272{
1273 int i;
1274 char *str;
1275
4aaff3f8 1276 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1277 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
718e3744 1278 if (strcmp (str, ifname) == 0)
1279 return i;
1280 return -1;
1281}
1282
1283void
1284rip_passive_interface_apply (struct interface *ifp)
1285{
718e3744 1286 struct rip_interface *ri;
1287
1288 ri = ifp->info;
1289
4aaff3f8 1290 ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ?
1291 passive_default : !passive_default);
1292
1293 if (IS_RIP_DEBUG_ZEBRA)
1294 zlog_info ("interface %s: passive = %d",ifp->name,ri->passive);
718e3744 1295}
1296
1297void
1298rip_passive_interface_apply_all ()
1299{
1300 struct interface *ifp;
1301 listnode node;
1302
1303 for (node = listhead (iflist); node; nextnode (node))
1304 {
1305 ifp = getdata (node);
1306 rip_passive_interface_apply (ifp);
1307 }
1308}
1309
1310/* Passive interface. */
1311int
4aaff3f8 1312rip_passive_nondefault_set (struct vty *vty, char *ifname)
718e3744 1313{
4aaff3f8 1314 if (rip_passive_nondefault_lookup (ifname) >= 0)
718e3744 1315 return CMD_WARNING;
1316
4aaff3f8 1317 vector_set (Vrip_passive_nondefault, strdup (ifname));
718e3744 1318
1319 rip_passive_interface_apply_all ();
1320
1321 return CMD_SUCCESS;
1322}
1323
1324int
4aaff3f8 1325rip_passive_nondefault_unset (struct vty *vty, char *ifname)
718e3744 1326{
1327 int i;
1328 char *str;
1329
4aaff3f8 1330 i = rip_passive_nondefault_lookup (ifname);
718e3744 1331 if (i < 0)
1332 return CMD_WARNING;
1333
4aaff3f8 1334 str = vector_slot (Vrip_passive_nondefault, i);
718e3744 1335 free (str);
4aaff3f8 1336 vector_unset (Vrip_passive_nondefault, i);
718e3744 1337
1338 rip_passive_interface_apply_all ();
1339
1340 return CMD_SUCCESS;
1341}
1342
1343/* Free all configured RIP passive-interface settings. */
1344void
4aaff3f8 1345rip_passive_nondefault_clean ()
718e3744 1346{
1347 int i;
1348 char *str;
1349
4aaff3f8 1350 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
1351 if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL)
718e3744 1352 {
1353 free (str);
4aaff3f8 1354 vector_slot (Vrip_passive_nondefault, i) = NULL;
718e3744 1355 }
1356 rip_passive_interface_apply_all ();
1357}
1358\f
1359/* RIP enable network or interface configuration. */
1360DEFUN (rip_network,
1361 rip_network_cmd,
1362 "network (A.B.C.D/M|WORD)",
1363 "Enable routing on an IP network\n"
1364 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1365 "Interface name\n")
1366{
1367 int ret;
1368 struct prefix_ipv4 p;
1369
1370 ret = str2prefix_ipv4 (argv[0], &p);
1371
1372 if (ret)
1373 ret = rip_enable_network_add ((struct prefix *) &p);
1374 else
1375 ret = rip_enable_if_add (argv[0]);
1376
1377 if (ret < 0)
1378 {
1379 vty_out (vty, "There is a same network configuration %s%s", argv[0],
1380 VTY_NEWLINE);
1381 return CMD_WARNING;
1382 }
1383
718e3744 1384 return CMD_SUCCESS;
1385}
1386
1387/* RIP enable network or interface configuration. */
1388DEFUN (no_rip_network,
1389 no_rip_network_cmd,
1390 "no network (A.B.C.D/M|WORD)",
1391 NO_STR
1392 "Enable routing on an IP network\n"
1393 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1394 "Interface name\n")
1395{
1396 int ret;
1397 struct prefix_ipv4 p;
1398
1399 ret = str2prefix_ipv4 (argv[0], &p);
1400
1401 if (ret)
1402 ret = rip_enable_network_delete ((struct prefix *) &p);
1403 else
1404 ret = rip_enable_if_delete (argv[0]);
1405
1406 if (ret < 0)
1407 {
1408 vty_out (vty, "Can't find network configuration %s%s", argv[0],
1409 VTY_NEWLINE);
1410 return CMD_WARNING;
1411 }
1412
718e3744 1413 return CMD_SUCCESS;
1414}
1415
1416/* RIP neighbor configuration set. */
1417DEFUN (rip_neighbor,
1418 rip_neighbor_cmd,
1419 "neighbor A.B.C.D",
1420 "Specify a neighbor router\n"
1421 "Neighbor address\n")
1422{
1423 int ret;
1424 struct prefix_ipv4 p;
1425
1426 ret = str2prefix_ipv4 (argv[0], &p);
1427
1428 if (ret <= 0)
1429 {
1430 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1431 return CMD_WARNING;
1432 }
1433
1434 rip_neighbor_add (&p);
1435
1436 return CMD_SUCCESS;
1437}
1438
1439/* RIP neighbor configuration unset. */
1440DEFUN (no_rip_neighbor,
1441 no_rip_neighbor_cmd,
1442 "no neighbor A.B.C.D",
1443 NO_STR
1444 "Specify a neighbor router\n"
1445 "Neighbor address\n")
1446{
1447 int ret;
1448 struct prefix_ipv4 p;
1449
1450 ret = str2prefix_ipv4 (argv[0], &p);
1451
1452 if (ret <= 0)
1453 {
1454 vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);
1455 return CMD_WARNING;
1456 }
1457
1458 rip_neighbor_delete (&p);
1459
1460 return CMD_SUCCESS;
1461}
1462
1463DEFUN (ip_rip_receive_version,
1464 ip_rip_receive_version_cmd,
1465 "ip rip receive version (1|2)",
1466 IP_STR
1467 "Routing Information Protocol\n"
1468 "Advertisement reception\n"
1469 "Version control\n"
1470 "RIP version 1\n"
1471 "RIP version 2\n")
1472{
1473 struct interface *ifp;
1474 struct rip_interface *ri;
1475
1476 ifp = (struct interface *)vty->index;
1477 ri = ifp->info;
1478
1479 /* Version 1. */
1480 if (atoi (argv[0]) == 1)
1481 {
1482 ri->ri_receive = RI_RIP_VERSION_1;
1483 return CMD_SUCCESS;
1484 }
1485 if (atoi (argv[0]) == 2)
1486 {
1487 ri->ri_receive = RI_RIP_VERSION_2;
1488 return CMD_SUCCESS;
1489 }
1490 return CMD_WARNING;
1491}
1492
1493DEFUN (ip_rip_receive_version_1,
1494 ip_rip_receive_version_1_cmd,
1495 "ip rip receive version 1 2",
1496 IP_STR
1497 "Routing Information Protocol\n"
1498 "Advertisement reception\n"
1499 "Version control\n"
1500 "RIP version 1\n"
1501 "RIP version 2\n")
1502{
1503 struct interface *ifp;
1504 struct rip_interface *ri;
1505
1506 ifp = (struct interface *)vty->index;
1507 ri = ifp->info;
1508
1509 /* Version 1 and 2. */
1510 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1511 return CMD_SUCCESS;
1512}
1513
1514DEFUN (ip_rip_receive_version_2,
1515 ip_rip_receive_version_2_cmd,
1516 "ip rip receive version 2 1",
1517 IP_STR
1518 "Routing Information Protocol\n"
1519 "Advertisement reception\n"
1520 "Version control\n"
1521 "RIP version 2\n"
1522 "RIP version 1\n")
1523{
1524 struct interface *ifp;
1525 struct rip_interface *ri;
1526
1527 ifp = (struct interface *)vty->index;
1528 ri = ifp->info;
1529
1530 /* Version 1 and 2. */
1531 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1532 return CMD_SUCCESS;
1533}
1534
1535DEFUN (no_ip_rip_receive_version,
1536 no_ip_rip_receive_version_cmd,
1537 "no ip rip receive version",
1538 NO_STR
1539 IP_STR
1540 "Routing Information Protocol\n"
1541 "Advertisement reception\n"
1542 "Version control\n")
1543{
1544 struct interface *ifp;
1545 struct rip_interface *ri;
1546
1547 ifp = (struct interface *)vty->index;
1548 ri = ifp->info;
1549
1550 ri->ri_receive = RI_RIP_UNSPEC;
1551 return CMD_SUCCESS;
1552}
1553
1554ALIAS (no_ip_rip_receive_version,
1555 no_ip_rip_receive_version_num_cmd,
1556 "no ip rip receive version (1|2)",
1557 NO_STR
1558 IP_STR
1559 "Routing Information Protocol\n"
1560 "Advertisement reception\n"
1561 "Version control\n"
1562 "Version 1\n"
1563 "Version 2\n")
1564
1565DEFUN (ip_rip_send_version,
1566 ip_rip_send_version_cmd,
1567 "ip rip send version (1|2)",
1568 IP_STR
1569 "Routing Information Protocol\n"
1570 "Advertisement transmission\n"
1571 "Version control\n"
1572 "RIP version 1\n"
1573 "RIP version 2\n")
1574{
1575 struct interface *ifp;
1576 struct rip_interface *ri;
1577
1578 ifp = (struct interface *)vty->index;
1579 ri = ifp->info;
1580
1581 /* Version 1. */
1582 if (atoi (argv[0]) == 1)
1583 {
1584 ri->ri_send = RI_RIP_VERSION_1;
1585 return CMD_SUCCESS;
1586 }
1587 if (atoi (argv[0]) == 2)
1588 {
1589 ri->ri_send = RI_RIP_VERSION_2;
1590 return CMD_SUCCESS;
1591 }
1592 return CMD_WARNING;
1593}
1594
1595DEFUN (ip_rip_send_version_1,
1596 ip_rip_send_version_1_cmd,
1597 "ip rip send version 1 2",
1598 IP_STR
1599 "Routing Information Protocol\n"
1600 "Advertisement transmission\n"
1601 "Version control\n"
1602 "RIP version 1\n"
1603 "RIP version 2\n")
1604{
1605 struct interface *ifp;
1606 struct rip_interface *ri;
1607
1608 ifp = (struct interface *)vty->index;
1609 ri = ifp->info;
1610
1611 /* Version 1 and 2. */
1612 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1613 return CMD_SUCCESS;
1614}
1615
1616DEFUN (ip_rip_send_version_2,
1617 ip_rip_send_version_2_cmd,
1618 "ip rip send version 2 1",
1619 IP_STR
1620 "Routing Information Protocol\n"
1621 "Advertisement transmission\n"
1622 "Version control\n"
1623 "RIP version 2\n"
1624 "RIP version 1\n")
1625{
1626 struct interface *ifp;
1627 struct rip_interface *ri;
1628
1629 ifp = (struct interface *)vty->index;
1630 ri = ifp->info;
1631
1632 /* Version 1 and 2. */
1633 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1634 return CMD_SUCCESS;
1635}
1636
1637DEFUN (no_ip_rip_send_version,
1638 no_ip_rip_send_version_cmd,
1639 "no ip rip send version",
1640 NO_STR
1641 IP_STR
1642 "Routing Information Protocol\n"
1643 "Advertisement transmission\n"
1644 "Version control\n")
1645{
1646 struct interface *ifp;
1647 struct rip_interface *ri;
1648
1649 ifp = (struct interface *)vty->index;
1650 ri = ifp->info;
1651
1652 ri->ri_send = RI_RIP_UNSPEC;
1653 return CMD_SUCCESS;
1654}
1655
1656ALIAS (no_ip_rip_send_version,
1657 no_ip_rip_send_version_num_cmd,
1658 "no ip rip send version (1|2)",
1659 NO_STR
1660 IP_STR
1661 "Routing Information Protocol\n"
1662 "Advertisement transmission\n"
1663 "Version control\n"
1664 "Version 1\n"
1665 "Version 2\n")
1666
1667DEFUN (ip_rip_authentication_mode,
1668 ip_rip_authentication_mode_cmd,
1669 "ip rip authentication mode (md5|text)",
1670 IP_STR
1671 "Routing Information Protocol\n"
1672 "Authentication control\n"
1673 "Authentication mode\n"
1674 "Keyed message digest\n"
1675 "Clear text authentication\n")
1676{
1677 struct interface *ifp;
1678 struct rip_interface *ri;
1679
1680 ifp = (struct interface *)vty->index;
1681 ri = ifp->info;
1682
ca5e516c 1683 if ( (argc < 1) || (argc > 2) )
1684 {
1685 vty_out (vty, "incorrect argument count%s", VTY_NEWLINE);
1686 return CMD_WARNING;
1687 }
1688
718e3744 1689 if (strncmp ("md5", argv[0], strlen (argv[0])) == 0)
1690 ri->auth_type = RIP_AUTH_MD5;
1691 else if (strncmp ("text", argv[0], strlen (argv[0])) == 0)
1692 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1693 else
1694 {
1695 vty_out (vty, "mode should be md5 or text%s", VTY_NEWLINE);
1696 return CMD_WARNING;
1697 }
1698
ca5e516c 1699 if (argc == 1)
1700 return CMD_SUCCESS;
1701
1702 if ( (argc == 2) && (ri->auth_type != RIP_AUTH_MD5) )
1703 {
1704 vty_out (vty, "auth length argument only valid for md5%s", VTY_NEWLINE);
1705 return CMD_WARNING;
1706}
1707
1708 if (strncmp ("r", argv[1], 1) == 0)
1709 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1710 else if (strncmp ("o", argv[1], 1) == 0)
1711 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1712 else
1713 return CMD_WARNING;
1714
718e3744 1715 return CMD_SUCCESS;
1716}
1717
ca5e516c 1718ALIAS (ip_rip_authentication_mode,
1719 ip_rip_authentication_mode_authlen_cmd,
1720 "ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1721 IP_STR
1722 "Routing Information Protocol\n"
1723 "Authentication control\n"
1724 "Authentication mode\n"
1725 "Keyed message digest\n"
1726 "Clear text authentication\n"
1727 "MD5 authentication data length\n"
1728 "RFC compatible\n"
1729 "Old ripd compatible\n")
1730
718e3744 1731DEFUN (no_ip_rip_authentication_mode,
1732 no_ip_rip_authentication_mode_cmd,
1733 "no ip rip authentication mode",
1734 NO_STR
1735 IP_STR
1736 "Routing Information Protocol\n"
1737 "Authentication control\n"
1738 "Authentication mode\n")
1739{
1740 struct interface *ifp;
1741 struct rip_interface *ri;
1742
1743 ifp = (struct interface *)vty->index;
1744 ri = ifp->info;
1745
1746 /* ri->auth_type = RIP_NO_AUTH; */
1747 ri->auth_type = RIP_AUTH_SIMPLE_PASSWORD;
ca5e516c 1748 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
718e3744 1749
1750 return CMD_SUCCESS;
1751}
1752
1753ALIAS (no_ip_rip_authentication_mode,
1754 no_ip_rip_authentication_mode_type_cmd,
1755 "no ip rip authentication mode (md5|text)",
1756 NO_STR
1757 IP_STR
1758 "Routing Information Protocol\n"
1759 "Authentication control\n"
1760 "Authentication mode\n"
1761 "Keyed message digest\n"
1762 "Clear text authentication\n")
1763
ca5e516c 1764ALIAS (no_ip_rip_authentication_mode,
1765 no_ip_rip_authentication_mode_type_authlen_cmd,
1766 "no ip rip authentication mode (md5|text) auth-length (rfc|old-ripd)",
1767 NO_STR
1768 IP_STR
1769 "Routing Information Protocol\n"
1770 "Authentication control\n"
1771 "Authentication mode\n"
1772 "Keyed message digest\n"
1773 "Clear text authentication\n"
1774 "MD5 authentication data length\n"
1775 "RFC compatible\n"
1776 "Old ripd compatible\n")
1777
718e3744 1778DEFUN (ip_rip_authentication_string,
1779 ip_rip_authentication_string_cmd,
1780 "ip rip authentication string LINE",
1781 IP_STR
1782 "Routing Information Protocol\n"
1783 "Authentication control\n"
1784 "Authentication string\n"
1785 "Authentication string\n")
1786{
1787 struct interface *ifp;
1788 struct rip_interface *ri;
1789
1790 ifp = (struct interface *)vty->index;
1791 ri = ifp->info;
1792
1793 if (strlen (argv[0]) > 16)
1794 {
1795 vty_out (vty, "%% RIPv2 authentication string must be shorter than 16%s",
1796 VTY_NEWLINE);
1797 return CMD_WARNING;
1798 }
1799
1800 if (ri->key_chain)
1801 {
1802 vty_out (vty, "%% key-chain configuration exists%s", VTY_NEWLINE);
1803 return CMD_WARNING;
1804 }
1805
1806 if (ri->auth_str)
1807 free (ri->auth_str);
1808
1809 ri->auth_str = strdup (argv[0]);
1810
1811 return CMD_SUCCESS;
1812}
1813
1814DEFUN (no_ip_rip_authentication_string,
1815 no_ip_rip_authentication_string_cmd,
1816 "no ip rip authentication string",
1817 NO_STR
1818 IP_STR
1819 "Routing Information Protocol\n"
1820 "Authentication control\n"
1821 "Authentication string\n")
1822{
1823 struct interface *ifp;
1824 struct rip_interface *ri;
1825
1826 ifp = (struct interface *)vty->index;
1827 ri = ifp->info;
1828
1829 if (ri->auth_str)
1830 free (ri->auth_str);
1831
1832 ri->auth_str = NULL;
1833
1834 return CMD_SUCCESS;
1835}
1836
1837ALIAS (no_ip_rip_authentication_string,
1838 no_ip_rip_authentication_string2_cmd,
1839 "no ip rip authentication string LINE",
1840 NO_STR
1841 IP_STR
1842 "Routing Information Protocol\n"
1843 "Authentication control\n"
1844 "Authentication string\n"
1845 "Authentication string\n")
1846
1847DEFUN (ip_rip_authentication_key_chain,
1848 ip_rip_authentication_key_chain_cmd,
1849 "ip rip authentication key-chain LINE",
1850 IP_STR
1851 "Routing Information Protocol\n"
1852 "Authentication control\n"
1853 "Authentication key-chain\n"
1854 "name of key-chain\n")
1855{
1856 struct interface *ifp;
1857 struct rip_interface *ri;
1858
1859 ifp = (struct interface *) vty->index;
1860 ri = ifp->info;
1861
1862 if (ri->auth_str)
1863 {
1864 vty_out (vty, "%% authentication string configuration exists%s",
1865 VTY_NEWLINE);
1866 return CMD_WARNING;
1867 }
1868
1869 if (ri->key_chain)
1870 free (ri->key_chain);
1871
1872 ri->key_chain = strdup (argv[0]);
1873
1874 return CMD_SUCCESS;
1875}
1876
1877DEFUN (no_ip_rip_authentication_key_chain,
1878 no_ip_rip_authentication_key_chain_cmd,
1879 "no ip rip authentication key-chain",
1880 NO_STR
1881 IP_STR
1882 "Routing Information Protocol\n"
1883 "Authentication control\n"
1884 "Authentication key-chain\n")
1885{
1886 struct interface *ifp;
1887 struct rip_interface *ri;
1888
1889 ifp = (struct interface *) vty->index;
1890 ri = ifp->info;
1891
1892 if (ri->key_chain)
1893 free (ri->key_chain);
1894
1895 ri->key_chain = NULL;
1896
1897 return CMD_SUCCESS;
1898}
1899
1900ALIAS (no_ip_rip_authentication_key_chain,
1901 no_ip_rip_authentication_key_chain2_cmd,
1902 "no ip rip authentication key-chain LINE",
1903 NO_STR
1904 IP_STR
1905 "Routing Information Protocol\n"
1906 "Authentication control\n"
1907 "Authentication key-chain\n"
1908 "name of key-chain\n")
1909
16705130 1910/* CHANGED: ip rip split-horizon
1911 Cisco and Zebra's command is
1912 ip split-horizon
1913 */
1914DEFUN (ip_rip_split_horizon,
1915 ip_rip_split_horizon_cmd,
1916 "ip rip split-horizon",
718e3744 1917 IP_STR
16705130 1918 "Routing Information Protocol\n"
718e3744 1919 "Perform split horizon\n")
1920{
1921 struct interface *ifp;
1922 struct rip_interface *ri;
1923
1924 ifp = vty->index;
1925 ri = ifp->info;
1926
16705130 1927 ri->split_horizon = RIP_SPLIT_HORIZON;
718e3744 1928 return CMD_SUCCESS;
1929}
1930
16705130 1931DEFUN (ip_rip_split_horizon_poisoned_reverse,
1932 ip_rip_split_horizon_poisoned_reverse_cmd,
1933 "ip rip split-horizon poisoned-reverse",
1934 IP_STR
1935 "Routing Information Protocol\n"
1936 "Perform split horizon\n"
1937 "With poisoned-reverse\n")
1938{
1939 struct interface *ifp;
1940 struct rip_interface *ri;
1941
1942 ifp = vty->index;
1943 ri = ifp->info;
1944
1945 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1946 return CMD_SUCCESS;
1947}
1948
1949/* CHANGED: no ip rip split-horizon
1950 Cisco and Zebra's command is
1951 no ip split-horizon
1952 */
1953DEFUN (no_ip_rip_split_horizon,
1954 no_ip_rip_split_horizon_cmd,
1955 "no ip rip split-horizon",
718e3744 1956 NO_STR
1957 IP_STR
16705130 1958 "Routing Information Protocol\n"
718e3744 1959 "Perform split horizon\n")
1960{
1961 struct interface *ifp;
1962 struct rip_interface *ri;
1963
1964 ifp = vty->index;
1965 ri = ifp->info;
1966
16705130 1967 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
718e3744 1968 return CMD_SUCCESS;
1969}
1970
16705130 1971ALIAS (no_ip_rip_split_horizon,
1972 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1973 "no ip rip split-horizon poisoned-reverse",
1974 NO_STR
1975 IP_STR
1976 "Routing Information Protocol\n"
1977 "Perform split horizon\n"
1978 "With poisoned-reverse\n")
1979
718e3744 1980DEFUN (rip_passive_interface,
1981 rip_passive_interface_cmd,
56e475cb 1982 "passive-interface (IFNAME|default)",
718e3744 1983 "Suppress routing updates on an interface\n"
56e475cb 1984 "Interface name\n"
1985 "default for all interfaces\n")
718e3744 1986{
4aaff3f8 1987 char *ifname = argv[0];
1988
1989 if (!strcmp(ifname,"default")) {
1990 passive_default = 1;
1991 rip_passive_nondefault_clean();
1992 return CMD_SUCCESS;
1993 }
1994 if (passive_default)
1995 return rip_passive_nondefault_unset (vty, ifname);
1996 else
1997 return rip_passive_nondefault_set (vty, ifname);
718e3744 1998}
1999
2000DEFUN (no_rip_passive_interface,
2001 no_rip_passive_interface_cmd,
56e475cb 2002 "no passive-interface (IFNAME|default)",
718e3744 2003 NO_STR
2004 "Suppress routing updates on an interface\n"
56e475cb 2005 "Interface name\n"
2006 "default for all interfaces\n")
718e3744 2007{
4aaff3f8 2008 char *ifname = argv[0];
2009
2010 if (!strcmp(ifname,"default")) {
2011 passive_default = 0;
2012 rip_passive_nondefault_clean();
2013 return CMD_SUCCESS;
2014 }
2015 if (passive_default)
2016 return rip_passive_nondefault_set (vty, ifname);
2017 else
2018 return rip_passive_nondefault_unset (vty, ifname);
718e3744 2019}
2020\f
2021/* Write rip configuration of each interface. */
2022int
2023rip_interface_config_write (struct vty *vty)
2024{
2025 listnode node;
2026 struct interface *ifp;
2027
2028 for (node = listhead (iflist); node; nextnode (node))
2029 {
2030 struct rip_interface *ri;
2031
2032 ifp = getdata (node);
2033 ri = ifp->info;
2034
16705130 2035 /* Do not display the interface if there is no
2036 * configuration about it.
2037 **/
2038 if ((!ifp->desc) &&
2039 (ri->split_horizon == ri->split_horizon_default) &&
2040 (ri->ri_send == RI_RIP_UNSPEC) &&
2041 (ri->ri_receive == RI_RIP_UNSPEC) &&
2042 (ri->auth_type != RIP_AUTH_MD5) &&
ca5e516c 2043 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
16705130 2044 (!ri->auth_str) &&
2045 (!ri->key_chain) )
2046 continue;
2047
718e3744 2048 vty_out (vty, "interface %s%s", ifp->name,
2049 VTY_NEWLINE);
2050
2051 if (ifp->desc)
2052 vty_out (vty, " description %s%s", ifp->desc,
2053 VTY_NEWLINE);
2054
2055 /* Split horizon. */
2056 if (ri->split_horizon != ri->split_horizon_default)
2057 {
16705130 2058 switch (ri->split_horizon) {
2059 case RIP_SPLIT_HORIZON:
2060 vty_out (vty, " ip rip split-horizon%s", VTY_NEWLINE);
2061 break;
2062 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
2063 vty_out (vty, " ip rip split-horizon poisoned-reverse%s",
2064 VTY_NEWLINE);
2065 break;
2066 case RIP_NO_SPLIT_HORIZON:
2067 default:
2068 vty_out (vty, " no ip rip split-horizon%s", VTY_NEWLINE);
2069 break;
2070 }
718e3744 2071 }
2072
2073 /* RIP version setting. */
2074 if (ri->ri_send != RI_RIP_UNSPEC)
2075 vty_out (vty, " ip rip send version %s%s",
2076 lookup (ri_version_msg, ri->ri_send),
2077 VTY_NEWLINE);
2078
2079 if (ri->ri_receive != RI_RIP_UNSPEC)
2080 vty_out (vty, " ip rip receive version %s%s",
2081 lookup (ri_version_msg, ri->ri_receive),
2082 VTY_NEWLINE);
2083
2084 /* RIP authentication. */
2085#if 0
2086 /* RIP_AUTH_SIMPLE_PASSWORD becomes default mode. */
2087 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
2088 vty_out (vty, " ip rip authentication mode text%s", VTY_NEWLINE);
2089#endif /* 0 */
ca5e516c 2090
718e3744 2091 if (ri->auth_type == RIP_AUTH_MD5)
ca5e516c 2092 {
2093 vty_out (vty, " ip rip authentication mode md5");
2094 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
2095 vty_out (vty, " auth-length old-ripd");
2096 else
2097 vty_out (vty, " auth-length rfc");
2098 vty_out (vty, "%s", VTY_NEWLINE);
2099 }
718e3744 2100
2101 if (ri->auth_str)
2102 vty_out (vty, " ip rip authentication string %s%s",
2103 ri->auth_str, VTY_NEWLINE);
2104
2105 if (ri->key_chain)
2106 vty_out (vty, " ip rip authentication key-chain %s%s",
2107 ri->key_chain, VTY_NEWLINE);
2108
2109 vty_out (vty, "!%s", VTY_NEWLINE);
2110 }
2111 return 0;
2112}
2113
2114int
2115config_write_rip_network (struct vty *vty, int config_mode)
2116{
2117 int i;
2118 char *ifname;
2119 struct route_node *node;
2120
2121 /* Network type RIP enable interface statement. */
2122 for (node = route_top (rip_enable_network); node; node = route_next (node))
2123 if (node->info)
2124 vty_out (vty, "%s%s/%d%s",
2125 config_mode ? " network " : " ",
2126 inet_ntoa (node->p.u.prefix4),
2127 node->p.prefixlen,
2128 VTY_NEWLINE);
2129
2130 /* Interface name RIP enable statement. */
2131 for (i = 0; i < vector_max (rip_enable_interface); i++)
2132 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
2133 vty_out (vty, "%s%s%s",
2134 config_mode ? " network " : " ",
2135 ifname,
2136 VTY_NEWLINE);
2137
2138 /* RIP neighbors listing. */
2139 for (node = route_top (rip->neighbor); node; node = route_next (node))
2140 if (node->info)
2141 vty_out (vty, "%s%s%s",
2142 config_mode ? " neighbor " : " ",
2143 inet_ntoa (node->p.u.prefix4),
2144 VTY_NEWLINE);
2145
2146 /* RIP passive interface listing. */
4aaff3f8 2147 if (config_mode) {
2148 if (passive_default)
01d0908a 2149 vty_out (vty, " passive-interface default%s", VTY_NEWLINE);
4aaff3f8 2150 for (i = 0; i < vector_max (Vrip_passive_nondefault); i++)
2151 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
2152 vty_out (vty, " %spassive-interface %s%s",
2153 (passive_default ? "no " : ""), ifname, VTY_NEWLINE);
2154 }
718e3744 2155
2156 return 0;
2157}
2158
2159struct cmd_node interface_node =
2160{
2161 INTERFACE_NODE,
2162 "%s(config-if)# ",
2163 1,
2164};
2165
2166/* Called when interface structure allocated. */
2167int
2168rip_interface_new_hook (struct interface *ifp)
2169{
2170 ifp->info = rip_interface_new ();
2171 return 0;
2172}
2173
2174/* Called when interface structure deleted. */
2175int
2176rip_interface_delete_hook (struct interface *ifp)
2177{
2178 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
16705130 2179 ifp->info = NULL;
718e3744 2180 return 0;
2181}
2182
2183/* Allocate and initialize interface vector. */
2184void
2185rip_if_init ()
2186{
2187 /* Default initial size of interface vector. */
2188 if_init();
2189 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2190 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2191
2192 /* RIP network init. */
2193 rip_enable_interface = vector_init (1);
2194 rip_enable_network = route_table_init ();
2195
2196 /* RIP passive interface. */
4aaff3f8 2197 Vrip_passive_nondefault = vector_init (1);
718e3744 2198
2199 /* Install interface node. */
2200 install_node (&interface_node, rip_interface_config_write);
2201
2202 /* Install commands. */
2203 install_element (CONFIG_NODE, &interface_cmd);
034489de 2204 install_element (CONFIG_NODE, &no_interface_cmd);
718e3744 2205 install_default (INTERFACE_NODE);
2206 install_element (INTERFACE_NODE, &interface_desc_cmd);
2207 install_element (INTERFACE_NODE, &no_interface_desc_cmd);
2208 install_element (RIP_NODE, &rip_network_cmd);
2209 install_element (RIP_NODE, &no_rip_network_cmd);
2210 install_element (RIP_NODE, &rip_neighbor_cmd);
2211 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2212
2213 install_element (RIP_NODE, &rip_passive_interface_cmd);
2214 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2215
2216 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2217 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2218 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2219 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2220 install_element (INTERFACE_NODE, &no_ip_rip_send_version_num_cmd);
2221
2222 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2223 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2224 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2225 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2226 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_num_cmd);
2227
2228 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
ca5e516c 2229 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_authlen_cmd);
718e3744 2230 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2231 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_cmd);
ca5e516c 2232 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_type_authlen_cmd);
718e3744 2233
2234 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2235 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2236 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain2_cmd);
2237
2238 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2239 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2240 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string2_cmd);
2241
16705130 2242 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2243 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2244 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2245 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
718e3744 2246}