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