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