]> git.proxmox.com Git - mirror_frr.git/blob - ripd/rip_interface.c
Merge pull request #3839 from srimohans/support_bundle
[mirror_frr.git] / ripd / rip_interface.c
1 /* Interface related function for RIP.
2 * Copyright (C) 1997, 98 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "command.h"
24 #include "if.h"
25 #include "sockunion.h"
26 #include "prefix.h"
27 #include "memory.h"
28 #include "network.h"
29 #include "table.h"
30 #include "log.h"
31 #include "stream.h"
32 #include "thread.h"
33 #include "zclient.h"
34 #include "filter.h"
35 #include "sockopt.h"
36 #include "privs.h"
37 #include "lib_errors.h"
38 #include "northbound_cli.h"
39
40 #include "zebra/connected.h"
41
42 #include "ripd/ripd.h"
43 #include "ripd/rip_debug.h"
44 #include "ripd/rip_interface.h"
45
46 DEFINE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc))
47 DEFINE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))
48
49 /* static prototypes */
50 static void rip_enable_apply(struct interface *);
51 static void rip_passive_interface_apply(struct interface *);
52 static int rip_if_down(struct interface *ifp);
53 static int rip_enable_if_lookup(const char *ifname);
54 static int rip_enable_network_lookup2(struct connected *connected);
55 static void rip_enable_apply_all(void);
56
57 const struct message ri_version_msg[] = {{RI_RIP_VERSION_1, "1"},
58 {RI_RIP_VERSION_2, "2"},
59 {RI_RIP_VERSION_1_AND_2, "1 2"},
60 {RI_RIP_VERSION_NONE, "none"},
61 {0}};
62
63 /* RIP enabled network vector. */
64 vector rip_enable_interface;
65
66 /* RIP enabled interface table. */
67 struct route_table *rip_enable_network;
68
69 /* Vector to store passive-interface name. */
70 vector Vrip_passive_nondefault;
71
72 /* Join to the RIP version 2 multicast group. */
73 static int ipv4_multicast_join(int sock, struct in_addr group,
74 struct in_addr ifa, ifindex_t ifindex)
75 {
76 int ret;
77
78 ret = setsockopt_ipv4_multicast(sock, IP_ADD_MEMBERSHIP, ifa,
79 group.s_addr, ifindex);
80
81 if (ret < 0)
82 zlog_info("can't setsockopt IP_ADD_MEMBERSHIP %s",
83 safe_strerror(errno));
84
85 return ret;
86 }
87
88 /* Leave from the RIP version 2 multicast group. */
89 static int ipv4_multicast_leave(int sock, struct in_addr group,
90 struct in_addr ifa, ifindex_t ifindex)
91 {
92 int ret;
93
94 ret = setsockopt_ipv4_multicast(sock, IP_DROP_MEMBERSHIP, ifa,
95 group.s_addr, ifindex);
96
97 if (ret < 0)
98 zlog_info("can't setsockopt IP_DROP_MEMBERSHIP");
99
100 return ret;
101 }
102
103 static void rip_interface_reset(struct rip_interface *);
104
105 /* Allocate new RIP's interface configuration. */
106 static struct rip_interface *rip_interface_new(void)
107 {
108 struct rip_interface *ri;
109
110 ri = XCALLOC(MTYPE_RIP_INTERFACE, sizeof(struct rip_interface));
111
112 rip_interface_reset(ri);
113
114 return ri;
115 }
116
117 void rip_interface_multicast_set(int sock, struct connected *connected)
118 {
119 struct in_addr addr;
120
121 assert(connected != NULL);
122
123 addr = CONNECTED_ID(connected)->u.prefix4;
124
125 if (setsockopt_ipv4_multicast_if(sock, addr, connected->ifp->ifindex)
126 < 0) {
127 zlog_warn(
128 "Can't setsockopt IP_MULTICAST_IF on fd %d to "
129 "ifindex %d for interface %s",
130 sock, connected->ifp->ifindex, connected->ifp->name);
131 }
132
133 return;
134 }
135
136 /* Send RIP request packet to specified interface. */
137 static void rip_request_interface_send(struct interface *ifp, uint8_t version)
138 {
139 struct sockaddr_in to;
140
141 /* RIPv2 support multicast. */
142 if (version == RIPv2 && if_is_multicast(ifp)) {
143
144 if (IS_RIP_DEBUG_EVENT)
145 zlog_debug("multicast request on %s", ifp->name);
146
147 rip_request_send(NULL, ifp, version, NULL);
148 return;
149 }
150
151 /* RIPv1 and non multicast interface. */
152 if (if_is_pointopoint(ifp) || if_is_broadcast(ifp)) {
153 struct listnode *cnode, *cnnode;
154 struct connected *connected;
155
156 if (IS_RIP_DEBUG_EVENT)
157 zlog_debug("broadcast request to %s", ifp->name);
158
159 for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode,
160 connected)) {
161 if (connected->address->family != AF_INET)
162 continue;
163
164 memset(&to, 0, sizeof(struct sockaddr_in));
165 to.sin_port = htons(RIP_PORT_DEFAULT);
166 if (connected->destination)
167 /* use specified broadcast or peer
168 * destination addr */
169 to.sin_addr = connected->destination->u.prefix4;
170 else if (connected->address->prefixlen
171 < IPV4_MAX_PREFIXLEN)
172 /* calculate the appropriate broadcast
173 * address */
174 to.sin_addr.s_addr = ipv4_broadcast_addr(
175 connected->address->u.prefix4.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 /* This will be executed when interface goes up. */
192 static void rip_request_interface(struct interface *ifp)
193 {
194 struct rip_interface *ri;
195 int vsend;
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 /* If there is no version configuration in the interface,
210 use rip's version setting. */
211 vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? rip->version_send
212 : ri->ri_send);
213 if (vsend & RIPv1)
214 rip_request_interface_send(ifp, RIPv1);
215 if (vsend & RIPv2)
216 rip_request_interface_send(ifp, RIPv2);
217 }
218
219 #if 0
220 /* Send RIP request to the neighbor. */
221 static void
222 rip_request_neighbor (struct in_addr addr)
223 {
224 struct sockaddr_in to;
225
226 memset (&to, 0, sizeof (struct sockaddr_in));
227 to.sin_port = htons (RIP_PORT_DEFAULT);
228 to.sin_addr = addr;
229
230 rip_request_send (&to, NULL, rip->version_send, NULL);
231 }
232
233 /* Request routes at all interfaces. */
234 static void
235 rip_request_neighbor_all (void)
236 {
237 struct route_node *rp;
238
239 if (! rip)
240 return;
241
242 if (IS_RIP_DEBUG_EVENT)
243 zlog_debug ("request to the all neighbor");
244
245 /* Send request to all neighbor. */
246 for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
247 if (rp->info)
248 rip_request_neighbor (rp->p.u.prefix4);
249 }
250 #endif
251
252 /* Multicast packet receive socket. */
253 static int rip_multicast_join(struct interface *ifp, int sock)
254 {
255 struct listnode *cnode;
256 struct connected *ifc;
257
258 if (if_is_operative(ifp) && if_is_multicast(ifp)) {
259 if (IS_RIP_DEBUG_EVENT)
260 zlog_debug("multicast join at %s", ifp->name);
261
262 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
263 struct prefix_ipv4 *p;
264 struct in_addr group;
265
266 p = (struct prefix_ipv4 *)ifc->address;
267
268 if (p->family != AF_INET)
269 continue;
270
271 group.s_addr = htonl(INADDR_RIP_GROUP);
272 if (ipv4_multicast_join(sock, group, p->prefix,
273 ifp->ifindex)
274 < 0)
275 return -1;
276 else
277 return 0;
278 }
279 }
280 return 0;
281 }
282
283 /* Leave from multicast group. */
284 static void rip_multicast_leave(struct interface *ifp, int sock)
285 {
286 struct listnode *cnode;
287 struct connected *connected;
288
289 if (if_is_up(ifp) && if_is_multicast(ifp)) {
290 if (IS_RIP_DEBUG_EVENT)
291 zlog_debug("multicast leave from %s", ifp->name);
292
293 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
294 struct prefix_ipv4 *p;
295 struct in_addr group;
296
297 p = (struct prefix_ipv4 *)connected->address;
298
299 if (p->family != AF_INET)
300 continue;
301
302 group.s_addr = htonl(INADDR_RIP_GROUP);
303 if (ipv4_multicast_leave(sock, group, p->prefix,
304 ifp->ifindex)
305 == 0)
306 return;
307 }
308 }
309 }
310
311 /* Is there and address on interface that I could use ? */
312 static int rip_if_ipv4_address_check(struct interface *ifp)
313 {
314 struct listnode *nn;
315 struct connected *connected;
316 int count = 0;
317
318 for (ALL_LIST_ELEMENTS_RO(ifp->connected, nn, connected)) {
319 struct prefix *p;
320
321 p = connected->address;
322
323 if (p->family == AF_INET)
324 count++;
325 }
326
327 return count;
328 }
329
330
331 /* Does this address belongs to me ? */
332 int if_check_address(struct in_addr addr)
333 {
334 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
335 struct interface *ifp;
336
337 FOR_ALL_INTERFACES (vrf, ifp) {
338 struct listnode *cnode;
339 struct connected *connected;
340
341 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) {
342 struct prefix_ipv4 *p;
343
344 p = (struct prefix_ipv4 *)connected->address;
345
346 if (p->family != AF_INET)
347 continue;
348
349 if (IPV4_ADDR_CMP(&p->prefix, &addr) == 0)
350 return 1;
351 }
352 }
353 return 0;
354 }
355
356 /* Inteface link down message processing. */
357 int rip_interface_down(int command, struct zclient *zclient,
358 zebra_size_t length, vrf_id_t vrf_id)
359 {
360 struct interface *ifp;
361 struct stream *s;
362
363 s = zclient->ibuf;
364
365 /* zebra_interface_state_read() updates interface structure in
366 iflist. */
367 ifp = zebra_interface_state_read(s, vrf_id);
368
369 if (ifp == NULL)
370 return 0;
371
372 rip_if_down(ifp);
373
374 if (IS_RIP_DEBUG_ZEBRA)
375 zlog_debug(
376 "interface %s index %d flags %llx metric %d mtu %d is down",
377 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
378 ifp->metric, ifp->mtu);
379
380 return 0;
381 }
382
383 /* Inteface link up message processing */
384 int rip_interface_up(int command, struct zclient *zclient, zebra_size_t length,
385 vrf_id_t vrf_id)
386 {
387 struct interface *ifp;
388
389 /* zebra_interface_state_read () updates interface structure in
390 iflist. */
391 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
392
393 if (ifp == NULL)
394 return 0;
395
396 if (IS_RIP_DEBUG_ZEBRA)
397 zlog_debug(
398 "interface %s index %d flags %#llx metric %d mtu %d is up",
399 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
400 ifp->metric, ifp->mtu);
401
402 /* Check if this interface is RIP enabled or not.*/
403 rip_enable_apply(ifp);
404
405 /* Check for a passive interface */
406 rip_passive_interface_apply(ifp);
407
408 /* Apply distribute list to the all interface. */
409 rip_distribute_update_interface(ifp);
410
411 return 0;
412 }
413
414 /* Inteface addition message from zebra. */
415 int rip_interface_add(int command, struct zclient *zclient, zebra_size_t length,
416 vrf_id_t vrf_id)
417 {
418 struct interface *ifp;
419
420 ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
421
422 if (IS_RIP_DEBUG_ZEBRA)
423 zlog_debug(
424 "interface add %s index %d flags %#llx metric %d mtu %d",
425 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
426 ifp->metric, ifp->mtu);
427
428 /* Check if this interface is RIP enabled or not.*/
429 rip_enable_apply(ifp);
430
431 /* Check for a passive interface */
432 rip_passive_interface_apply(ifp);
433
434 /* Apply distribute list to the all interface. */
435 rip_distribute_update_interface(ifp);
436
437 /* rip_request_neighbor_all (); */
438
439 /* Check interface routemap. */
440 rip_if_rmap_update_interface(ifp);
441
442 return 0;
443 }
444
445 int rip_interface_delete(int command, struct zclient *zclient,
446 zebra_size_t length, vrf_id_t vrf_id)
447 {
448 struct interface *ifp;
449 struct stream *s;
450
451
452 s = zclient->ibuf;
453 /* zebra_interface_state_read() updates interface structure in iflist */
454 ifp = zebra_interface_state_read(s, vrf_id);
455
456 if (ifp == NULL)
457 return 0;
458
459 if (if_is_up(ifp)) {
460 rip_if_down(ifp);
461 }
462
463 zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d",
464 ifp->name, ifp->ifindex, (unsigned long long)ifp->flags,
465 ifp->metric, ifp->mtu);
466
467 /* To support pseudo interface do not free interface structure. */
468 /* if_delete(ifp); */
469 if_set_index(ifp, IFINDEX_INTERNAL);
470
471 return 0;
472 }
473
474 static void rip_interface_clean(struct rip_interface *ri)
475 {
476 ri->enable_network = 0;
477 ri->enable_interface = 0;
478 ri->running = 0;
479
480 if (ri->t_wakeup) {
481 thread_cancel(ri->t_wakeup);
482 ri->t_wakeup = NULL;
483 }
484 }
485
486 void rip_interfaces_clean(void)
487 {
488 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
489 struct interface *ifp;
490
491 FOR_ALL_INTERFACES (vrf, ifp)
492 rip_interface_clean(ifp->info);
493 }
494
495 static void rip_interface_reset(struct rip_interface *ri)
496 {
497 ri->auth_type = yang_get_default_enum("%s/authentication-scheme/mode",
498 RIP_IFACE);
499 ri->md5_auth_len = yang_get_default_enum(
500 "%s/authentication-scheme/md5-auth-length", RIP_IFACE);
501
502 /* Set default split-horizon behavior. If the interface is Frame
503 Relay or SMDS is enabled, the default value for split-horizon is
504 off. But currently Zebra does detect Frame Relay or SMDS
505 interface. So all interface is set to split horizon. */
506 ri->split_horizon =
507 yang_get_default_enum("%s/split-horizon", RIP_IFACE);
508
509 ri->ri_send = yang_get_default_enum("%s/version-send", RIP_IFACE);
510 ri->ri_receive = yang_get_default_enum("%s/version-receive", RIP_IFACE);
511 ri->v2_broadcast = yang_get_default_bool("%s/v2-broadcast", RIP_IFACE);
512
513 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str);
514
515 XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain);
516
517 ri->list[RIP_FILTER_IN] = NULL;
518 ri->list[RIP_FILTER_OUT] = NULL;
519
520 ri->prefix[RIP_FILTER_IN] = NULL;
521 ri->prefix[RIP_FILTER_OUT] = NULL;
522
523 ri->recv_badpackets = 0;
524 ri->recv_badroutes = 0;
525 ri->sent_updates = 0;
526
527 ri->passive = 0;
528
529 rip_interface_clean(ri);
530 }
531
532 int rip_if_down(struct interface *ifp)
533 {
534 struct route_node *rp;
535 struct rip_info *rinfo;
536 struct rip_interface *ri = NULL;
537 struct list *list = NULL;
538 struct listnode *listnode = NULL, *nextnode = NULL;
539 if (rip) {
540 for (rp = route_top(rip->table); rp; rp = route_next(rp))
541 if ((list = rp->info) != NULL)
542 for (ALL_LIST_ELEMENTS(list, listnode, nextnode,
543 rinfo))
544 if (rinfo->nh.ifindex == ifp->ifindex)
545 rip_ecmp_delete(rinfo);
546
547 ri = ifp->info;
548
549 if (ri->running) {
550 if (IS_RIP_DEBUG_EVENT)
551 zlog_debug("turn off %s", ifp->name);
552
553 /* Leave from multicast group. */
554 rip_multicast_leave(ifp, rip->sock);
555
556 ri->running = 0;
557 }
558 }
559
560 return 0;
561 }
562
563 /* Needed for stop RIP process. */
564 void rip_if_down_all(void)
565 {
566 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
567 struct interface *ifp;
568
569 FOR_ALL_INTERFACES (vrf, ifp)
570 rip_if_down(ifp);
571 }
572
573 static void rip_apply_address_add(struct connected *ifc)
574 {
575 struct prefix_ipv4 address;
576 struct nexthop nh;
577 struct prefix *p;
578
579 if (!rip)
580 return;
581
582 if (!if_is_up(ifc->ifp))
583 return;
584
585 p = ifc->address;
586
587 memset(&address, 0, sizeof(address));
588 memset(&nh, 0, sizeof(nh));
589
590 address.family = p->family;
591 address.prefix = p->u.prefix4;
592 address.prefixlen = p->prefixlen;
593 apply_mask_ipv4(&address);
594
595 nh.ifindex = ifc->ifp->ifindex;
596 nh.type = NEXTHOP_TYPE_IFINDEX;
597
598 /* Check if this interface is RIP enabled or not
599 or Check if this address's prefix is RIP enabled */
600 if ((rip_enable_if_lookup(ifc->ifp->name) >= 0)
601 || (rip_enable_network_lookup2(ifc) >= 0))
602 rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
603 &address, &nh, 0, 0, 0);
604 }
605
606 int rip_interface_address_add(int command, struct zclient *zclient,
607 zebra_size_t length, vrf_id_t vrf_id)
608 {
609 struct connected *ifc;
610 struct prefix *p;
611
612 ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
613 zclient->ibuf, vrf_id);
614
615 if (ifc == NULL)
616 return 0;
617
618 p = ifc->address;
619
620 if (p->family == AF_INET) {
621 if (IS_RIP_DEBUG_ZEBRA)
622 zlog_debug("connected address %s/%d is added",
623 inet_ntoa(p->u.prefix4), p->prefixlen);
624
625 rip_enable_apply(ifc->ifp);
626 /* Check if this prefix needs to be redistributed */
627 rip_apply_address_add(ifc);
628
629 hook_call(rip_ifaddr_add, ifc);
630 }
631
632 return 0;
633 }
634
635 static void rip_apply_address_del(struct connected *ifc)
636 {
637 struct prefix_ipv4 address;
638 struct prefix *p;
639
640 if (!rip)
641 return;
642
643 if (!if_is_up(ifc->ifp))
644 return;
645
646 p = ifc->address;
647
648 memset(&address, 0, sizeof(address));
649 address.family = p->family;
650 address.prefix = p->u.prefix4;
651 address.prefixlen = p->prefixlen;
652 apply_mask_ipv4(&address);
653
654 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,
655 &address, ifc->ifp->ifindex);
656 }
657
658 int rip_interface_address_delete(int command, struct zclient *zclient,
659 zebra_size_t length, vrf_id_t vrf_id)
660 {
661 struct connected *ifc;
662 struct prefix *p;
663
664 ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
665 zclient->ibuf, vrf_id);
666
667 if (ifc) {
668 p = ifc->address;
669 if (p->family == AF_INET) {
670 if (IS_RIP_DEBUG_ZEBRA)
671 zlog_debug("connected address %s/%d is deleted",
672 inet_ntoa(p->u.prefix4),
673 p->prefixlen);
674
675 hook_call(rip_ifaddr_del, ifc);
676
677 /* Chech wether this prefix needs to be removed */
678 rip_apply_address_del(ifc);
679 }
680
681 connected_free(ifc);
682 }
683
684 return 0;
685 }
686
687 /* Check interface is enabled by network statement. */
688 /* Check wether the interface has at least a connected prefix that
689 * is within the ripng_enable_network table. */
690 static int rip_enable_network_lookup_if(struct interface *ifp)
691 {
692 struct listnode *node, *nnode;
693 struct connected *connected;
694 struct prefix_ipv4 address;
695
696 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
697 struct prefix *p;
698 struct route_node *n;
699
700 p = connected->address;
701
702 if (p->family == AF_INET) {
703 address.family = AF_INET;
704 address.prefix = p->u.prefix4;
705 address.prefixlen = IPV4_MAX_BITLEN;
706
707 n = route_node_match(rip_enable_network,
708 (struct prefix *)&address);
709 if (n) {
710 route_unlock_node(n);
711 return 1;
712 }
713 }
714 }
715 return -1;
716 }
717
718 /* Check wether connected is within the ripng_enable_network table. */
719 int rip_enable_network_lookup2(struct connected *connected)
720 {
721 struct prefix_ipv4 address;
722 struct prefix *p;
723
724 p = connected->address;
725
726 if (p->family == AF_INET) {
727 struct route_node *node;
728
729 address.family = p->family;
730 address.prefix = p->u.prefix4;
731 address.prefixlen = IPV4_MAX_BITLEN;
732
733 /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within
734 * rip_enable_network */
735 node = route_node_match(rip_enable_network,
736 (struct prefix *)&address);
737
738 if (node) {
739 route_unlock_node(node);
740 return 1;
741 }
742 }
743
744 return -1;
745 }
746 /* Add RIP enable network. */
747 int rip_enable_network_add(struct prefix *p)
748 {
749 struct route_node *node;
750
751 node = route_node_get(rip_enable_network, p);
752
753 if (node->info) {
754 route_unlock_node(node);
755 return NB_ERR_INCONSISTENCY;
756 } else
757 node->info = (void *)1;
758
759 /* XXX: One should find a better solution than a generic one */
760 rip_enable_apply_all();
761
762 return NB_OK;
763 }
764
765 /* Delete RIP enable network. */
766 int rip_enable_network_delete(struct prefix *p)
767 {
768 struct route_node *node;
769
770 node = route_node_lookup(rip_enable_network, p);
771 if (node) {
772 node->info = NULL;
773
774 /* Unlock info lock. */
775 route_unlock_node(node);
776
777 /* Unlock lookup lock. */
778 route_unlock_node(node);
779
780 /* XXX: One should find a better solution than a generic one */
781 rip_enable_apply_all();
782
783 return NB_OK;
784 }
785
786 return NB_ERR_INCONSISTENCY;
787 }
788
789 /* Check interface is enabled by ifname statement. */
790 static int rip_enable_if_lookup(const char *ifname)
791 {
792 unsigned int i;
793 char *str;
794
795 for (i = 0; i < vector_active(rip_enable_interface); i++)
796 if ((str = vector_slot(rip_enable_interface, i)) != NULL)
797 if (strcmp(str, ifname) == 0)
798 return i;
799 return -1;
800 }
801
802 /* Add interface to rip_enable_if. */
803 int rip_enable_if_add(const char *ifname)
804 {
805 int ret;
806
807 ret = rip_enable_if_lookup(ifname);
808 if (ret >= 0)
809 return NB_ERR_INCONSISTENCY;
810
811 vector_set(rip_enable_interface,
812 XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname));
813
814 rip_enable_apply_all(); /* TODOVJ */
815
816 return NB_OK;
817 }
818
819 /* Delete interface from rip_enable_if. */
820 int rip_enable_if_delete(const char *ifname)
821 {
822 int index;
823 char *str;
824
825 index = rip_enable_if_lookup(ifname);
826 if (index < 0)
827 return NB_ERR_INCONSISTENCY;
828
829 str = vector_slot(rip_enable_interface, index);
830 XFREE(MTYPE_RIP_INTERFACE_STRING, str);
831 vector_unset(rip_enable_interface, index);
832
833 rip_enable_apply_all(); /* TODOVJ */
834
835 return NB_OK;
836 }
837
838 /* Join to multicast group and send request to the interface. */
839 static int rip_interface_wakeup(struct thread *t)
840 {
841 struct interface *ifp;
842 struct rip_interface *ri;
843
844 /* Get interface. */
845 ifp = THREAD_ARG(t);
846
847 ri = ifp->info;
848 ri->t_wakeup = NULL;
849
850 /* Join to multicast group. */
851 if (rip_multicast_join(ifp, rip->sock) < 0) {
852 flog_err_sys(EC_LIB_SOCKET,
853 "multicast join failed, interface %s not running",
854 ifp->name);
855 return 0;
856 }
857
858 /* Set running flag. */
859 ri->running = 1;
860
861 /* Send RIP request to the interface. */
862 rip_request_interface(ifp);
863
864 return 0;
865 }
866
867 static void rip_connect_set(struct interface *ifp, int set)
868 {
869 struct listnode *node, *nnode;
870 struct connected *connected;
871 struct prefix_ipv4 address;
872 struct nexthop nh;
873
874 memset(&nh, 0, sizeof(nh));
875
876 for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) {
877 struct prefix *p;
878 p = connected->address;
879
880 if (p->family != AF_INET)
881 continue;
882
883 address.family = AF_INET;
884 address.prefix = p->u.prefix4;
885 address.prefixlen = p->prefixlen;
886 apply_mask_ipv4(&address);
887
888 nh.ifindex = connected->ifp->ifindex;
889 nh.type = NEXTHOP_TYPE_IFINDEX;
890 if (set) {
891 /* Check once more wether this prefix is within a
892 * "network IF_OR_PREF" one */
893 if ((rip_enable_if_lookup(connected->ifp->name) >= 0)
894 || (rip_enable_network_lookup2(connected) >= 0))
895 rip_redistribute_add(ZEBRA_ROUTE_CONNECT,
896 RIP_ROUTE_INTERFACE,
897 &address, &nh, 0, 0, 0);
898 } else {
899 rip_redistribute_delete(ZEBRA_ROUTE_CONNECT,
900 RIP_ROUTE_INTERFACE, &address,
901 connected->ifp->ifindex);
902 if (rip_redistribute_check(ZEBRA_ROUTE_CONNECT))
903 rip_redistribute_add(ZEBRA_ROUTE_CONNECT,
904 RIP_ROUTE_REDISTRIBUTE,
905 &address, &nh, 0, 0, 0);
906 }
907 }
908 }
909
910 /* Update interface status. */
911 void rip_enable_apply(struct interface *ifp)
912 {
913 int ret;
914 struct rip_interface *ri = NULL;
915
916 /* Check interface. */
917 if (!if_is_operative(ifp))
918 return;
919
920 ri = ifp->info;
921
922 /* Check network configuration. */
923 ret = rip_enable_network_lookup_if(ifp);
924
925 /* If the interface is matched. */
926 if (ret > 0)
927 ri->enable_network = 1;
928 else
929 ri->enable_network = 0;
930
931 /* Check interface name configuration. */
932 ret = rip_enable_if_lookup(ifp->name);
933 if (ret >= 0)
934 ri->enable_interface = 1;
935 else
936 ri->enable_interface = 0;
937
938 /* any interface MUST have an IPv4 address */
939 if (!rip_if_ipv4_address_check(ifp)) {
940 ri->enable_network = 0;
941 ri->enable_interface = 0;
942 }
943
944 /* Update running status of the interface. */
945 if (ri->enable_network || ri->enable_interface) {
946 if (IS_RIP_DEBUG_EVENT)
947 zlog_debug("turn on %s", ifp->name);
948
949 /* Add interface wake up thread. */
950 thread_add_timer(master, rip_interface_wakeup, ifp, 1,
951 &ri->t_wakeup);
952 rip_connect_set(ifp, 1);
953 } else if (ri->running) {
954 /* Might as well clean up the route table as well
955 * rip_if_down sets to 0 ri->running, and displays "turn
956 *off %s"
957 **/
958 rip_if_down(ifp);
959
960 rip_connect_set(ifp, 0);
961 }
962 }
963
964 /* Apply network configuration to all interface. */
965 void rip_enable_apply_all(void)
966 {
967 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
968 struct interface *ifp;
969
970 /* Check each interface. */
971 FOR_ALL_INTERFACES (vrf, ifp)
972 rip_enable_apply(ifp);
973 }
974
975 int rip_neighbor_lookup(struct sockaddr_in *from)
976 {
977 struct prefix_ipv4 p;
978 struct route_node *node;
979
980 memset(&p, 0, sizeof(struct prefix_ipv4));
981 p.family = AF_INET;
982 p.prefix = from->sin_addr;
983 p.prefixlen = IPV4_MAX_BITLEN;
984
985 node = route_node_lookup(rip->neighbor, (struct prefix *)&p);
986 if (node) {
987 route_unlock_node(node);
988 return 1;
989 }
990 return 0;
991 }
992
993 /* Add new RIP neighbor to the neighbor tree. */
994 int rip_neighbor_add(struct prefix_ipv4 *p)
995 {
996 struct route_node *node;
997
998 node = route_node_get(rip->neighbor, (struct prefix *)p);
999
1000 if (node->info)
1001 return NB_ERR_INCONSISTENCY;
1002
1003 node->info = rip->neighbor;
1004
1005 return NB_OK;
1006 }
1007
1008 /* Delete RIP neighbor from the neighbor tree. */
1009 int rip_neighbor_delete(struct prefix_ipv4 *p)
1010 {
1011 struct route_node *node;
1012
1013 /* Lock for look up. */
1014 node = route_node_lookup(rip->neighbor, (struct prefix *)p);
1015 if (!node)
1016 return NB_ERR_INCONSISTENCY;
1017
1018 node->info = NULL;
1019
1020 /* Unlock lookup lock. */
1021 route_unlock_node(node);
1022
1023 /* Unlock real neighbor information lock. */
1024 route_unlock_node(node);
1025
1026 return NB_OK;
1027 }
1028
1029 /* Clear all network and neighbor configuration. */
1030 void rip_clean_network(void)
1031 {
1032 unsigned int i;
1033 char *str;
1034 struct route_node *rn;
1035
1036 /* rip_enable_network. */
1037 for (rn = route_top(rip_enable_network); rn; rn = route_next(rn))
1038 if (rn->info) {
1039 rn->info = NULL;
1040 route_unlock_node(rn);
1041 }
1042
1043 /* rip_enable_interface. */
1044 for (i = 0; i < vector_active(rip_enable_interface); i++)
1045 if ((str = vector_slot(rip_enable_interface, i)) != NULL) {
1046 XFREE(MTYPE_RIP_INTERFACE_STRING, str);
1047 vector_slot(rip_enable_interface, i) = NULL;
1048 }
1049 }
1050
1051 /* Utility function for looking up passive interface settings. */
1052 static int rip_passive_nondefault_lookup(const char *ifname)
1053 {
1054 unsigned int i;
1055 char *str;
1056
1057 for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
1058 if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL)
1059 if (strcmp(str, ifname) == 0)
1060 return i;
1061 return -1;
1062 }
1063
1064 void rip_passive_interface_apply(struct interface *ifp)
1065 {
1066 struct rip_interface *ri;
1067
1068 if (rip == NULL)
1069 return;
1070
1071 ri = ifp->info;
1072
1073 ri->passive = ((rip_passive_nondefault_lookup(ifp->name) < 0)
1074 ? rip->passive_default
1075 : !rip->passive_default);
1076
1077 if (IS_RIP_DEBUG_ZEBRA)
1078 zlog_debug("interface %s: passive = %d", ifp->name,
1079 ri->passive);
1080 }
1081
1082 static void rip_passive_interface_apply_all(void)
1083 {
1084 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1085 struct interface *ifp;
1086
1087 FOR_ALL_INTERFACES (vrf, ifp)
1088 rip_passive_interface_apply(ifp);
1089 }
1090
1091 /* Passive interface. */
1092 int rip_passive_nondefault_set(const char *ifname)
1093 {
1094 if (rip_passive_nondefault_lookup(ifname) >= 0)
1095 /*
1096 * Don't return an error, this can happen after changing
1097 * 'passive-default'.
1098 */
1099 return NB_OK;
1100
1101 vector_set(Vrip_passive_nondefault,
1102 XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname));
1103
1104 rip_passive_interface_apply_all();
1105
1106 return NB_OK;
1107 }
1108
1109 int rip_passive_nondefault_unset(const char *ifname)
1110 {
1111 int i;
1112 char *str;
1113
1114 i = rip_passive_nondefault_lookup(ifname);
1115 if (i < 0)
1116 /*
1117 * Don't return an error, this can happen after changing
1118 * 'passive-default'.
1119 */
1120 return NB_OK;
1121
1122 str = vector_slot(Vrip_passive_nondefault, i);
1123 XFREE(MTYPE_RIP_INTERFACE_STRING, str);
1124 vector_unset(Vrip_passive_nondefault, i);
1125
1126 rip_passive_interface_apply_all();
1127
1128 return NB_OK;
1129 }
1130
1131 /* Free all configured RIP passive-interface settings. */
1132 void rip_passive_nondefault_clean(void)
1133 {
1134 unsigned int i;
1135 char *str;
1136
1137 for (i = 0; i < vector_active(Vrip_passive_nondefault); i++)
1138 if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL) {
1139 XFREE(MTYPE_RIP_INTERFACE_STRING, str);
1140 vector_slot(Vrip_passive_nondefault, i) = NULL;
1141 }
1142 rip_passive_interface_apply_all();
1143 }
1144
1145 /* Write rip configuration of each interface. */
1146 static int rip_interface_config_write(struct vty *vty)
1147 {
1148 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1149 struct interface *ifp;
1150 int write = 0;
1151
1152 FOR_ALL_INTERFACES (vrf, ifp) {
1153 struct lyd_node *dnode;
1154
1155 dnode = yang_dnode_get(
1156 running_config->dnode,
1157 "/frr-interface:lib/interface[name='%s'][vrf='%s']",
1158 ifp->name, vrf->name);
1159 if (dnode == NULL)
1160 continue;
1161
1162 write = 1;
1163 nb_cli_show_dnode_cmds(vty, dnode, false);
1164 }
1165
1166 return write;
1167 }
1168
1169 int rip_show_network_config(struct vty *vty)
1170 {
1171 unsigned int i;
1172 char *ifname;
1173 struct route_node *node;
1174
1175 /* Network type RIP enable interface statement. */
1176 for (node = route_top(rip_enable_network); node;
1177 node = route_next(node))
1178 if (node->info)
1179 vty_out(vty, " %s/%u\n",
1180 inet_ntoa(node->p.u.prefix4),
1181 node->p.prefixlen);
1182
1183 /* Interface name RIP enable statement. */
1184 for (i = 0; i < vector_active(rip_enable_interface); i++)
1185 if ((ifname = vector_slot(rip_enable_interface, i)) != NULL)
1186 vty_out(vty, " %s\n", ifname);
1187
1188 /* RIP neighbors listing. */
1189 for (node = route_top(rip->neighbor); node; node = route_next(node))
1190 if (node->info)
1191 vty_out(vty, " %s\n", inet_ntoa(node->p.u.prefix4));
1192
1193 return 0;
1194 }
1195
1196 static struct cmd_node interface_node = {
1197 INTERFACE_NODE, "%s(config-if)# ", 1,
1198 };
1199
1200 /* Called when interface structure allocated. */
1201 static int rip_interface_new_hook(struct interface *ifp)
1202 {
1203 ifp->info = rip_interface_new();
1204 return 0;
1205 }
1206
1207 /* Called when interface structure deleted. */
1208 static int rip_interface_delete_hook(struct interface *ifp)
1209 {
1210 rip_interface_reset(ifp->info);
1211 XFREE(MTYPE_RIP_INTERFACE, ifp->info);
1212 ifp->info = NULL;
1213 return 0;
1214 }
1215
1216 /* Allocate and initialize interface vector. */
1217 void rip_if_init(void)
1218 {
1219 /* Default initial size of interface vector. */
1220 hook_register_prio(if_add, 0, rip_interface_new_hook);
1221 hook_register_prio(if_del, 0, rip_interface_delete_hook);
1222
1223 /* RIP network init. */
1224 rip_enable_interface = vector_init(1);
1225 rip_enable_network = route_table_init();
1226
1227 /* RIP passive interface. */
1228 Vrip_passive_nondefault = vector_init(1);
1229
1230 /* Install interface node. */
1231 install_node(&interface_node, rip_interface_config_write);
1232 if_cmd_init();
1233 }