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