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