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