]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_interface.c
bgpd: improve default shutdown help string
[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 /* RIP enabled network vector. */
62 vector rip_enable_interface;
63
64 /* RIP enabled interface table. */
65 struct route_table *rip_enable_network;
66
67 /* Vector to store passive-interface name. */
68 static int passive_default; /* are we in passive-interface default mode? */
69 vector Vrip_passive_nondefault;
70
71 /* Join to the RIP version 2 multicast group. */
72 static int ipv4_multicast_join(int sock, struct in_addr group,
73 struct in_addr ifa, ifindex_t ifindex)
74 {
75 int ret;
76
77 ret = setsockopt_ipv4_multicast(sock, IP_ADD_MEMBERSHIP, ifa,
78 group.s_addr, ifindex);
79
80 if (ret < 0)
81 zlog_info("can't setsockopt IP_ADD_MEMBERSHIP %s",
82 safe_strerror(errno));
83
84 return ret;
85 }
86
87 /* Leave from the RIP version 2 multicast group. */
88 static int ipv4_multicast_leave(int sock, struct in_addr group,
89 struct in_addr ifa, ifindex_t ifindex)
90 {
91 int ret;
92
93 ret = setsockopt_ipv4_multicast(sock, IP_DROP_MEMBERSHIP, ifa,
94 group.s_addr, ifindex);
95
96 if (ret < 0)
97 zlog_info("can't setsockopt IP_DROP_MEMBERSHIP");
98
99 return ret;
100 }
101
102 static void rip_interface_reset(struct rip_interface *);
103
104 /* Allocate new RIP's interface configuration. */
105 static struct rip_interface *rip_interface_new(void)
106 {
107 struct rip_interface *ri;
108
109 ri = XCALLOC(MTYPE_RIP_INTERFACE, sizeof(struct rip_interface));
110
111 rip_interface_reset(ri);
112
113 return ri;
114 }
115
116 void rip_interface_multicast_set(int sock, struct connected *connected)
117 {
118 struct in_addr addr;
119
120 assert(connected != NULL);
121
122 addr = CONNECTED_ID(connected)->u.prefix4;
123
124 if (setsockopt_ipv4_multicast_if(sock, addr, connected->ifp->ifindex)
125 < 0) {
126 zlog_warn(
127 "Can't setsockopt IP_MULTICAST_IF on fd %d to "
128 "ifindex %d for interface %s",
129 sock, connected->ifp->ifindex, connected->ifp->name);
130 }
131
132 return;
133 }
134
135 /* Send RIP request packet to specified interface. */
136 static void rip_request_interface_send(struct interface *ifp, u_char version)
137 {
138 struct sockaddr_in to;
139
140 /* RIPv2 support multicast. */
141 if (version == RIPv2 && if_is_multicast(ifp)) {
142
143 if (IS_RIP_DEBUG_EVENT)
144 zlog_debug("multicast request on %s", ifp->name);
145
146 rip_request_send(NULL, ifp, version, NULL);
147 return;
148 }
149
150 /* RIPv1 and non multicast interface. */
151 if (if_is_pointopoint(ifp) || if_is_broadcast(ifp)) {
152 struct listnode *cnode, *cnnode;
153 struct connected *connected;
154
155 if (IS_RIP_DEBUG_EVENT)
156 zlog_debug("broadcast request to %s", ifp->name);
157
158 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode,
159 connected)) {
160 if (connected->address->family == AF_INET) {
161 memset(&to, 0, sizeof(struct sockaddr_in));
162 to.sin_port = htons(RIP_PORT_DEFAULT);
163 if (connected->destination)
164 /* use specified broadcast or peer
165 * destination addr */
166 to.sin_addr = connected->destination->u
167 .prefix4;
168 else if (connected->address->prefixlen
169 < IPV4_MAX_PREFIXLEN)
170 /* calculate the appropriate broadcast
171 * address */
172 to.sin_addr
173 .s_addr = ipv4_broadcast_addr(
174 connected->address->u.prefix4
175 .s_addr,
176 connected->address->prefixlen);
177 else
178 /* do not know where to send the packet
179 */
180 continue;
181
182 if (IS_RIP_DEBUG_EVENT)
183 zlog_debug("SEND request to %s",
184 inet_ntoa(to.sin_addr));
185
186 rip_request_send(&to, ifp, version, connected);
187 }
188 }
189 }
190 }
191
192 /* This will be executed when interface goes up. */
193 static void rip_request_interface(struct interface *ifp)
194 {
195 struct rip_interface *ri;
196
197 /* In default ripd doesn't send RIP_REQUEST to the loopback interface.
198 */
199 if (if_is_loopback(ifp))
200 return;
201
202 /* If interface is down, don't send RIP packet. */
203 if (!if_is_operative(ifp))
204 return;
205
206 /* Fetch RIP interface information. */
207 ri = ifp->info;
208
209
210 /* If there is no version configuration in the interface,
211 use rip's version setting. */
212 {
213 int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? rip->version_send
214 : ri->ri_send);
215 if (vsend & RIPv1)
216 rip_request_interface_send(ifp, RIPv1);
217 if (vsend & RIPv2)
218 rip_request_interface_send(ifp, RIPv2);
219 }
220 }
221
222 #if 0
223 /* Send RIP request to the neighbor. */
224 static void
225 rip_request_neighbor (struct in_addr addr)
226 {
227 struct sockaddr_in to;
228
229 memset (&to, 0, sizeof (struct sockaddr_in));
230 to.sin_port = htons (RIP_PORT_DEFAULT);
231 to.sin_addr = addr;
232
233 rip_request_send (&to, NULL, rip->version_send, NULL);
234 }
235
236 /* Request routes at all interfaces. */
237 static void
238 rip_request_neighbor_all (void)
239 {
240 struct route_node *rp;
241
242 if (! rip)
243 return;
244
245 if (IS_RIP_DEBUG_EVENT)
246 zlog_debug ("request to the all neighbor");
247
248 /* Send request to all neighbor. */
249 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
250 if (rp->info)
251 rip_request_neighbor (rp->p.u.prefix4);
252 }
253 #endif
254
255 /* Multicast packet receive socket. */
256 static int rip_multicast_join(struct interface *ifp, int sock)
257 {
258 struct listnode *cnode;
259 struct connected *ifc;
260
261 if (if_is_operative(ifp) && if_is_multicast(ifp)) {
262 if (IS_RIP_DEBUG_EVENT)
263 zlog_debug("multicast join at %s", ifp->name);
264
265 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
266 struct prefix_ipv4 *p;
267 struct in_addr group;
268
269 p = (struct prefix_ipv4 *)ifc->address;
270
271 if (p->family != AF_INET)
272 continue;
273
274 group.s_addr = htonl(INADDR_RIP_GROUP);
275 if (ipv4_multicast_join(sock, group, p->prefix,
276 ifp->ifindex)
277 < 0)
278 return -1;
279 else
280 return 0;
281 }
282 }
283 return 0;
284 }
285
286 /* Leave from multicast group. */
287 static void rip_multicast_leave(struct interface *ifp, int sock)
288 {
289 struct listnode *cnode;
290 struct connected *connected;
291
292 if (if_is_up(ifp) && if_is_multicast(ifp)) {
293 if (IS_RIP_DEBUG_EVENT)
294 zlog_debug("multicast leave from %s", ifp->name);
295
296 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
297 struct prefix_ipv4 *p;
298 struct in_addr group;
299
300 p = (struct prefix_ipv4 *)connected->address;
301
302 if (p->family != AF_INET)
303 continue;
304
305 group.s_addr = htonl(INADDR_RIP_GROUP);
306 if (ipv4_multicast_leave(sock, group, p->prefix,
307 ifp->ifindex)
308 == 0)
309 return;
310 }
311 }
312 }
313
314 /* Is there and address on interface that I could use ? */
315 static int rip_if_ipv4_address_check(struct interface *ifp)
316 {
317 struct listnode *nn;
318 struct connected *connected;
319 int count = 0;
320
321 for (ALL_LIST_ELEMENTS_RO(ifp->connected, nn, connected)) {
322 struct prefix *p;
323
324 p = connected->address;
325
326 if (p->family == AF_INET)
327 count++;
328 }
329
330 return count;
331 }
332
333
334 /* Does this address belongs to me ? */
335 int if_check_address(struct in_addr addr)
336 {
337 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
338 struct interface *ifp;
339
340 FOR_ALL_INTERFACES (vrf, ifp) {
341 struct listnode *cnode;
342 struct connected *connected;
343
344 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
345 struct prefix_ipv4 *p;
346
347 p = (struct prefix_ipv4 *)connected->address;
348
349 if (p->family != AF_INET)
350 continue;
351
352 if (IPV4_ADDR_CMP(&p->prefix, &addr) == 0)
353 return 1;
354 }
355 }
356 return 0;
357 }
358
359 /* Inteface link down message processing. */
360 int rip_interface_down(int command, struct zclient *zclient,
361 zebra_size_t length, vrf_id_t vrf_id)
362 {
363 struct interface *ifp;
364 struct stream *s;
365
366 s = zclient->ibuf;
367
368 /* zebra_interface_state_read() updates interface structure in
369 iflist. */
370 ifp = zebra_interface_state_read(s, vrf_id);
371
372 if (ifp == NULL)
373 return 0;
374
375 rip_if_down(ifp);
376
377 if (IS_RIP_DEBUG_ZEBRA)
378 zlog_debug(
379 "interface %s index %d flags %llx metric %d mtu %d is down",
380 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
381 ifp->metric, ifp->mtu);
382
383 return 0;
384 }
385
386 /* Inteface link up message processing */
387 int rip_interface_up(int command, struct zclient *zclient, zebra_size_t length,
388 vrf_id_t vrf_id)
389 {
390 struct interface *ifp;
391
392 /* zebra_interface_state_read () updates interface structure in
393 iflist. */
394 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
395
396 if (ifp == NULL)
397 return 0;
398
399 if (IS_RIP_DEBUG_ZEBRA)
400 zlog_debug(
401 "interface %s index %d flags %#llx metric %d mtu %d is up",
402 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
403 ifp->metric, ifp->mtu);
404
405 /* Check if this interface is RIP enabled or not.*/
406 rip_enable_apply(ifp);
407
408 /* Check for a passive interface */
409 rip_passive_interface_apply(ifp);
410
411 /* Apply distribute list to the all interface. */
412 rip_distribute_update_interface(ifp);
413
414 return 0;
415 }
416
417 /* Inteface addition message from zebra. */
418 int rip_interface_add(int command, struct zclient *zclient, zebra_size_t length,
419 vrf_id_t vrf_id)
420 {
421 struct interface *ifp;
422
423 ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
424
425 if (IS_RIP_DEBUG_ZEBRA)
426 zlog_debug(
427 "interface add %s index %d flags %#llx metric %d mtu %d",
428 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
429 ifp->metric, ifp->mtu);
430
431 /* Check if this interface is RIP enabled or not.*/
432 rip_enable_apply(ifp);
433
434 /* Check for a passive interface */
435 rip_passive_interface_apply(ifp);
436
437 /* Apply distribute list to the all interface. */
438 rip_distribute_update_interface(ifp);
439
440 /* rip_request_neighbor_all (); */
441
442 /* Check interface routemap. */
443 rip_if_rmap_update_interface(ifp);
444
445 return 0;
446 }
447
448 int rip_interface_delete(int command, struct zclient *zclient,
449 zebra_size_t length, vrf_id_t vrf_id)
450 {
451 struct interface *ifp;
452 struct stream *s;
453
454
455 s = zclient->ibuf;
456 /* zebra_interface_state_read() updates interface structure in iflist */
457 ifp = zebra_interface_state_read(s, vrf_id);
458
459 if (ifp == NULL)
460 return 0;
461
462 if (if_is_up(ifp)) {
463 rip_if_down(ifp);
464 }
465
466 zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
467 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
468 ifp->metric, ifp->mtu);
469
470 /* To support pseudo interface do not free interface structure. */
471 /* if_delete(ifp); */
472 if_set_index(ifp, IFINDEX_INTERNAL);
473
474 return 0;
475 }
476
477 static void rip_interface_clean(struct rip_interface *ri)
478 {
479 ri->enable_network = 0;
480 ri->enable_interface = 0;
481 ri->running = 0;
482
483 if (ri->t_wakeup) {
484 thread_cancel(ri->t_wakeup);
485 ri->t_wakeup = NULL;
486 }
487 }
488
489 void rip_interfaces_clean(void)
490 {
491 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
492 struct interface *ifp;
493
494 FOR_ALL_INTERFACES (vrf, ifp)
495 rip_interface_clean(ifp->info);
496 }
497
498 static void rip_interface_reset(struct rip_interface *ri)
499 {
500 /* Default authentication type is simple password for Cisco
501 compatibility. */
502 ri->auth_type = RIP_NO_AUTH;
503 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
504
505 /* Set default split-horizon behavior. If the interface is Frame
506 Relay or SMDS is enabled, the default value for split-horizon is
507 off. But currently Zebra does detect Frame Relay or SMDS
508 interface. So all interface is set to split horizon. */
509 ri->split_horizon_default = RIP_SPLIT_HORIZON;
510 ri->split_horizon = ri->split_horizon_default;
511
512 ri->ri_send = RI_RIP_UNSPEC;
513 ri->ri_receive = RI_RIP_UNSPEC;
514
515 ri->v2_broadcast = 0;
516
517 if (ri->auth_str) {
518 free(ri->auth_str);
519 ri->auth_str = NULL;
520 }
521 if (ri->key_chain) {
522 free(ri->key_chain);
523 ri->key_chain = NULL;
524 }
525
526 ri->list[RIP_FILTER_IN] = NULL;
527 ri->list[RIP_FILTER_OUT] = NULL;
528
529 ri->prefix[RIP_FILTER_IN] = NULL;
530 ri->prefix[RIP_FILTER_OUT] = NULL;
531
532 ri->recv_badpackets = 0;
533 ri->recv_badroutes = 0;
534 ri->sent_updates = 0;
535
536 ri->passive = 0;
537
538 rip_interface_clean(ri);
539 }
540
541 void rip_interfaces_reset(void)
542 {
543 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
544 struct interface *ifp;
545
546 FOR_ALL_INTERFACES (vrf, ifp)
547 rip_interface_reset(ifp->info);
548 }
549
550 int rip_if_down(struct interface *ifp)
551 {
552 struct route_node *rp;
553 struct rip_info *rinfo;
554 struct rip_interface *ri = NULL;
555 struct list *list = NULL;
556 struct listnode *listnode = NULL, *nextnode = NULL;
557 if (rip) {
558 for (rp = route_top(rip->table); rp; rp = route_next(rp))
559 if ((list = rp->info) != NULL)
560 for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
561 rinfo))
562 if (rinfo->nh.ifindex == ifp->ifindex)
563 rip_ecmp_delete(rinfo);
564
565 ri = ifp->info;
566
567 if (ri->running) {
568 if (IS_RIP_DEBUG_EVENT)
569 zlog_debug("turn off %s", ifp->name);
570
571 /* Leave from multicast group. */
572 rip_multicast_leave(ifp, rip->sock);
573
574 ri->running = 0;
575 }
576 }
577
578 return 0;
579 }
580
581 /* Needed for stop RIP process. */
582 void rip_if_down_all()
583 {
584 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
585 struct interface *ifp;
586
587 FOR_ALL_INTERFACES (vrf, ifp)
588 rip_if_down(ifp);
589 }
590
591 static void rip_apply_address_add(struct connected *ifc)
592 {
593 struct prefix_ipv4 address;
594 struct nexthop nh;
595 struct prefix *p;
596
597 if (!rip)
598 return;
599
600 if (!if_is_up(ifc->ifp))
601 return;
602
603 p = ifc->address;
604
605 memset(&address, 0, sizeof(address));
606 memset(&nh, 0, sizeof(nh));
607
608 address.family = p->family;
609 address.prefix = p->u.prefix4;
610 address.prefixlen = p->prefixlen;
611 apply_mask_ipv4(&address);
612
613 nh.ifindex = ifc->ifp->ifindex;
614 nh.type = NEXTHOP_TYPE_IFINDEX;
615
616 /* Check if this interface is RIP enabled or not
617 or Check if this address's prefix is RIP enabled */
618 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0)
619 || (rip_enable_network_lookup2(ifc) >= 0))
620 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
621 &address, &nh, 0, 0, 0);
622 }
623
624 int rip_interface_address_add(int command, struct zclient *zclient,
625 zebra_size_t length, vrf_id_t vrf_id)
626 {
627 struct connected *ifc;
628 struct prefix *p;
629
630 ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
631 zclient->ibuf, vrf_id);
632
633 if (ifc == NULL)
634 return 0;
635
636 p = ifc->address;
637
638 if (p->family == AF_INET) {
639 if (IS_RIP_DEBUG_ZEBRA)
640 zlog_debug("connected address %s/%d is added",
641 inet_ntoa(p->u.prefix4), p->prefixlen);
642
643 rip_enable_apply(ifc->ifp);
644 /* Check if this prefix needs to be redistributed */
645 rip_apply_address_add(ifc);
646
647 hook_call(rip_ifaddr_add, ifc);
648 }
649
650 return 0;
651 }
652
653 static void rip_apply_address_del(struct connected *ifc)
654 {
655 struct prefix_ipv4 address;
656 struct prefix *p;
657
658 if (!rip)
659 return;
660
661 if (!if_is_up(ifc->ifp))
662 return;
663
664 p = ifc->address;
665
666 memset(&address, 0, sizeof(address));
667 address.family = p->family;
668 address.prefix = p->u.prefix4;
669 address.prefixlen = p->prefixlen;
670 apply_mask_ipv4(&address);
671
672 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
673 &address, ifc->ifp->ifindex);
674 }
675
676 int rip_interface_address_delete(int command, struct zclient *zclient,
677 zebra_size_t length, vrf_id_t vrf_id)
678 {
679 struct connected *ifc;
680 struct prefix *p;
681
682 ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
683 zclient->ibuf, vrf_id);
684
685 if (ifc) {
686 p = ifc->address;
687 if (p->family == AF_INET) {
688 if (IS_RIP_DEBUG_ZEBRA)
689 zlog_debug("connected address %s/%d is deleted",
690 inet_ntoa(p->u.prefix4),
691 p->prefixlen);
692
693 hook_call(rip_ifaddr_del, ifc);
694
695 /* Chech wether this prefix needs to be removed */
696 rip_apply_address_del(ifc);
697 }
698
699 connected_free(ifc);
700 }
701
702 return 0;
703 }
704
705 /* Check interface is enabled by network statement. */
706 /* Check wether the interface has at least a connected prefix that
707 * is within the ripng_enable_network table. */
708 static int rip_enable_network_lookup_if(struct interface *ifp)
709 {
710 struct listnode *node, *nnode;
711 struct connected *connected;
712 struct prefix_ipv4 address;
713
714 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
715 struct prefix *p;
716 struct route_node *node;
717
718 p = connected->address;
719
720 if (p->family == AF_INET) {
721 address.family = AF_INET;
722 address.prefix = p->u.prefix4;
723 address.prefixlen = IPV4_MAX_BITLEN;
724
725 node = route_node_match(rip_enable_network,
726 (struct prefix *)&address);
727 if (node) {
728 route_unlock_node(node);
729 return 1;
730 }
731 }
732 }
733 return -1;
734 }
735
736 /* Check wether connected is within the ripng_enable_network table. */
737 int rip_enable_network_lookup2(struct connected *connected)
738 {
739 struct prefix_ipv4 address;
740 struct prefix *p;
741
742 p = connected->address;
743
744 if (p->family == AF_INET) {
745 struct route_node *node;
746
747 address.family = p->family;
748 address.prefix = p->u.prefix4;
749 address.prefixlen = IPV4_MAX_BITLEN;
750
751 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within
752 * rip_enable_network */
753 node = route_node_match(rip_enable_network,
754 (struct prefix *)&address);
755
756 if (node) {
757 route_unlock_node(node);
758 return 1;
759 }
760 }
761
762 return -1;
763 }
764 /* Add RIP enable network. */
765 static int rip_enable_network_add(struct prefix *p)
766 {
767 struct route_node *node;
768
769 node = route_node_get(rip_enable_network, p);
770
771 if (node->info) {
772 route_unlock_node(node);
773 return -1;
774 } else
775 node->info = (void *)1;
776
777 /* XXX: One should find a better solution than a generic one */
778 rip_enable_apply_all();
779
780 return 1;
781 }
782
783 /* Delete RIP enable network. */
784 static int rip_enable_network_delete(struct prefix *p)
785 {
786 struct route_node *node;
787
788 node = route_node_lookup(rip_enable_network, p);
789 if (node) {
790 node->info = NULL;
791
792 /* Unlock info lock. */
793 route_unlock_node(node);
794
795 /* Unlock lookup lock. */
796 route_unlock_node(node);
797
798 /* XXX: One should find a better solution than a generic one */
799 rip_enable_apply_all();
800
801 return 1;
802 }
803 return -1;
804 }
805
806 /* Check interface is enabled by ifname statement. */
807 static int rip_enable_if_lookup(const char *ifname)
808 {
809 unsigned int i;
810 char *str;
811
812 for (i = 0; i < vector_active(rip_enable_interface); i++)
813 if ((str = vector_slot(rip_enable_interface, i)) != NULL)
814 if (strcmp(str, ifname) == 0)
815 return i;
816 return -1;
817 }
818
819 /* Add interface to rip_enable_if. */
820 static int rip_enable_if_add(const char *ifname)
821 {
822 int ret;
823
824 ret = rip_enable_if_lookup(ifname);
825 if (ret >= 0)
826 return -1;
827
828 vector_set(rip_enable_interface, strdup(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 free(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_err("multicast join failed, interface %s not running",
869 ifp->name);
870 return 0;
871 }
872
873 /* Set running flag. */
874 ri->running = 1;
875
876 /* Send RIP request to the interface. */
877 rip_request_interface(ifp);
878
879 return 0;
880 }
881
882 static void rip_connect_set(struct interface *ifp, int set)
883 {
884 struct listnode *node, *nnode;
885 struct connected *connected;
886 struct prefix_ipv4 address;
887 struct nexthop nh;
888
889 memset(&nh, 0, sizeof(nh));
890
891 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
892 struct prefix *p;
893 p = connected->address;
894
895 if (p->family != AF_INET)
896 continue;
897
898 address.family = AF_INET;
899 address.prefix = p->u.prefix4;
900 address.prefixlen = p->prefixlen;
901 apply_mask_ipv4(&address);
902
903 nh.ifindex = connected->ifp->ifindex;
904 nh.type = NEXTHOP_TYPE_IFINDEX;
905 if (set) {
906 /* Check once more wether this prefix is within a
907 * "network IF_OR_PREF" one */
908 if ((rip_enable_if_lookup(connected->ifp->name) >= 0)
909 || (rip_enable_network_lookup2(connected) >= 0))
910 rip_redistribute_add(
911 ZEBRA_ROUTE_CONNECT,
912 RIP_ROUTE_INTERFACE, &address,
913 &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(
920 ZEBRA_ROUTE_CONNECT,
921 RIP_ROUTE_REDISTRIBUTE, &address,
922 &nh, 0, 0, 0);
923 }
924 }
925 }
926
927 /* Update interface status. */
928 void rip_enable_apply(struct interface *ifp)
929 {
930 int ret;
931 struct rip_interface *ri = NULL;
932
933 /* Check interface. */
934 if (!if_is_operative(ifp))
935 return;
936
937 ri = ifp->info;
938
939 /* Check network configuration. */
940 ret = rip_enable_network_lookup_if(ifp);
941
942 /* If the interface is matched. */
943 if (ret > 0)
944 ri->enable_network = 1;
945 else
946 ri->enable_network = 0;
947
948 /* Check interface name configuration. */
949 ret = rip_enable_if_lookup(ifp->name);
950 if (ret >= 0)
951 ri->enable_interface = 1;
952 else
953 ri->enable_interface = 0;
954
955 /* any interface MUST have an IPv4 address */
956 if (!rip_if_ipv4_address_check(ifp)) {
957 ri->enable_network = 0;
958 ri->enable_interface = 0;
959 }
960
961 /* Update running status of the interface. */
962 if (ri->enable_network || ri->enable_interface) {
963 {
964 if (IS_RIP_DEBUG_EVENT)
965 zlog_debug("turn on %s", ifp->name);
966
967 /* Add interface wake up thread. */
968 thread_add_timer(master, rip_interface_wakeup, ifp, 1,
969 &ri->t_wakeup);
970 rip_connect_set(ifp, 1);
971 }
972 } else {
973 if (ri->running) {
974 /* Might as well clean up the route table as well
975 * rip_if_down sets to 0 ri->running, and displays "turn
976 *off %s"
977 **/
978 rip_if_down(ifp);
979
980 rip_connect_set(ifp, 0);
981 }
982 }
983 }
984
985 /* Apply network configuration to all interface. */
986 void rip_enable_apply_all()
987 {
988 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
989 struct interface *ifp;
990
991 /* Check each interface. */
992 FOR_ALL_INTERFACES (vrf, ifp)
993 rip_enable_apply(ifp);
994 }
995
996 int rip_neighbor_lookup(struct sockaddr_in *from)
997 {
998 struct prefix_ipv4 p;
999 struct route_node *node;
1000
1001 memset(&p, 0, sizeof(struct prefix_ipv4));
1002 p.family = AF_INET;
1003 p.prefix = from->sin_addr;
1004 p.prefixlen = IPV4_MAX_BITLEN;
1005
1006 node = route_node_lookup(rip->neighbor, (struct prefix *)&p);
1007 if (node) {
1008 route_unlock_node(node);
1009 return 1;
1010 }
1011 return 0;
1012 }
1013
1014 /* Add new RIP neighbor to the neighbor tree. */
1015 static int rip_neighbor_add(struct prefix_ipv4 *p)
1016 {
1017 struct route_node *node;
1018
1019 node = route_node_get(rip->neighbor, (struct prefix *)p);
1020
1021 if (node->info)
1022 return -1;
1023
1024 node->info = rip->neighbor;
1025
1026 return 0;
1027 }
1028
1029 /* Delete RIP neighbor from the neighbor tree. */
1030 static int rip_neighbor_delete(struct prefix_ipv4 *p)
1031 {
1032 struct route_node *node;
1033
1034 /* Lock for look up. */
1035 node = route_node_lookup(rip->neighbor, (struct prefix *)p);
1036 if (!node)
1037 return -1;
1038
1039 node->info = NULL;
1040
1041 /* Unlock lookup lock. */
1042 route_unlock_node(node);
1043
1044 /* Unlock real neighbor information lock. */
1045 route_unlock_node(node);
1046
1047 return 0;
1048 }
1049
1050 /* Clear all network and neighbor configuration. */
1051 void rip_clean_network()
1052 {
1053 unsigned int i;
1054 char *str;
1055 struct route_node *rn;
1056
1057 /* rip_enable_network. */
1058 for (rn = route_top(rip_enable_network); rn; rn = route_next(rn))
1059 if (rn->info) {
1060 rn->info = NULL;
1061 route_unlock_node(rn);
1062 }
1063
1064 /* rip_enable_interface. */
1065 for (i = 0; i < vector_active(rip_enable_interface); i++)
1066 if ((str = vector_slot(rip_enable_interface, i)) != NULL) {
1067 free(str);
1068 vector_slot(rip_enable_interface, i) = NULL;
1069 }
1070 }
1071
1072 /* Utility function for looking up passive interface settings. */
1073 static int rip_passive_nondefault_lookup(const char *ifname)
1074 {
1075 unsigned int i;
1076 char *str;
1077
1078 for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
1079 if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL)
1080 if (strcmp(str, ifname) == 0)
1081 return i;
1082 return -1;
1083 }
1084
1085 void rip_passive_interface_apply(struct interface *ifp)
1086 {
1087 struct rip_interface *ri;
1088
1089 ri = ifp->info;
1090
1091 ri->passive = ((rip_passive_nondefault_lookup(ifp->name) < 0)
1092 ? passive_default
1093 : !passive_default);
1094
1095 if (IS_RIP_DEBUG_ZEBRA)
1096 zlog_debug("interface %s: passive = %d", ifp->name,
1097 ri->passive);
1098 }
1099
1100 static void rip_passive_interface_apply_all(void)
1101 {
1102 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1103 struct interface *ifp;
1104
1105 FOR_ALL_INTERFACES (vrf, ifp)
1106 rip_passive_interface_apply(ifp);
1107 }
1108
1109 /* Passive interface. */
1110 static int rip_passive_nondefault_set(struct vty *vty, const char *ifname)
1111 {
1112 if (rip_passive_nondefault_lookup(ifname) >= 0)
1113 return CMD_WARNING_CONFIG_FAILED;
1114
1115 vector_set(Vrip_passive_nondefault, strdup(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 free(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 free(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 free(ri->auth_str);
1535
1536 ri->auth_str = strdup(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 free(ri->auth_str);
1558
1559 ri->auth_str = NULL;
1560
1561 return CMD_SUCCESS;
1562 }
1563
1564
1565 DEFUN (ip_rip_authentication_key_chain,
1566 ip_rip_authentication_key_chain_cmd,
1567 "ip rip authentication key-chain LINE",
1568 IP_STR
1569 "Routing Information Protocol\n"
1570 "Authentication control\n"
1571 "Authentication key-chain\n"
1572 "name of key-chain\n")
1573 {
1574 VTY_DECLVAR_CONTEXT(interface, ifp);
1575 int idx_line = 4;
1576 struct rip_interface *ri;
1577
1578 ri = ifp->info;
1579
1580 if (ri->auth_str) {
1581 vty_out(vty, "%% authentication string configuration exists\n");
1582 return CMD_WARNING_CONFIG_FAILED;
1583 }
1584
1585 if (ri->key_chain)
1586 free(ri->key_chain);
1587
1588 ri->key_chain = strdup(argv[idx_line]->arg);
1589
1590 return CMD_SUCCESS;
1591 }
1592
1593 DEFUN (no_ip_rip_authentication_key_chain,
1594 no_ip_rip_authentication_key_chain_cmd,
1595 "no ip rip authentication key-chain [LINE]",
1596 NO_STR
1597 IP_STR
1598 "Routing Information Protocol\n"
1599 "Authentication control\n"
1600 "Authentication key-chain\n"
1601 "name of key-chain\n")
1602 {
1603 VTY_DECLVAR_CONTEXT(interface, ifp);
1604 struct rip_interface *ri;
1605
1606 ri = ifp->info;
1607
1608 if (ri->key_chain)
1609 free(ri->key_chain);
1610
1611 ri->key_chain = NULL;
1612
1613 return CMD_SUCCESS;
1614 }
1615
1616
1617 /* CHANGED: ip rip split-horizon
1618 Cisco and Zebra's command is
1619 ip split-horizon
1620 */
1621 DEFUN (ip_rip_split_horizon,
1622 ip_rip_split_horizon_cmd,
1623 "ip rip split-horizon",
1624 IP_STR
1625 "Routing Information Protocol\n"
1626 "Perform split horizon\n")
1627 {
1628 VTY_DECLVAR_CONTEXT(interface, ifp);
1629 struct rip_interface *ri;
1630
1631 ri = ifp->info;
1632
1633 ri->split_horizon = RIP_SPLIT_HORIZON;
1634 return CMD_SUCCESS;
1635 }
1636
1637 DEFUN (ip_rip_split_horizon_poisoned_reverse,
1638 ip_rip_split_horizon_poisoned_reverse_cmd,
1639 "ip rip split-horizon poisoned-reverse",
1640 IP_STR
1641 "Routing Information Protocol\n"
1642 "Perform split horizon\n"
1643 "With poisoned-reverse\n")
1644 {
1645 VTY_DECLVAR_CONTEXT(interface, ifp);
1646 struct rip_interface *ri;
1647
1648 ri = ifp->info;
1649
1650 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1651 return CMD_SUCCESS;
1652 }
1653
1654 /* CHANGED: no ip rip split-horizon
1655 Cisco and Zebra's command is
1656 no ip split-horizon
1657 */
1658 DEFUN (no_ip_rip_split_horizon,
1659 no_ip_rip_split_horizon_cmd,
1660 "no ip rip split-horizon",
1661 NO_STR
1662 IP_STR
1663 "Routing Information Protocol\n"
1664 "Perform split horizon\n")
1665 {
1666 VTY_DECLVAR_CONTEXT(interface, ifp);
1667 struct rip_interface *ri;
1668
1669 ri = ifp->info;
1670
1671 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
1672 return CMD_SUCCESS;
1673 }
1674
1675 DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
1676 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1677 "no ip rip split-horizon poisoned-reverse",
1678 NO_STR
1679 IP_STR
1680 "Routing Information Protocol\n"
1681 "Perform split horizon\n"
1682 "With poisoned-reverse\n")
1683 {
1684 VTY_DECLVAR_CONTEXT(interface, ifp);
1685 struct rip_interface *ri;
1686
1687 ri = ifp->info;
1688
1689 switch (ri->split_horizon) {
1690 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1691 ri->split_horizon = RIP_SPLIT_HORIZON;
1692 default:
1693 break;
1694 }
1695
1696 return CMD_SUCCESS;
1697 }
1698
1699 DEFUN (rip_passive_interface,
1700 rip_passive_interface_cmd,
1701 "passive-interface <IFNAME|default>",
1702 "Suppress routing updates on an interface\n"
1703 "Interface name\n"
1704 "default for all interfaces\n")
1705 {
1706 if (argv[1]->type == WORD_TKN) { // user passed 'default'
1707 passive_default = 1;
1708 rip_passive_nondefault_clean();
1709 return CMD_SUCCESS;
1710 }
1711 if (passive_default)
1712 return rip_passive_nondefault_unset(vty, argv[1]->arg);
1713 else
1714 return rip_passive_nondefault_set(vty, argv[1]->arg);
1715 }
1716
1717 DEFUN (no_rip_passive_interface,
1718 no_rip_passive_interface_cmd,
1719 "no passive-interface <IFNAME|default>",
1720 NO_STR
1721 "Suppress routing updates on an interface\n"
1722 "Interface name\n"
1723 "default for all interfaces\n")
1724 {
1725 if (argv[2]->type == WORD_TKN) {
1726 passive_default = 0;
1727 rip_passive_nondefault_clean();
1728 return CMD_SUCCESS;
1729 }
1730 if (passive_default)
1731 return rip_passive_nondefault_set(vty, argv[2]->arg);
1732 else
1733 return rip_passive_nondefault_unset(vty, argv[2]->arg);
1734 }
1735
1736 /* Write rip configuration of each interface. */
1737 static int rip_interface_config_write(struct vty *vty)
1738 {
1739 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1740 struct interface *ifp;
1741
1742 FOR_ALL_INTERFACES (vrf, ifp) {
1743 struct rip_interface *ri;
1744
1745 ri = ifp->info;
1746
1747 /* Do not display the interface if there is no
1748 * configuration about it.
1749 **/
1750 if ((!ifp->desc)
1751 && (ri->split_horizon == ri->split_horizon_default)
1752 && (ri->ri_send == RI_RIP_UNSPEC)
1753 && (ri->ri_receive == RI_RIP_UNSPEC)
1754 && (ri->auth_type != RIP_AUTH_MD5) && (!ri->v2_broadcast)
1755 && (ri->md5_auth_len != RIP_AUTH_MD5_SIZE)
1756 && (!ri->auth_str) && (!ri->key_chain))
1757 continue;
1758
1759 vty_frame(vty, "interface %s\n", ifp->name);
1760
1761 if (ifp->desc)
1762 vty_out(vty, " description %s\n", ifp->desc);
1763
1764 /* Split horizon. */
1765 if (ri->split_horizon != ri->split_horizon_default) {
1766 switch (ri->split_horizon) {
1767 case RIP_SPLIT_HORIZON:
1768 vty_out(vty, " ip rip split-horizon\n");
1769 break;
1770 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1771 vty_out(vty,
1772 " ip rip split-horizon poisoned-reverse\n");
1773 break;
1774 case RIP_NO_SPLIT_HORIZON:
1775 default:
1776 vty_out(vty, " no ip rip split-horizon\n");
1777 break;
1778 }
1779 }
1780
1781 /* RIP version setting. */
1782 if (ri->ri_send != RI_RIP_UNSPEC)
1783 vty_out(vty, " ip rip send version %s\n",
1784 lookup_msg(ri_version_msg, ri->ri_send, NULL));
1785
1786 if (ri->ri_receive != RI_RIP_UNSPEC)
1787 vty_out(vty, " ip rip receive version %s \n",
1788 lookup_msg(ri_version_msg, ri->ri_receive,
1789 NULL));
1790
1791 if (ri->v2_broadcast)
1792 vty_out(vty, " ip rip v2-broadcast\n");
1793
1794 /* RIP authentication. */
1795 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1796 vty_out(vty, " ip rip authentication mode text\n");
1797
1798 if (ri->auth_type == RIP_AUTH_MD5) {
1799 vty_out(vty, " ip rip authentication mode md5");
1800 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1801 vty_out(vty, " auth-length old-ripd");
1802 else
1803 vty_out(vty, " auth-length rfc");
1804 vty_out(vty, "\n");
1805 }
1806
1807 if (ri->auth_str)
1808 vty_out(vty, " ip rip authentication string %s\n",
1809 ri->auth_str);
1810
1811 if (ri->key_chain)
1812 vty_out(vty, " ip rip authentication key-chain %s\n",
1813 ri->key_chain);
1814
1815 vty_endframe(vty, "!\n");
1816 }
1817 return 0;
1818 }
1819
1820 int config_write_rip_network(struct vty *vty, int config_mode)
1821 {
1822 unsigned int i;
1823 char *ifname;
1824 struct route_node *node;
1825
1826 /* Network type RIP enable interface statement. */
1827 for (node = route_top(rip_enable_network); node;
1828 node = route_next(node))
1829 if (node->info)
1830 vty_out(vty, "%s%s/%d\n",
1831 config_mode ? " network " : " ",
1832 inet_ntoa(node->p.u.prefix4),
1833 node->p.prefixlen);
1834
1835 /* Interface name RIP enable statement. */
1836 for (i = 0; i < vector_active(rip_enable_interface); i++)
1837 if ((ifname = vector_slot(rip_enable_interface, i)) != NULL)
1838 vty_out(vty, "%s%s\n",
1839 config_mode ? " network " : " ", ifname);
1840
1841 /* RIP neighbors listing. */
1842 for (node = route_top(rip->neighbor); node; node = route_next(node))
1843 if (node->info)
1844 vty_out(vty, "%s%s\n",
1845 config_mode ? " neighbor " : " ",
1846 inet_ntoa(node->p.u.prefix4));
1847
1848 /* RIP passive interface listing. */
1849 if (config_mode) {
1850 if (passive_default)
1851 vty_out(vty, " passive-interface default\n");
1852 for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
1853 if ((ifname = vector_slot(Vrip_passive_nondefault, i))
1854 != NULL)
1855 vty_out(vty, " %spassive-interface %s\n",
1856 (passive_default ? "no " : ""), ifname);
1857 }
1858
1859 return 0;
1860 }
1861
1862 static struct cmd_node interface_node = {
1863 INTERFACE_NODE, "%s(config-if)# ", 1,
1864 };
1865
1866 /* Called when interface structure allocated. */
1867 static int rip_interface_new_hook(struct interface *ifp)
1868 {
1869 ifp->info = rip_interface_new();
1870 return 0;
1871 }
1872
1873 /* Called when interface structure deleted. */
1874 static int rip_interface_delete_hook(struct interface *ifp)
1875 {
1876 XFREE(MTYPE_RIP_INTERFACE, ifp->info);
1877 ifp->info = NULL;
1878 return 0;
1879 }
1880
1881 /* Allocate and initialize interface vector. */
1882 void rip_if_init(void)
1883 {
1884 /* Default initial size of interface vector. */
1885 hook_register_prio(if_add, 0, rip_interface_new_hook);
1886 hook_register_prio(if_del, 0, rip_interface_delete_hook);
1887
1888 /* RIP network init. */
1889 rip_enable_interface = vector_init(1);
1890 rip_enable_network = route_table_init();
1891
1892 /* RIP passive interface. */
1893 Vrip_passive_nondefault = vector_init(1);
1894
1895 /* Install interface node. */
1896 install_node(&interface_node, rip_interface_config_write);
1897 if_cmd_init();
1898
1899 /* Install commands. */
1900 install_element(RIP_NODE, &rip_network_cmd);
1901 install_element(RIP_NODE, &no_rip_network_cmd);
1902 install_element(RIP_NODE, &rip_neighbor_cmd);
1903 install_element(RIP_NODE, &no_rip_neighbor_cmd);
1904
1905 install_element(RIP_NODE, &rip_passive_interface_cmd);
1906 install_element(RIP_NODE, &no_rip_passive_interface_cmd);
1907
1908 install_element(INTERFACE_NODE, &ip_rip_send_version_cmd);
1909 install_element(INTERFACE_NODE, &ip_rip_send_version_1_cmd);
1910 install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd);
1911
1912 install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd);
1913 install_element(INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
1914 install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
1915
1916 install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
1917 install_element(INTERFACE_NODE, &no_ip_rip_v2_broadcast_cmd);
1918
1919 install_element(INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
1920 install_element(INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
1921
1922 install_element(INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
1923 install_element(INTERFACE_NODE,
1924 &no_ip_rip_authentication_key_chain_cmd);
1925
1926 install_element(INTERFACE_NODE, &ip_rip_authentication_string_cmd);
1927 install_element(INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
1928
1929 install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd);
1930 install_element(INTERFACE_NODE,
1931 &ip_rip_split_horizon_poisoned_reverse_cmd);
1932 install_element(INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
1933 install_element(INTERFACE_NODE,
1934 &no_ip_rip_split_horizon_poisoned_reverse_cmd);
1935 }