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