]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_interface.c
*: use vty_outln
[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;
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;
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;
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;
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;
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;
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 1\n"
1331 "RIP version 2\n"
1332 "None\n")
1333 {
1334 VTY_DECLVAR_CONTEXT(interface, ifp);
1335 int idx_type = 4;
1336 struct rip_interface *ri;
1337
1338 ri = ifp->info;
1339
1340 switch (argv[idx_type]->arg[0])
1341 {
1342 case '1':
1343 ri->ri_receive = RI_RIP_VERSION_1;
1344 return CMD_SUCCESS;
1345 case '2':
1346 ri->ri_receive = RI_RIP_VERSION_2;
1347 return CMD_SUCCESS;
1348 case 'n':
1349 ri->ri_receive = RI_RIP_VERSION_NONE;
1350 return CMD_SUCCESS;
1351 default:
1352 break;
1353 }
1354
1355 return CMD_WARNING;
1356 }
1357
1358 DEFUN (ip_rip_receive_version_1,
1359 ip_rip_receive_version_1_cmd,
1360 "ip rip receive version (1-1) (2-2)",
1361 IP_STR
1362 "Routing Information Protocol\n"
1363 "Advertisement reception\n"
1364 "Version control\n"
1365 "RIP version 1\n"
1366 "RIP version 2\n")
1367 {
1368 VTY_DECLVAR_CONTEXT(interface, ifp);
1369 struct rip_interface *ri;
1370
1371 ri = ifp->info;
1372
1373 /* Version 1 and 2. */
1374 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1375 return CMD_SUCCESS;
1376 }
1377
1378 DEFUN (ip_rip_receive_version_2,
1379 ip_rip_receive_version_2_cmd,
1380 "ip rip receive version (2-2) (1-1)",
1381 IP_STR
1382 "Routing Information Protocol\n"
1383 "Advertisement reception\n"
1384 "Version control\n"
1385 "RIP version 2\n"
1386 "RIP version 1\n")
1387 {
1388 VTY_DECLVAR_CONTEXT(interface, ifp);
1389 struct rip_interface *ri;
1390
1391 ri = ifp->info;
1392
1393 /* Version 1 and 2. */
1394 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1395 return CMD_SUCCESS;
1396 }
1397
1398 DEFUN (no_ip_rip_receive_version,
1399 no_ip_rip_receive_version_cmd,
1400 "no ip rip receive version [(1-2)]",
1401 NO_STR
1402 IP_STR
1403 "Routing Information Protocol\n"
1404 "Advertisement reception\n"
1405 "Version control\n"
1406 "Version 1\n"
1407 "Version 2\n")
1408 {
1409 VTY_DECLVAR_CONTEXT(interface, ifp);
1410 struct rip_interface *ri;
1411
1412 ri = ifp->info;
1413
1414 ri->ri_receive = RI_RIP_UNSPEC;
1415 return CMD_SUCCESS;
1416 }
1417
1418
1419 DEFUN (ip_rip_send_version,
1420 ip_rip_send_version_cmd,
1421 "ip rip send version (1-2)",
1422 IP_STR
1423 "Routing Information Protocol\n"
1424 "Advertisement transmission\n"
1425 "Version control\n"
1426 "RIP version 1\n"
1427 "RIP version 2\n")
1428 {
1429 VTY_DECLVAR_CONTEXT(interface, ifp);
1430 int idx_type = 4;
1431 struct rip_interface *ri;
1432
1433 ri = ifp->info;
1434
1435 /* Version 1. */
1436 if (atoi (argv[idx_type]->arg) == 1)
1437 {
1438 ri->ri_send = RI_RIP_VERSION_1;
1439 return CMD_SUCCESS;
1440 }
1441 if (atoi (argv[idx_type]->arg) == 2)
1442 {
1443 ri->ri_send = RI_RIP_VERSION_2;
1444 return CMD_SUCCESS;
1445 }
1446 return CMD_WARNING;
1447 }
1448
1449 DEFUN (ip_rip_send_version_1,
1450 ip_rip_send_version_1_cmd,
1451 "ip rip send version (1-1) (2-2)",
1452 IP_STR
1453 "Routing Information Protocol\n"
1454 "Advertisement transmission\n"
1455 "Version control\n"
1456 "RIP version 1\n"
1457 "RIP version 2\n")
1458 {
1459 VTY_DECLVAR_CONTEXT(interface, ifp);
1460 struct rip_interface *ri;
1461
1462 ri = ifp->info;
1463
1464 /* Version 1 and 2. */
1465 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1466 return CMD_SUCCESS;
1467 }
1468
1469 DEFUN (ip_rip_send_version_2,
1470 ip_rip_send_version_2_cmd,
1471 "ip rip send version (2-2) (1-1)",
1472 IP_STR
1473 "Routing Information Protocol\n"
1474 "Advertisement transmission\n"
1475 "Version control\n"
1476 "RIP version 2\n"
1477 "RIP version 1\n")
1478 {
1479 VTY_DECLVAR_CONTEXT(interface, ifp);
1480 struct rip_interface *ri;
1481
1482 ri = ifp->info;
1483
1484 /* Version 1 and 2. */
1485 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1486 return CMD_SUCCESS;
1487 }
1488
1489 DEFUN (no_ip_rip_send_version,
1490 no_ip_rip_send_version_cmd,
1491 "no ip rip send version [(1-2)]",
1492 NO_STR
1493 IP_STR
1494 "Routing Information Protocol\n"
1495 "Advertisement transmission\n"
1496 "Version control\n"
1497 "Version 1\n"
1498 "Version 2\n")
1499 {
1500 VTY_DECLVAR_CONTEXT(interface, ifp);
1501 struct rip_interface *ri;
1502
1503 ri = ifp->info;
1504
1505 ri->ri_send = RI_RIP_UNSPEC;
1506 return CMD_SUCCESS;
1507 }
1508
1509
1510 DEFUN (ip_rip_v2_broadcast,
1511 ip_rip_v2_broadcast_cmd,
1512 "ip rip v2-broadcast",
1513 IP_STR
1514 "Routing Information Protocol\n"
1515 "Send ip broadcast v2 update\n")
1516 {
1517 VTY_DECLVAR_CONTEXT(interface, ifp);
1518 struct rip_interface *ri;
1519
1520 ri = ifp->info;
1521
1522 ri->v2_broadcast = 1;
1523 return CMD_SUCCESS;
1524 }
1525
1526 DEFUN (no_ip_rip_v2_broadcast,
1527 no_ip_rip_v2_broadcast_cmd,
1528 "no ip rip v2-broadcast",
1529 NO_STR
1530 IP_STR
1531 "Routing Information Protocol\n"
1532 "Send ip broadcast v2 update\n")
1533 {
1534 VTY_DECLVAR_CONTEXT(interface, ifp);
1535 struct rip_interface *ri;
1536
1537 ri = ifp->info;
1538
1539 ri->v2_broadcast = 0;
1540 return CMD_SUCCESS;
1541 }
1542
1543 DEFUN (ip_rip_authentication_mode,
1544 ip_rip_authentication_mode_cmd,
1545 "ip rip authentication mode <md5|text> [auth-length <rfc|old-ripd>]",
1546 IP_STR
1547 "Routing Information Protocol\n"
1548 "Authentication control\n"
1549 "Authentication mode\n"
1550 "Keyed message digest\n"
1551 "Clear text authentication\n"
1552 "MD5 authentication data length\n"
1553 "RFC compatible\n"
1554 "Old ripd compatible\n")
1555 {
1556 VTY_DECLVAR_CONTEXT(interface, ifp);
1557 char *cryptmode = argv[4]->text;
1558 char *authlen = (argc > 5) ? argv[6]->text : NULL;
1559 struct rip_interface *ri;
1560 int auth_type;
1561
1562 ri = ifp->info;
1563
1564 if (strmatch ("md5", cryptmode))
1565 auth_type = RIP_AUTH_MD5;
1566 else {
1567 assert (strmatch ("text", cryptmode));
1568 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1569 }
1570
1571 ri->auth_type = auth_type;
1572
1573 if (argc > 5)
1574 {
1575 if (auth_type != RIP_AUTH_MD5)
1576 {
1577 vty_outln (vty, "auth length argument only valid for md5");
1578 return CMD_WARNING;
1579 }
1580 if (strmatch ("rfc", authlen))
1581 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1582 else
1583 {
1584 assert (strmatch ("old-ripd", authlen));
1585 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1586 }
1587 }
1588
1589 return CMD_SUCCESS;
1590 }
1591
1592 DEFUN (no_ip_rip_authentication_mode,
1593 no_ip_rip_authentication_mode_cmd,
1594 "no ip rip authentication mode [<md5|text> [auth-length <rfc|old-ripd>]]",
1595 NO_STR
1596 IP_STR
1597 "Routing Information Protocol\n"
1598 "Authentication control\n"
1599 "Authentication mode\n"
1600 "Keyed message digest\n"
1601 "Clear text authentication\n"
1602 "MD5 authentication data length\n"
1603 "RFC compatible\n"
1604 "Old ripd compatible\n")
1605 {
1606 VTY_DECLVAR_CONTEXT(interface, ifp);
1607 struct rip_interface *ri;
1608
1609 ri = ifp->info;
1610
1611 ri->auth_type = RIP_NO_AUTH;
1612 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1613
1614 return CMD_SUCCESS;
1615 }
1616
1617 DEFUN (ip_rip_authentication_string,
1618 ip_rip_authentication_string_cmd,
1619 "ip rip authentication string LINE",
1620 IP_STR
1621 "Routing Information Protocol\n"
1622 "Authentication control\n"
1623 "Authentication string\n"
1624 "Authentication string\n")
1625 {
1626 VTY_DECLVAR_CONTEXT(interface, ifp);
1627 int idx_line = 4;
1628 struct rip_interface *ri;
1629
1630 ri = ifp->info;
1631
1632 if (strlen (argv[idx_line]->arg) > 16)
1633 {
1634 vty_outln (vty,
1635 "%% RIPv2 authentication string must be shorter than 16");
1636 return CMD_WARNING;
1637 }
1638
1639 if (ri->key_chain)
1640 {
1641 vty_outln (vty, "%% key-chain configuration exists");
1642 return CMD_WARNING;
1643 }
1644
1645 if (ri->auth_str)
1646 free (ri->auth_str);
1647
1648 ri->auth_str = strdup (argv[idx_line]->arg);
1649
1650 return CMD_SUCCESS;
1651 }
1652
1653 DEFUN (no_ip_rip_authentication_string,
1654 no_ip_rip_authentication_string_cmd,
1655 "no ip rip authentication string [LINE]",
1656 NO_STR
1657 IP_STR
1658 "Routing Information Protocol\n"
1659 "Authentication control\n"
1660 "Authentication string\n"
1661 "Authentication string\n")
1662 {
1663 VTY_DECLVAR_CONTEXT(interface, ifp);
1664 struct rip_interface *ri;
1665
1666 ri = ifp->info;
1667
1668 if (ri->auth_str)
1669 free (ri->auth_str);
1670
1671 ri->auth_str = NULL;
1672
1673 return CMD_SUCCESS;
1674 }
1675
1676
1677 DEFUN (ip_rip_authentication_key_chain,
1678 ip_rip_authentication_key_chain_cmd,
1679 "ip rip authentication key-chain LINE",
1680 IP_STR
1681 "Routing Information Protocol\n"
1682 "Authentication control\n"
1683 "Authentication key-chain\n"
1684 "name of key-chain\n")
1685 {
1686 VTY_DECLVAR_CONTEXT(interface, ifp);
1687 int idx_line = 4;
1688 struct rip_interface *ri;
1689
1690 ri = ifp->info;
1691
1692 if (ri->auth_str)
1693 {
1694 vty_outln (vty,"%% authentication string configuration exists");
1695 return CMD_WARNING;
1696 }
1697
1698 if (ri->key_chain)
1699 free (ri->key_chain);
1700
1701 ri->key_chain = strdup (argv[idx_line]->arg);
1702
1703 return CMD_SUCCESS;
1704 }
1705
1706 DEFUN (no_ip_rip_authentication_key_chain,
1707 no_ip_rip_authentication_key_chain_cmd,
1708 "no ip rip authentication key-chain [LINE]",
1709 NO_STR
1710 IP_STR
1711 "Routing Information Protocol\n"
1712 "Authentication control\n"
1713 "Authentication key-chain\n"
1714 "name of key-chain\n")
1715 {
1716 VTY_DECLVAR_CONTEXT(interface, ifp);
1717 struct rip_interface *ri;
1718
1719 ri = ifp->info;
1720
1721 if (ri->key_chain)
1722 free (ri->key_chain);
1723
1724 ri->key_chain = NULL;
1725
1726 return CMD_SUCCESS;
1727 }
1728
1729
1730 /* CHANGED: ip rip split-horizon
1731 Cisco and Zebra's command is
1732 ip split-horizon
1733 */
1734 DEFUN (ip_rip_split_horizon,
1735 ip_rip_split_horizon_cmd,
1736 "ip rip split-horizon",
1737 IP_STR
1738 "Routing Information Protocol\n"
1739 "Perform split horizon\n")
1740 {
1741 VTY_DECLVAR_CONTEXT(interface, ifp);
1742 struct rip_interface *ri;
1743
1744 ri = ifp->info;
1745
1746 ri->split_horizon = RIP_SPLIT_HORIZON;
1747 return CMD_SUCCESS;
1748 }
1749
1750 DEFUN (ip_rip_split_horizon_poisoned_reverse,
1751 ip_rip_split_horizon_poisoned_reverse_cmd,
1752 "ip rip split-horizon poisoned-reverse",
1753 IP_STR
1754 "Routing Information Protocol\n"
1755 "Perform split horizon\n"
1756 "With poisoned-reverse\n")
1757 {
1758 VTY_DECLVAR_CONTEXT(interface, ifp);
1759 struct rip_interface *ri;
1760
1761 ri = ifp->info;
1762
1763 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1764 return CMD_SUCCESS;
1765 }
1766
1767 /* CHANGED: no ip rip split-horizon
1768 Cisco and Zebra's command is
1769 no ip split-horizon
1770 */
1771 DEFUN (no_ip_rip_split_horizon,
1772 no_ip_rip_split_horizon_cmd,
1773 "no ip rip split-horizon",
1774 NO_STR
1775 IP_STR
1776 "Routing Information Protocol\n"
1777 "Perform split horizon\n")
1778 {
1779 VTY_DECLVAR_CONTEXT(interface, ifp);
1780 struct rip_interface *ri;
1781
1782 ri = ifp->info;
1783
1784 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
1785 return CMD_SUCCESS;
1786 }
1787
1788 DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
1789 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1790 "no ip rip split-horizon poisoned-reverse",
1791 NO_STR
1792 IP_STR
1793 "Routing Information Protocol\n"
1794 "Perform split horizon\n"
1795 "With poisoned-reverse\n")
1796 {
1797 VTY_DECLVAR_CONTEXT(interface, ifp);
1798 struct rip_interface *ri;
1799
1800 ri = ifp->info;
1801
1802 switch( ri->split_horizon )
1803 {
1804 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1805 ri->split_horizon = RIP_SPLIT_HORIZON;
1806 default:
1807 break;
1808 }
1809
1810 return CMD_SUCCESS;
1811 }
1812
1813 DEFUN (rip_passive_interface,
1814 rip_passive_interface_cmd,
1815 "passive-interface <IFNAME|default>",
1816 "Suppress routing updates on an interface\n"
1817 "Interface name\n"
1818 "default for all interfaces\n")
1819 {
1820 if (argv[1]->type == WORD_TKN) { // user passed 'default'
1821 passive_default = 1;
1822 rip_passive_nondefault_clean();
1823 return CMD_SUCCESS;
1824 }
1825 if (passive_default)
1826 return rip_passive_nondefault_unset (vty, argv[1]->arg);
1827 else
1828 return rip_passive_nondefault_set (vty, argv[1]->arg);
1829 }
1830
1831 DEFUN (no_rip_passive_interface,
1832 no_rip_passive_interface_cmd,
1833 "no passive-interface <IFNAME|default>",
1834 NO_STR
1835 "Suppress routing updates on an interface\n"
1836 "Interface name\n"
1837 "default for all interfaces\n")
1838 {
1839 if (argv[2]->type == WORD_TKN) {
1840 passive_default = 0;
1841 rip_passive_nondefault_clean();
1842 return CMD_SUCCESS;
1843 }
1844 if (passive_default)
1845 return rip_passive_nondefault_set (vty, argv[2]->arg);
1846 else
1847 return rip_passive_nondefault_unset (vty, argv[2]->arg);
1848 }
1849
1850 /* Write rip configuration of each interface. */
1851 static int
1852 rip_interface_config_write (struct vty *vty)
1853 {
1854 struct listnode *node;
1855 struct interface *ifp;
1856
1857 for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
1858 {
1859 struct rip_interface *ri;
1860
1861 if (ifp->ifindex == IFINDEX_DELETED)
1862 continue;
1863
1864 ri = ifp->info;
1865
1866 /* Do not display the interface if there is no
1867 * configuration about it.
1868 **/
1869 if ((!ifp->desc) &&
1870 (ri->split_horizon == ri->split_horizon_default) &&
1871 (ri->ri_send == RI_RIP_UNSPEC) &&
1872 (ri->ri_receive == RI_RIP_UNSPEC) &&
1873 (ri->auth_type != RIP_AUTH_MD5) &&
1874 (!ri->v2_broadcast) &&
1875 (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) &&
1876 (!ri->auth_str) &&
1877 (!ri->key_chain) )
1878 continue;
1879
1880 vty_outln (vty, "interface %s",ifp->name);
1881
1882 if (ifp->desc)
1883 vty_outln (vty, " description %s",ifp->desc);
1884
1885 /* Split horizon. */
1886 if (ri->split_horizon != ri->split_horizon_default)
1887 {
1888 switch (ri->split_horizon) {
1889 case RIP_SPLIT_HORIZON:
1890 vty_outln (vty, " ip rip split-horizon");
1891 break;
1892 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1893 vty_outln (vty," ip rip split-horizon poisoned-reverse");
1894 break;
1895 case RIP_NO_SPLIT_HORIZON:
1896 default:
1897 vty_outln (vty, " no ip rip split-horizon");
1898 break;
1899 }
1900 }
1901
1902 /* RIP version setting. */
1903 if (ri->ri_send != RI_RIP_UNSPEC)
1904 vty_outln (vty, " ip rip send version %s",
1905 lookup_msg(ri_version_msg, ri->ri_send, NULL));
1906
1907 if (ri->ri_receive != RI_RIP_UNSPEC)
1908 vty_outln (vty, " ip rip receive version %s ",
1909 lookup_msg(ri_version_msg, ri->ri_receive, NULL));
1910
1911 if (ri->v2_broadcast)
1912 vty_outln (vty, " ip rip v2-broadcast");
1913
1914 /* RIP authentication. */
1915 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1916 vty_outln (vty, " ip rip authentication mode text");
1917
1918 if (ri->auth_type == RIP_AUTH_MD5)
1919 {
1920 vty_out (vty, " ip rip authentication mode md5");
1921 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1922 vty_out (vty, " auth-length old-ripd");
1923 else
1924 vty_out (vty, " auth-length rfc");
1925 vty_outln (vty, "");
1926 }
1927
1928 if (ri->auth_str)
1929 vty_outln (vty, " ip rip authentication string %s",
1930 ri->auth_str);
1931
1932 if (ri->key_chain)
1933 vty_outln (vty, " ip rip authentication key-chain %s",
1934 ri->key_chain);
1935
1936 vty_outln (vty, "!");
1937 }
1938 return 0;
1939 }
1940
1941 int
1942 config_write_rip_network (struct vty *vty, int config_mode)
1943 {
1944 unsigned int i;
1945 char *ifname;
1946 struct route_node *node;
1947
1948 /* Network type RIP enable interface statement. */
1949 for (node = route_top (rip_enable_network); node; node = route_next (node))
1950 if (node->info)
1951 vty_outln (vty, "%s%s/%d",
1952 config_mode ? " network " : " ",
1953 inet_ntoa (node->p.u.prefix4),
1954 node->p.prefixlen);
1955
1956 /* Interface name RIP enable statement. */
1957 for (i = 0; i < vector_active (rip_enable_interface); i++)
1958 if ((ifname = vector_slot (rip_enable_interface, i)) != NULL)
1959 vty_outln (vty, "%s%s",
1960 config_mode ? " network " : " ",
1961 ifname);
1962
1963 /* RIP neighbors listing. */
1964 for (node = route_top (rip->neighbor); node; node = route_next (node))
1965 if (node->info)
1966 vty_outln (vty, "%s%s",
1967 config_mode ? " neighbor " : " ",
1968 inet_ntoa(node->p.u.prefix4));
1969
1970 /* RIP passive interface listing. */
1971 if (config_mode) {
1972 if (passive_default)
1973 vty_outln (vty, " passive-interface default");
1974 for (i = 0; i < vector_active (Vrip_passive_nondefault); i++)
1975 if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL)
1976 vty_outln (vty, " %spassive-interface %s",
1977 (passive_default ? "no " : ""), ifname);
1978 }
1979
1980 return 0;
1981 }
1982
1983 static struct cmd_node interface_node =
1984 {
1985 INTERFACE_NODE,
1986 "%s(config-if)# ",
1987 1,
1988 };
1989
1990 /* Called when interface structure allocated. */
1991 static int
1992 rip_interface_new_hook (struct interface *ifp)
1993 {
1994 ifp->info = rip_interface_new ();
1995 return 0;
1996 }
1997
1998 /* Called when interface structure deleted. */
1999 static int
2000 rip_interface_delete_hook (struct interface *ifp)
2001 {
2002 XFREE (MTYPE_RIP_INTERFACE, ifp->info);
2003 ifp->info = NULL;
2004 return 0;
2005 }
2006
2007 /* Allocate and initialize interface vector. */
2008 void
2009 rip_if_init (void)
2010 {
2011 /* Default initial size of interface vector. */
2012 if_add_hook (IF_NEW_HOOK, rip_interface_new_hook);
2013 if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook);
2014
2015 /* RIP network init. */
2016 rip_enable_interface = vector_init (1);
2017 rip_enable_network = route_table_init ();
2018
2019 /* RIP passive interface. */
2020 Vrip_passive_nondefault = vector_init (1);
2021
2022 /* Install interface node. */
2023 install_node (&interface_node, rip_interface_config_write);
2024 if_cmd_init ();
2025
2026 /* Install commands. */
2027 install_element (RIP_NODE, &rip_network_cmd);
2028 install_element (RIP_NODE, &no_rip_network_cmd);
2029 install_element (RIP_NODE, &rip_neighbor_cmd);
2030 install_element (RIP_NODE, &no_rip_neighbor_cmd);
2031
2032 install_element (RIP_NODE, &rip_passive_interface_cmd);
2033 install_element (RIP_NODE, &no_rip_passive_interface_cmd);
2034
2035 install_element (INTERFACE_NODE, &ip_rip_send_version_cmd);
2036 install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd);
2037 install_element (INTERFACE_NODE, &ip_rip_send_version_2_cmd);
2038 install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd);
2039
2040 install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd);
2041 install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
2042 install_element (INTERFACE_NODE, &ip_rip_receive_version_2_cmd);
2043 install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
2044
2045 install_element (INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
2046 install_element (INTERFACE_NODE, &no_ip_rip_v2_broadcast_cmd);
2047
2048 install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
2049 install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
2050
2051 install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
2052 install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd);
2053
2054 install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd);
2055 install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
2056
2057 install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd);
2058 install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd);
2059 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
2060 install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd);
2061 }