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