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