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