]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_interface.c
Merge branch 'master' into stylechecker
[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(ZEBRA_ROUTE_CONNECT,
911 RIP_ROUTE_INTERFACE,
912 &address, &nh, 0, 0, 0);
913 } else {
914 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT,
915 RIP_ROUTE_INTERFACE, &address,
916 connected->ifp->ifindex);
917 if (rip_redistribute_check(ZEBRA_ROUTE_CONNECT))
918 rip_redistribute_add(ZEBRA_ROUTE_CONNECT,
919 RIP_ROUTE_REDISTRIBUTE,
920 &address, &nh, 0, 0, 0);
921 }
922 }
923 }
924
925 /* Update interface status. */
926 void rip_enable_apply(struct interface *ifp)
927 {
928 int ret;
929 struct rip_interface *ri = NULL;
930
931 /* Check interface. */
932 if (!if_is_operative(ifp))
933 return;
934
935 ri = ifp->info;
936
937 /* Check network configuration. */
938 ret = rip_enable_network_lookup_if(ifp);
939
940 /* If the interface is matched. */
941 if (ret > 0)
942 ri->enable_network = 1;
943 else
944 ri->enable_network = 0;
945
946 /* Check interface name configuration. */
947 ret = rip_enable_if_lookup(ifp->name);
948 if (ret >= 0)
949 ri->enable_interface = 1;
950 else
951 ri->enable_interface = 0;
952
953 /* any interface MUST have an IPv4 address */
954 if (!rip_if_ipv4_address_check(ifp)) {
955 ri->enable_network = 0;
956 ri->enable_interface = 0;
957 }
958
959 /* Update running status of the interface. */
960 if (ri->enable_network || ri->enable_interface) {
961 {
962 if (IS_RIP_DEBUG_EVENT)
963 zlog_debug("turn on %s", ifp->name);
964
965 /* Add interface wake up thread. */
966 thread_add_timer(master, rip_interface_wakeup, ifp, 1,
967 &ri->t_wakeup);
968 rip_connect_set(ifp, 1);
969 }
970 } else {
971 if (ri->running) {
972 /* Might as well clean up the route table as well
973 * rip_if_down sets to 0 ri->running, and displays "turn
974 *off %s"
975 **/
976 rip_if_down(ifp);
977
978 rip_connect_set(ifp, 0);
979 }
980 }
981 }
982
983 /* Apply network configuration to all interface. */
984 void rip_enable_apply_all()
985 {
986 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
987 struct interface *ifp;
988
989 /* Check each interface. */
990 FOR_ALL_INTERFACES (vrf, ifp)
991 rip_enable_apply(ifp);
992 }
993
994 int rip_neighbor_lookup(struct sockaddr_in *from)
995 {
996 struct prefix_ipv4 p;
997 struct route_node *node;
998
999 memset(&p, 0, sizeof(struct prefix_ipv4));
1000 p.family = AF_INET;
1001 p.prefix = from->sin_addr;
1002 p.prefixlen = IPV4_MAX_BITLEN;
1003
1004 node = route_node_lookup(rip->neighbor, (struct prefix *)&p);
1005 if (node) {
1006 route_unlock_node(node);
1007 return 1;
1008 }
1009 return 0;
1010 }
1011
1012 /* Add new RIP neighbor to the neighbor tree. */
1013 static int rip_neighbor_add(struct prefix_ipv4 *p)
1014 {
1015 struct route_node *node;
1016
1017 node = route_node_get(rip->neighbor, (struct prefix *)p);
1018
1019 if (node->info)
1020 return -1;
1021
1022 node->info = rip->neighbor;
1023
1024 return 0;
1025 }
1026
1027 /* Delete RIP neighbor from the neighbor tree. */
1028 static int rip_neighbor_delete(struct prefix_ipv4 *p)
1029 {
1030 struct route_node *node;
1031
1032 /* Lock for look up. */
1033 node = route_node_lookup(rip->neighbor, (struct prefix *)p);
1034 if (!node)
1035 return -1;
1036
1037 node->info = NULL;
1038
1039 /* Unlock lookup lock. */
1040 route_unlock_node(node);
1041
1042 /* Unlock real neighbor information lock. */
1043 route_unlock_node(node);
1044
1045 return 0;
1046 }
1047
1048 /* Clear all network and neighbor configuration. */
1049 void rip_clean_network()
1050 {
1051 unsigned int i;
1052 char *str;
1053 struct route_node *rn;
1054
1055 /* rip_enable_network. */
1056 for (rn = route_top(rip_enable_network); rn; rn = route_next(rn))
1057 if (rn->info) {
1058 rn->info = NULL;
1059 route_unlock_node(rn);
1060 }
1061
1062 /* rip_enable_interface. */
1063 for (i = 0; i < vector_active(rip_enable_interface); i++)
1064 if ((str = vector_slot(rip_enable_interface, i)) != NULL) {
1065 free(str);
1066 vector_slot(rip_enable_interface, i) = NULL;
1067 }
1068 }
1069
1070 /* Utility function for looking up passive interface settings. */
1071 static int rip_passive_nondefault_lookup(const char *ifname)
1072 {
1073 unsigned int i;
1074 char *str;
1075
1076 for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
1077 if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL)
1078 if (strcmp(str, ifname) == 0)
1079 return i;
1080 return -1;
1081 }
1082
1083 void rip_passive_interface_apply(struct interface *ifp)
1084 {
1085 struct rip_interface *ri;
1086
1087 ri = ifp->info;
1088
1089 ri->passive = ((rip_passive_nondefault_lookup(ifp->name) < 0)
1090 ? passive_default
1091 : !passive_default);
1092
1093 if (IS_RIP_DEBUG_ZEBRA)
1094 zlog_debug("interface %s: passive = %d", ifp->name,
1095 ri->passive);
1096 }
1097
1098 static void rip_passive_interface_apply_all(void)
1099 {
1100 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1101 struct interface *ifp;
1102
1103 FOR_ALL_INTERFACES (vrf, ifp)
1104 rip_passive_interface_apply(ifp);
1105 }
1106
1107 /* Passive interface. */
1108 static int rip_passive_nondefault_set(struct vty *vty, const char *ifname)
1109 {
1110 if (rip_passive_nondefault_lookup(ifname) >= 0)
1111 return CMD_WARNING_CONFIG_FAILED;
1112
1113 vector_set(Vrip_passive_nondefault, strdup(ifname));
1114
1115 rip_passive_interface_apply_all();
1116
1117 return CMD_SUCCESS;
1118 }
1119
1120 static int rip_passive_nondefault_unset(struct vty *vty, const char *ifname)
1121 {
1122 int i;
1123 char *str;
1124
1125 i = rip_passive_nondefault_lookup(ifname);
1126 if (i < 0)
1127 return CMD_WARNING_CONFIG_FAILED;
1128
1129 str = vector_slot(Vrip_passive_nondefault, i);
1130 free(str);
1131 vector_unset(Vrip_passive_nondefault, i);
1132
1133 rip_passive_interface_apply_all();
1134
1135 return CMD_SUCCESS;
1136 }
1137
1138 /* Free all configured RIP passive-interface settings. */
1139 void rip_passive_nondefault_clean(void)
1140 {
1141 unsigned int i;
1142 char *str;
1143
1144 for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
1145 if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL) {
1146 free(str);
1147 vector_slot(Vrip_passive_nondefault, i) = NULL;
1148 }
1149 rip_passive_interface_apply_all();
1150 }
1151
1152 /* RIP enable network or interface configuration. */
1153 DEFUN (rip_network,
1154 rip_network_cmd,
1155 "network <A.B.C.D/M|WORD>",
1156 "Enable routing on an IP network\n"
1157 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1158 "Interface name\n")
1159 {
1160 int idx_ipv4_word = 1;
1161 int ret;
1162 struct prefix_ipv4 p;
1163
1164 ret = str2prefix_ipv4(argv[idx_ipv4_word]->arg, &p);
1165
1166 if (ret)
1167 ret = rip_enable_network_add((struct prefix *)&p);
1168 else
1169 ret = rip_enable_if_add(argv[idx_ipv4_word]->arg);
1170
1171 if (ret < 0) {
1172 vty_out(vty, "There is a same network configuration %s\n",
1173 argv[idx_ipv4_word]->arg);
1174 return CMD_WARNING_CONFIG_FAILED;
1175 }
1176
1177 return CMD_SUCCESS;
1178 }
1179
1180 /* RIP enable network or interface configuration. */
1181 DEFUN (no_rip_network,
1182 no_rip_network_cmd,
1183 "no network <A.B.C.D/M|WORD>",
1184 NO_STR
1185 "Enable routing on an IP network\n"
1186 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
1187 "Interface name\n")
1188 {
1189 int idx_ipv4_word = 2;
1190 int ret;
1191 struct prefix_ipv4 p;
1192
1193 ret = str2prefix_ipv4(argv[idx_ipv4_word]->arg, &p);
1194
1195 if (ret)
1196 ret = rip_enable_network_delete((struct prefix *)&p);
1197 else
1198 ret = rip_enable_if_delete(argv[idx_ipv4_word]->arg);
1199
1200 if (ret < 0) {
1201 vty_out(vty, "Can't find network configuration %s\n",
1202 argv[idx_ipv4_word]->arg);
1203 return CMD_WARNING_CONFIG_FAILED;
1204 }
1205
1206 return CMD_SUCCESS;
1207 }
1208
1209 /* RIP neighbor configuration set. */
1210 DEFUN (rip_neighbor,
1211 rip_neighbor_cmd,
1212 "neighbor A.B.C.D",
1213 "Specify a neighbor router\n"
1214 "Neighbor address\n")
1215 {
1216 int idx_ipv4 = 1;
1217 int ret;
1218 struct prefix_ipv4 p;
1219
1220 ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p);
1221
1222 if (ret <= 0) {
1223 vty_out(vty, "Please specify address by A.B.C.D\n");
1224 return CMD_WARNING_CONFIG_FAILED;
1225 }
1226
1227 rip_neighbor_add(&p);
1228
1229 return CMD_SUCCESS;
1230 }
1231
1232 /* RIP neighbor configuration unset. */
1233 DEFUN (no_rip_neighbor,
1234 no_rip_neighbor_cmd,
1235 "no neighbor A.B.C.D",
1236 NO_STR
1237 "Specify a neighbor router\n"
1238 "Neighbor address\n")
1239 {
1240 int idx_ipv4 = 2;
1241 int ret;
1242 struct prefix_ipv4 p;
1243
1244 ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p);
1245
1246 if (ret <= 0) {
1247 vty_out(vty, "Please specify address by A.B.C.D\n");
1248 return CMD_WARNING_CONFIG_FAILED;
1249 }
1250
1251 rip_neighbor_delete(&p);
1252
1253 return CMD_SUCCESS;
1254 }
1255
1256 DEFUN (ip_rip_receive_version,
1257 ip_rip_receive_version_cmd,
1258 "ip rip receive version <(1-2)|none>",
1259 IP_STR
1260 "Routing Information Protocol\n"
1261 "Advertisement reception\n"
1262 "Version control\n"
1263 "RIP version\n"
1264 "None\n")
1265 {
1266 VTY_DECLVAR_CONTEXT(interface, ifp);
1267 int idx_type = 4;
1268 struct rip_interface *ri;
1269
1270 ri = ifp->info;
1271
1272 switch (argv[idx_type]->arg[0]) {
1273 case '1':
1274 ri->ri_receive = RI_RIP_VERSION_1;
1275 return CMD_SUCCESS;
1276 case '2':
1277 ri->ri_receive = RI_RIP_VERSION_2;
1278 return CMD_SUCCESS;
1279 case 'n':
1280 ri->ri_receive = RI_RIP_VERSION_NONE;
1281 return CMD_SUCCESS;
1282 default:
1283 break;
1284 }
1285
1286 return CMD_WARNING_CONFIG_FAILED;
1287 }
1288
1289 DEFUN (ip_rip_receive_version_1,
1290 ip_rip_receive_version_1_cmd,
1291 "ip rip receive version <1 2|2 1>",
1292 IP_STR
1293 "Routing Information Protocol\n"
1294 "Advertisement reception\n"
1295 "Version control\n"
1296 "RIP version 1\n"
1297 "RIP version 2\n"
1298 "RIP version 2\n"
1299 "RIP version 1\n")
1300 {
1301 VTY_DECLVAR_CONTEXT(interface, ifp);
1302 struct rip_interface *ri;
1303
1304 ri = ifp->info;
1305
1306 /* Version 1 and 2. */
1307 ri->ri_receive = RI_RIP_VERSION_1_AND_2;
1308 return CMD_SUCCESS;
1309 }
1310
1311 DEFUN (no_ip_rip_receive_version,
1312 no_ip_rip_receive_version_cmd,
1313 "no ip rip receive version [(1-2)]",
1314 NO_STR
1315 IP_STR
1316 "Routing Information Protocol\n"
1317 "Advertisement reception\n"
1318 "Version control\n"
1319 "RIP version\n")
1320 {
1321 VTY_DECLVAR_CONTEXT(interface, ifp);
1322 struct rip_interface *ri;
1323
1324 ri = ifp->info;
1325
1326 ri->ri_receive = RI_RIP_UNSPEC;
1327 return CMD_SUCCESS;
1328 }
1329
1330
1331 DEFUN (ip_rip_send_version,
1332 ip_rip_send_version_cmd,
1333 "ip rip send version (1-2)",
1334 IP_STR
1335 "Routing Information Protocol\n"
1336 "Advertisement transmission\n"
1337 "Version control\n"
1338 "RIP version\n")
1339 {
1340 VTY_DECLVAR_CONTEXT(interface, ifp);
1341 int idx_type = 4;
1342 struct rip_interface *ri;
1343
1344 ri = ifp->info;
1345
1346 /* Version 1. */
1347 if (atoi(argv[idx_type]->arg) == 1) {
1348 ri->ri_send = RI_RIP_VERSION_1;
1349 return CMD_SUCCESS;
1350 }
1351 if (atoi(argv[idx_type]->arg) == 2) {
1352 ri->ri_send = RI_RIP_VERSION_2;
1353 return CMD_SUCCESS;
1354 }
1355 return CMD_WARNING_CONFIG_FAILED;
1356 }
1357
1358 DEFUN (ip_rip_send_version_1,
1359 ip_rip_send_version_1_cmd,
1360 "ip rip send version <1 2|2 1>",
1361 IP_STR
1362 "Routing Information Protocol\n"
1363 "Advertisement transmission\n"
1364 "Version control\n"
1365 "RIP version 1\n"
1366 "RIP version 2\n"
1367 "RIP version 2\n"
1368 "RIP version 1\n")
1369 {
1370 VTY_DECLVAR_CONTEXT(interface, ifp);
1371 struct rip_interface *ri;
1372
1373 ri = ifp->info;
1374
1375 /* Version 1 and 2. */
1376 ri->ri_send = RI_RIP_VERSION_1_AND_2;
1377 return CMD_SUCCESS;
1378 }
1379
1380 DEFUN (no_ip_rip_send_version,
1381 no_ip_rip_send_version_cmd,
1382 "no ip rip send version [(1-2)]",
1383 NO_STR
1384 IP_STR
1385 "Routing Information Protocol\n"
1386 "Advertisement transmission\n"
1387 "Version control\n"
1388 "RIP version\n")
1389 {
1390 VTY_DECLVAR_CONTEXT(interface, ifp);
1391 struct rip_interface *ri;
1392
1393 ri = ifp->info;
1394
1395 ri->ri_send = RI_RIP_UNSPEC;
1396 return CMD_SUCCESS;
1397 }
1398
1399
1400 DEFUN (ip_rip_v2_broadcast,
1401 ip_rip_v2_broadcast_cmd,
1402 "ip rip v2-broadcast",
1403 IP_STR
1404 "Routing Information Protocol\n"
1405 "Send ip broadcast v2 update\n")
1406 {
1407 VTY_DECLVAR_CONTEXT(interface, ifp);
1408 struct rip_interface *ri;
1409
1410 ri = ifp->info;
1411
1412 ri->v2_broadcast = 1;
1413 return CMD_SUCCESS;
1414 }
1415
1416 DEFUN (no_ip_rip_v2_broadcast,
1417 no_ip_rip_v2_broadcast_cmd,
1418 "no ip rip v2-broadcast",
1419 NO_STR
1420 IP_STR
1421 "Routing Information Protocol\n"
1422 "Send ip broadcast v2 update\n")
1423 {
1424 VTY_DECLVAR_CONTEXT(interface, ifp);
1425 struct rip_interface *ri;
1426
1427 ri = ifp->info;
1428
1429 ri->v2_broadcast = 0;
1430 return CMD_SUCCESS;
1431 }
1432
1433 DEFUN (ip_rip_authentication_mode,
1434 ip_rip_authentication_mode_cmd,
1435 "ip rip authentication mode <md5|text> [auth-length <rfc|old-ripd>]",
1436 IP_STR
1437 "Routing Information Protocol\n"
1438 "Authentication control\n"
1439 "Authentication mode\n"
1440 "Keyed message digest\n"
1441 "Clear text authentication\n"
1442 "MD5 authentication data length\n"
1443 "RFC compatible\n"
1444 "Old ripd compatible\n")
1445 {
1446 VTY_DECLVAR_CONTEXT(interface, ifp);
1447 char *cryptmode = argv[4]->text;
1448 char *authlen = (argc > 5) ? argv[6]->text : NULL;
1449 struct rip_interface *ri;
1450 int auth_type;
1451
1452 ri = ifp->info;
1453
1454 if (strmatch("md5", cryptmode))
1455 auth_type = RIP_AUTH_MD5;
1456 else {
1457 assert(strmatch("text", cryptmode));
1458 auth_type = RIP_AUTH_SIMPLE_PASSWORD;
1459 }
1460
1461 ri->auth_type = auth_type;
1462
1463 if (argc > 5) {
1464 if (auth_type != RIP_AUTH_MD5) {
1465 vty_out(vty,
1466 "auth length argument only valid for md5\n");
1467 return CMD_WARNING_CONFIG_FAILED;
1468 }
1469 if (strmatch("rfc", authlen))
1470 ri->md5_auth_len = RIP_AUTH_MD5_SIZE;
1471 else {
1472 assert(strmatch("old-ripd", authlen));
1473 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1474 }
1475 }
1476
1477 return CMD_SUCCESS;
1478 }
1479
1480 DEFUN (no_ip_rip_authentication_mode,
1481 no_ip_rip_authentication_mode_cmd,
1482 "no ip rip authentication mode [<md5|text> [auth-length <rfc|old-ripd>]]",
1483 NO_STR
1484 IP_STR
1485 "Routing Information Protocol\n"
1486 "Authentication control\n"
1487 "Authentication mode\n"
1488 "Keyed message digest\n"
1489 "Clear text authentication\n"
1490 "MD5 authentication data length\n"
1491 "RFC compatible\n"
1492 "Old ripd compatible\n")
1493 {
1494 VTY_DECLVAR_CONTEXT(interface, ifp);
1495 struct rip_interface *ri;
1496
1497 ri = ifp->info;
1498
1499 ri->auth_type = RIP_NO_AUTH;
1500 ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE;
1501
1502 return CMD_SUCCESS;
1503 }
1504
1505 DEFUN (ip_rip_authentication_string,
1506 ip_rip_authentication_string_cmd,
1507 "ip rip authentication string LINE",
1508 IP_STR
1509 "Routing Information Protocol\n"
1510 "Authentication control\n"
1511 "Authentication string\n"
1512 "Authentication string\n")
1513 {
1514 VTY_DECLVAR_CONTEXT(interface, ifp);
1515 int idx_line = 4;
1516 struct rip_interface *ri;
1517
1518 ri = ifp->info;
1519
1520 if (strlen(argv[idx_line]->arg) > 16) {
1521 vty_out(vty,
1522 "%% RIPv2 authentication string must be shorter than 16\n");
1523 return CMD_WARNING_CONFIG_FAILED;
1524 }
1525
1526 if (ri->key_chain) {
1527 vty_out(vty, "%% key-chain configuration exists\n");
1528 return CMD_WARNING_CONFIG_FAILED;
1529 }
1530
1531 if (ri->auth_str)
1532 free(ri->auth_str);
1533
1534 ri->auth_str = strdup(argv[idx_line]->arg);
1535
1536 return CMD_SUCCESS;
1537 }
1538
1539 DEFUN (no_ip_rip_authentication_string,
1540 no_ip_rip_authentication_string_cmd,
1541 "no ip rip authentication string [LINE]",
1542 NO_STR
1543 IP_STR
1544 "Routing Information Protocol\n"
1545 "Authentication control\n"
1546 "Authentication string\n"
1547 "Authentication string\n")
1548 {
1549 VTY_DECLVAR_CONTEXT(interface, ifp);
1550 struct rip_interface *ri;
1551
1552 ri = ifp->info;
1553
1554 if (ri->auth_str)
1555 free(ri->auth_str);
1556
1557 ri->auth_str = NULL;
1558
1559 return CMD_SUCCESS;
1560 }
1561
1562
1563 DEFUN (ip_rip_authentication_key_chain,
1564 ip_rip_authentication_key_chain_cmd,
1565 "ip rip authentication key-chain LINE",
1566 IP_STR
1567 "Routing Information Protocol\n"
1568 "Authentication control\n"
1569 "Authentication key-chain\n"
1570 "name of key-chain\n")
1571 {
1572 VTY_DECLVAR_CONTEXT(interface, ifp);
1573 int idx_line = 4;
1574 struct rip_interface *ri;
1575
1576 ri = ifp->info;
1577
1578 if (ri->auth_str) {
1579 vty_out(vty, "%% authentication string configuration exists\n");
1580 return CMD_WARNING_CONFIG_FAILED;
1581 }
1582
1583 if (ri->key_chain)
1584 free(ri->key_chain);
1585
1586 ri->key_chain = strdup(argv[idx_line]->arg);
1587
1588 return CMD_SUCCESS;
1589 }
1590
1591 DEFUN (no_ip_rip_authentication_key_chain,
1592 no_ip_rip_authentication_key_chain_cmd,
1593 "no ip rip authentication key-chain [LINE]",
1594 NO_STR
1595 IP_STR
1596 "Routing Information Protocol\n"
1597 "Authentication control\n"
1598 "Authentication key-chain\n"
1599 "name of key-chain\n")
1600 {
1601 VTY_DECLVAR_CONTEXT(interface, ifp);
1602 struct rip_interface *ri;
1603
1604 ri = ifp->info;
1605
1606 if (ri->key_chain)
1607 free(ri->key_chain);
1608
1609 ri->key_chain = NULL;
1610
1611 return CMD_SUCCESS;
1612 }
1613
1614
1615 /* CHANGED: ip rip split-horizon
1616 Cisco and Zebra's command is
1617 ip split-horizon
1618 */
1619 DEFUN (ip_rip_split_horizon,
1620 ip_rip_split_horizon_cmd,
1621 "ip rip split-horizon",
1622 IP_STR
1623 "Routing Information Protocol\n"
1624 "Perform split horizon\n")
1625 {
1626 VTY_DECLVAR_CONTEXT(interface, ifp);
1627 struct rip_interface *ri;
1628
1629 ri = ifp->info;
1630
1631 ri->split_horizon = RIP_SPLIT_HORIZON;
1632 return CMD_SUCCESS;
1633 }
1634
1635 DEFUN (ip_rip_split_horizon_poisoned_reverse,
1636 ip_rip_split_horizon_poisoned_reverse_cmd,
1637 "ip rip split-horizon poisoned-reverse",
1638 IP_STR
1639 "Routing Information Protocol\n"
1640 "Perform split horizon\n"
1641 "With poisoned-reverse\n")
1642 {
1643 VTY_DECLVAR_CONTEXT(interface, ifp);
1644 struct rip_interface *ri;
1645
1646 ri = ifp->info;
1647
1648 ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE;
1649 return CMD_SUCCESS;
1650 }
1651
1652 /* CHANGED: no ip rip split-horizon
1653 Cisco and Zebra's command is
1654 no ip split-horizon
1655 */
1656 DEFUN (no_ip_rip_split_horizon,
1657 no_ip_rip_split_horizon_cmd,
1658 "no ip rip split-horizon",
1659 NO_STR
1660 IP_STR
1661 "Routing Information Protocol\n"
1662 "Perform split horizon\n")
1663 {
1664 VTY_DECLVAR_CONTEXT(interface, ifp);
1665 struct rip_interface *ri;
1666
1667 ri = ifp->info;
1668
1669 ri->split_horizon = RIP_NO_SPLIT_HORIZON;
1670 return CMD_SUCCESS;
1671 }
1672
1673 DEFUN (no_ip_rip_split_horizon_poisoned_reverse,
1674 no_ip_rip_split_horizon_poisoned_reverse_cmd,
1675 "no ip rip split-horizon poisoned-reverse",
1676 NO_STR
1677 IP_STR
1678 "Routing Information Protocol\n"
1679 "Perform split horizon\n"
1680 "With poisoned-reverse\n")
1681 {
1682 VTY_DECLVAR_CONTEXT(interface, ifp);
1683 struct rip_interface *ri;
1684
1685 ri = ifp->info;
1686
1687 switch (ri->split_horizon) {
1688 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1689 ri->split_horizon = RIP_SPLIT_HORIZON;
1690 default:
1691 break;
1692 }
1693
1694 return CMD_SUCCESS;
1695 }
1696
1697 DEFUN (rip_passive_interface,
1698 rip_passive_interface_cmd,
1699 "passive-interface <IFNAME|default>",
1700 "Suppress routing updates on an interface\n"
1701 "Interface name\n"
1702 "default for all interfaces\n")
1703 {
1704 if (argv[1]->type == WORD_TKN) { // user passed 'default'
1705 passive_default = 1;
1706 rip_passive_nondefault_clean();
1707 return CMD_SUCCESS;
1708 }
1709 if (passive_default)
1710 return rip_passive_nondefault_unset(vty, argv[1]->arg);
1711 else
1712 return rip_passive_nondefault_set(vty, argv[1]->arg);
1713 }
1714
1715 DEFUN (no_rip_passive_interface,
1716 no_rip_passive_interface_cmd,
1717 "no passive-interface <IFNAME|default>",
1718 NO_STR
1719 "Suppress routing updates on an interface\n"
1720 "Interface name\n"
1721 "default for all interfaces\n")
1722 {
1723 if (argv[2]->type == WORD_TKN) {
1724 passive_default = 0;
1725 rip_passive_nondefault_clean();
1726 return CMD_SUCCESS;
1727 }
1728 if (passive_default)
1729 return rip_passive_nondefault_set(vty, argv[2]->arg);
1730 else
1731 return rip_passive_nondefault_unset(vty, argv[2]->arg);
1732 }
1733
1734 /* Write rip configuration of each interface. */
1735 static int rip_interface_config_write(struct vty *vty)
1736 {
1737 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1738 struct interface *ifp;
1739
1740 FOR_ALL_INTERFACES (vrf, ifp) {
1741 struct rip_interface *ri;
1742
1743 ri = ifp->info;
1744
1745 /* Do not display the interface if there is no
1746 * configuration about it.
1747 **/
1748 if ((!ifp->desc)
1749 && (ri->split_horizon == ri->split_horizon_default)
1750 && (ri->ri_send == RI_RIP_UNSPEC)
1751 && (ri->ri_receive == RI_RIP_UNSPEC)
1752 && (ri->auth_type != RIP_AUTH_MD5) && (!ri->v2_broadcast)
1753 && (ri->md5_auth_len != RIP_AUTH_MD5_SIZE)
1754 && (!ri->auth_str) && (!ri->key_chain))
1755 continue;
1756
1757 vty_frame(vty, "interface %s\n", ifp->name);
1758
1759 if (ifp->desc)
1760 vty_out(vty, " description %s\n", ifp->desc);
1761
1762 /* Split horizon. */
1763 if (ri->split_horizon != ri->split_horizon_default) {
1764 switch (ri->split_horizon) {
1765 case RIP_SPLIT_HORIZON:
1766 vty_out(vty, " ip rip split-horizon\n");
1767 break;
1768 case RIP_SPLIT_HORIZON_POISONED_REVERSE:
1769 vty_out(vty,
1770 " ip rip split-horizon poisoned-reverse\n");
1771 break;
1772 case RIP_NO_SPLIT_HORIZON:
1773 default:
1774 vty_out(vty, " no ip rip split-horizon\n");
1775 break;
1776 }
1777 }
1778
1779 /* RIP version setting. */
1780 if (ri->ri_send != RI_RIP_UNSPEC)
1781 vty_out(vty, " ip rip send version %s\n",
1782 lookup_msg(ri_version_msg, ri->ri_send, NULL));
1783
1784 if (ri->ri_receive != RI_RIP_UNSPEC)
1785 vty_out(vty, " ip rip receive version %s \n",
1786 lookup_msg(ri_version_msg, ri->ri_receive,
1787 NULL));
1788
1789 if (ri->v2_broadcast)
1790 vty_out(vty, " ip rip v2-broadcast\n");
1791
1792 /* RIP authentication. */
1793 if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
1794 vty_out(vty, " ip rip authentication mode text\n");
1795
1796 if (ri->auth_type == RIP_AUTH_MD5) {
1797 vty_out(vty, " ip rip authentication mode md5");
1798 if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE)
1799 vty_out(vty, " auth-length old-ripd");
1800 else
1801 vty_out(vty, " auth-length rfc");
1802 vty_out(vty, "\n");
1803 }
1804
1805 if (ri->auth_str)
1806 vty_out(vty, " ip rip authentication string %s\n",
1807 ri->auth_str);
1808
1809 if (ri->key_chain)
1810 vty_out(vty, " ip rip authentication key-chain %s\n",
1811 ri->key_chain);
1812
1813 vty_endframe(vty, "!\n");
1814 }
1815 return 0;
1816 }
1817
1818 int config_write_rip_network(struct vty *vty, int config_mode)
1819 {
1820 unsigned int i;
1821 char *ifname;
1822 struct route_node *node;
1823
1824 /* Network type RIP enable interface statement. */
1825 for (node = route_top(rip_enable_network); node;
1826 node = route_next(node))
1827 if (node->info)
1828 vty_out(vty, "%s%s/%d\n",
1829 config_mode ? " network " : " ",
1830 inet_ntoa(node->p.u.prefix4),
1831 node->p.prefixlen);
1832
1833 /* Interface name RIP enable statement. */
1834 for (i = 0; i < vector_active(rip_enable_interface); i++)
1835 if ((ifname = vector_slot(rip_enable_interface, i)) != NULL)
1836 vty_out(vty, "%s%s\n",
1837 config_mode ? " network " : " ", ifname);
1838
1839 /* RIP neighbors listing. */
1840 for (node = route_top(rip->neighbor); node; node = route_next(node))
1841 if (node->info)
1842 vty_out(vty, "%s%s\n",
1843 config_mode ? " neighbor " : " ",
1844 inet_ntoa(node->p.u.prefix4));
1845
1846 /* RIP passive interface listing. */
1847 if (config_mode) {
1848 if (passive_default)
1849 vty_out(vty, " passive-interface default\n");
1850 for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
1851 if ((ifname = vector_slot(Vrip_passive_nondefault, i))
1852 != NULL)
1853 vty_out(vty, " %spassive-interface %s\n",
1854 (passive_default ? "no " : ""), ifname);
1855 }
1856
1857 return 0;
1858 }
1859
1860 static struct cmd_node interface_node = {
1861 INTERFACE_NODE, "%s(config-if)# ", 1,
1862 };
1863
1864 /* Called when interface structure allocated. */
1865 static int rip_interface_new_hook(struct interface *ifp)
1866 {
1867 ifp->info = rip_interface_new();
1868 return 0;
1869 }
1870
1871 /* Called when interface structure deleted. */
1872 static int rip_interface_delete_hook(struct interface *ifp)
1873 {
1874 XFREE(MTYPE_RIP_INTERFACE, ifp->info);
1875 ifp->info = NULL;
1876 return 0;
1877 }
1878
1879 /* Allocate and initialize interface vector. */
1880 void rip_if_init(void)
1881 {
1882 /* Default initial size of interface vector. */
1883 hook_register_prio(if_add, 0, rip_interface_new_hook);
1884 hook_register_prio(if_del, 0, rip_interface_delete_hook);
1885
1886 /* RIP network init. */
1887 rip_enable_interface = vector_init(1);
1888 rip_enable_network = route_table_init();
1889
1890 /* RIP passive interface. */
1891 Vrip_passive_nondefault = vector_init(1);
1892
1893 /* Install interface node. */
1894 install_node(&interface_node, rip_interface_config_write);
1895 if_cmd_init();
1896
1897 /* Install commands. */
1898 install_element(RIP_NODE, &rip_network_cmd);
1899 install_element(RIP_NODE, &no_rip_network_cmd);
1900 install_element(RIP_NODE, &rip_neighbor_cmd);
1901 install_element(RIP_NODE, &no_rip_neighbor_cmd);
1902
1903 install_element(RIP_NODE, &rip_passive_interface_cmd);
1904 install_element(RIP_NODE, &no_rip_passive_interface_cmd);
1905
1906 install_element(INTERFACE_NODE, &ip_rip_send_version_cmd);
1907 install_element(INTERFACE_NODE, &ip_rip_send_version_1_cmd);
1908 install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd);
1909
1910 install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd);
1911 install_element(INTERFACE_NODE, &ip_rip_receive_version_1_cmd);
1912 install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd);
1913
1914 install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd);
1915 install_element(INTERFACE_NODE, &no_ip_rip_v2_broadcast_cmd);
1916
1917 install_element(INTERFACE_NODE, &ip_rip_authentication_mode_cmd);
1918 install_element(INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd);
1919
1920 install_element(INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd);
1921 install_element(INTERFACE_NODE,
1922 &no_ip_rip_authentication_key_chain_cmd);
1923
1924 install_element(INTERFACE_NODE, &ip_rip_authentication_string_cmd);
1925 install_element(INTERFACE_NODE, &no_ip_rip_authentication_string_cmd);
1926
1927 install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd);
1928 install_element(INTERFACE_NODE,
1929 &ip_rip_split_horizon_poisoned_reverse_cmd);
1930 install_element(INTERFACE_NODE, &no_ip_rip_split_horizon_cmd);
1931 install_element(INTERFACE_NODE,
1932 &no_ip_rip_split_horizon_poisoned_reverse_cmd);
1933 }