xref: /freebsd/sys/net/route.c (revision 6990ffd8a95caaba6858ad44ff1b3157d1efba8f)
1 /*
2  * Copyright (c) 1980, 1986, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)route.c	8.2 (Berkeley) 11/15/93
34  * $FreeBSD$
35  */
36 
37 #include "opt_inet.h"
38 #include "opt_mrouting.h"
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/malloc.h>
43 #include <sys/mbuf.h>
44 #include <sys/socket.h>
45 #include <sys/domain.h>
46 #include <sys/kernel.h>
47 
48 #include <net/if.h>
49 #include <net/route.h>
50 
51 #include <netinet/in.h>
52 #include <netinet/ip_mroute.h>
53 
54 #define	SA(p) ((struct sockaddr *)(p))
55 
56 struct route_cb route_cb;
57 static struct rtstat rtstat;
58 struct radix_node_head *rt_tables[AF_MAX+1];
59 
60 static int	rttrash;		/* routes not in table but not freed */
61 
62 static void rt_maskedcopy __P((struct sockaddr *,
63 	    struct sockaddr *, struct sockaddr *));
64 static void rtable_init __P((void **));
65 
66 static void
67 rtable_init(table)
68 	void **table;
69 {
70 	struct domain *dom;
71 	for (dom = domains; dom; dom = dom->dom_next)
72 		if (dom->dom_rtattach)
73 			dom->dom_rtattach(&table[dom->dom_family],
74 			    dom->dom_rtoffset);
75 }
76 
77 void
78 route_init()
79 {
80 	rn_init();	/* initialize all zeroes, all ones, mask table */
81 	rtable_init((void **)rt_tables);
82 }
83 
84 /*
85  * Packet routing routines.
86  */
87 void
88 rtalloc(ro)
89 	register struct route *ro;
90 {
91 	rtalloc_ign(ro, 0UL);
92 }
93 
94 void
95 rtalloc_ign(ro, ignore)
96 	register struct route *ro;
97 	u_long ignore;
98 {
99 	struct rtentry *rt;
100 	int s;
101 
102 	if ((rt = ro->ro_rt) != NULL) {
103 		if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
104 			return;
105 		/* XXX - We are probably always at splnet here already. */
106 		s = splnet();
107 		RTFREE(rt);
108 		ro->ro_rt = NULL;
109 		splx(s);
110 	}
111 	ro->ro_rt = rtalloc1(&ro->ro_dst, 1, ignore);
112 }
113 
114 /*
115  * Look up the route that matches the address given
116  * Or, at least try.. Create a cloned route if needed.
117  */
118 struct rtentry *
119 rtalloc1(dst, report, ignflags)
120 	register struct sockaddr *dst;
121 	int report;
122 	u_long ignflags;
123 {
124 	register struct radix_node_head *rnh = rt_tables[dst->sa_family];
125 	register struct rtentry *rt;
126 	register struct radix_node *rn;
127 	struct rtentry *newrt = 0;
128 	struct rt_addrinfo info;
129 	u_long nflags;
130 	int  s = splnet(), err = 0, msgtype = RTM_MISS;
131 
132 	/*
133 	 * Look up the address in the table for that Address Family
134 	 */
135 	if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&
136 	    ((rn->rn_flags & RNF_ROOT) == 0)) {
137 		/*
138 		 * If we find it and it's not the root node, then
139 		 * get a refernce on the rtentry associated.
140 		 */
141 		newrt = rt = (struct rtentry *)rn;
142 		nflags = rt->rt_flags & ~ignflags;
143 		if (report && (nflags & (RTF_CLONING | RTF_PRCLONING))) {
144 			/*
145 			 * We are apparently adding (report = 0 in delete).
146 			 * If it requires that it be cloned, do so.
147 			 * (This implies it wasn't a HOST route.)
148 			 */
149 			err = rtrequest(RTM_RESOLVE, dst, SA(0),
150 					      SA(0), 0, &newrt);
151 			if (err) {
152 				/*
153 				 * If the cloning didn't succeed, maybe
154 				 * what we have will do. Return that.
155 				 */
156 				newrt = rt;
157 				rt->rt_refcnt++;
158 				goto miss;
159 			}
160 			if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {
161 				/*
162 				 * If the new route specifies it be
163 				 * externally resolved, then go do that.
164 				 */
165 				msgtype = RTM_RESOLVE;
166 				goto miss;
167 			}
168 		} else
169 			rt->rt_refcnt++;
170 	} else {
171 		/*
172 		 * Either we hit the root or couldn't find any match,
173 		 * Which basically means
174 		 * "caint get there frm here"
175 		 */
176 		rtstat.rts_unreach++;
177 	miss:	if (report) {
178 			/*
179 			 * If required, report the failure to the supervising
180 			 * Authorities.
181 			 * For a delete, this is not an error. (report == 0)
182 			 */
183 			bzero((caddr_t)&info, sizeof(info));
184 			info.rti_info[RTAX_DST] = dst;
185 			rt_missmsg(msgtype, &info, 0, err);
186 		}
187 	}
188 	splx(s);
189 	return (newrt);
190 }
191 
192 /*
193  * Remove a reference count from an rtentry.
194  * If the count gets low enough, take it out of the routing table
195  */
196 void
197 rtfree(rt)
198 	register struct rtentry *rt;
199 {
200 	/*
201 	 * find the tree for that address family
202 	 */
203 	register struct radix_node_head *rnh =
204 		rt_tables[rt_key(rt)->sa_family];
205 	register struct ifaddr *ifa;
206 
207 	if (rt == 0 || rnh == 0)
208 		panic("rtfree");
209 
210 	/*
211 	 * decrement the reference count by one and if it reaches 0,
212 	 * and there is a close function defined, call the close function
213 	 */
214 	rt->rt_refcnt--;
215 	if(rnh->rnh_close && rt->rt_refcnt == 0) {
216 		rnh->rnh_close((struct radix_node *)rt, rnh);
217 	}
218 
219 	/*
220 	 * If we are no longer "up" (and ref == 0)
221 	 * then we can free the resources associated
222 	 * with the route.
223 	 */
224 	if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) {
225 		if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
226 			panic ("rtfree 2");
227 		/*
228 		 * the rtentry must have been removed from the routing table
229 		 * so it is represented in rttrash.. remove that now.
230 		 */
231 		rttrash--;
232 
233 #ifdef	DIAGNOSTIC
234 		if (rt->rt_refcnt < 0) {
235 			printf("rtfree: %p not freed (neg refs)\n", rt);
236 			return;
237 		}
238 #endif
239 
240 		/*
241 		 * release references on items we hold them on..
242 		 * e.g other routes and ifaddrs.
243 		 */
244 		if((ifa = rt->rt_ifa))
245 			IFAFREE(ifa);
246 		if (rt->rt_parent) {
247 			RTFREE(rt->rt_parent);
248 		}
249 
250 		/*
251 		 * The key is separatly alloc'd so free it (see rt_setgate()).
252 		 * This also frees the gateway, as they are always malloc'd
253 		 * together.
254 		 */
255 		Free(rt_key(rt));
256 
257 		/*
258 		 * and the rtentry itself of course
259 		 */
260 		Free(rt);
261 	}
262 }
263 
264 void
265 ifafree(ifa)
266 	register struct ifaddr *ifa;
267 {
268 	if (ifa == NULL)
269 		panic("ifafree");
270 	if (ifa->ifa_refcnt == 0)
271 		free(ifa, M_IFADDR);
272 	else
273 		ifa->ifa_refcnt--;
274 }
275 
276 /*
277  * Force a routing table entry to the specified
278  * destination to go through the given gateway.
279  * Normally called as a result of a routing redirect
280  * message from the network layer.
281  *
282  * N.B.: must be called at splnet
283  *
284  */
285 void
286 rtredirect(dst, gateway, netmask, flags, src, rtp)
287 	struct sockaddr *dst, *gateway, *netmask, *src;
288 	int flags;
289 	struct rtentry **rtp;
290 {
291 	register struct rtentry *rt;
292 	int error = 0;
293 	short *stat = 0;
294 	struct rt_addrinfo info;
295 	struct ifaddr *ifa;
296 
297 	/* verify the gateway is directly reachable */
298 	if ((ifa = ifa_ifwithnet(gateway)) == 0) {
299 		error = ENETUNREACH;
300 		goto out;
301 	}
302 	rt = rtalloc1(dst, 0, 0UL);
303 	/*
304 	 * If the redirect isn't from our current router for this dst,
305 	 * it's either old or wrong.  If it redirects us to ourselves,
306 	 * we have a routing loop, perhaps as a result of an interface
307 	 * going down recently.
308 	 */
309 #define	equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)
310 	if (!(flags & RTF_DONE) && rt &&
311 	     (!equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
312 		error = EINVAL;
313 	else if (ifa_ifwithaddr(gateway))
314 		error = EHOSTUNREACH;
315 	if (error)
316 		goto done;
317 	/*
318 	 * Create a new entry if we just got back a wildcard entry
319 	 * or the the lookup failed.  This is necessary for hosts
320 	 * which use routing redirects generated by smart gateways
321 	 * to dynamically build the routing tables.
322 	 */
323 	if ((rt == 0) || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
324 		goto create;
325 	/*
326 	 * Don't listen to the redirect if it's
327 	 * for a route to an interface.
328 	 */
329 	if (rt->rt_flags & RTF_GATEWAY) {
330 		if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
331 			/*
332 			 * Changing from route to net => route to host.
333 			 * Create new route, rather than smashing route to net.
334 			 */
335 		create:
336 			flags |=  RTF_GATEWAY | RTF_DYNAMIC;
337 			error = rtrequest((int)RTM_ADD, dst, gateway,
338 				    netmask, flags,
339 				    (struct rtentry **)0);
340 			stat = &rtstat.rts_dynamic;
341 		} else {
342 			/*
343 			 * Smash the current notion of the gateway to
344 			 * this destination.  Should check about netmask!!!
345 			 */
346 			rt->rt_flags |= RTF_MODIFIED;
347 			flags |= RTF_MODIFIED;
348 			stat = &rtstat.rts_newgateway;
349 			/*
350 			 * add the key and gateway (in one malloc'd chunk).
351 			 */
352 			rt_setgate(rt, rt_key(rt), gateway);
353 		}
354 	} else
355 		error = EHOSTUNREACH;
356 done:
357 	if (rt) {
358 		if (rtp && !error)
359 			*rtp = rt;
360 		else
361 			rtfree(rt);
362 	}
363 out:
364 	if (error)
365 		rtstat.rts_badredirect++;
366 	else if (stat != NULL)
367 		(*stat)++;
368 	bzero((caddr_t)&info, sizeof(info));
369 	info.rti_info[RTAX_DST] = dst;
370 	info.rti_info[RTAX_GATEWAY] = gateway;
371 	info.rti_info[RTAX_NETMASK] = netmask;
372 	info.rti_info[RTAX_AUTHOR] = src;
373 	rt_missmsg(RTM_REDIRECT, &info, flags, error);
374 }
375 
376 /*
377 * Routing table ioctl interface.
378 */
379 int
380 rtioctl(req, data)
381 	int req;
382 	caddr_t data;
383 {
384 #ifdef INET
385 	/* Multicast goop, grrr... */
386 	return mrt_ioctl(req, data);
387 #else /* INET */
388 	return ENXIO;
389 #endif /* INET */
390 }
391 
392 struct ifaddr *
393 ifa_ifwithroute(flags, dst, gateway)
394 	int flags;
395 	struct sockaddr	*dst, *gateway;
396 {
397 	register struct ifaddr *ifa;
398 	if ((flags & RTF_GATEWAY) == 0) {
399 		/*
400 		 * If we are adding a route to an interface,
401 		 * and the interface is a pt to pt link
402 		 * we should search for the destination
403 		 * as our clue to the interface.  Otherwise
404 		 * we can use the local address.
405 		 */
406 		ifa = 0;
407 		if (flags & RTF_HOST) {
408 			ifa = ifa_ifwithdstaddr(dst);
409 		}
410 		if (ifa == 0)
411 			ifa = ifa_ifwithaddr(gateway);
412 	} else {
413 		/*
414 		 * If we are adding a route to a remote net
415 		 * or host, the gateway may still be on the
416 		 * other end of a pt to pt link.
417 		 */
418 		ifa = ifa_ifwithdstaddr(gateway);
419 	}
420 	if (ifa == 0)
421 		ifa = ifa_ifwithnet(gateway);
422 	if (ifa == 0) {
423 		struct rtentry *rt = rtalloc1(gateway, 0, 0UL);
424 		if (rt == 0)
425 			return (0);
426 		rt->rt_refcnt--;
427 		if ((ifa = rt->rt_ifa) == 0)
428 			return (0);
429 	}
430 	if (ifa->ifa_addr->sa_family != dst->sa_family) {
431 		struct ifaddr *oifa = ifa;
432 		ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
433 		if (ifa == 0)
434 			ifa = oifa;
435 	}
436 	return (ifa);
437 }
438 
439 #define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
440 
441 static int rt_fixdelete __P((struct radix_node *, void *));
442 static int rt_fixchange __P((struct radix_node *, void *));
443 
444 struct rtfc_arg {
445 	struct rtentry *rt0;
446 	struct radix_node_head *rnh;
447 };
448 
449 /*
450  * Do appropriate manipulations of a routing tree given
451  * all the bits of info needed
452  */
453 int
454 rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
455 	int req, flags;
456 	struct sockaddr *dst, *gateway, *netmask;
457 	struct rtentry **ret_nrt;
458 {
459 	int s = splnet(); int error = 0;
460 	register struct rtentry *rt;
461 	register struct radix_node *rn;
462 	register struct radix_node_head *rnh;
463 	struct ifaddr *ifa;
464 	struct sockaddr *ndst;
465 #define senderr(x) { error = x ; goto bad; }
466 
467 	/*
468 	 * Find the correct routing tree to use for this Address Family
469 	 */
470 	if ((rnh = rt_tables[dst->sa_family]) == 0)
471 		senderr(ESRCH);
472 	/*
473 	 * If we are adding a host route then we don't want to put
474 	 * a netmask in the tree
475 	 */
476 	if (flags & RTF_HOST)
477 		netmask = 0;
478 	switch (req) {
479 	case RTM_DELETE:
480 		/*
481 		 * Remove the item from the tree and return it.
482 		 * Complain if it is not there and do no more processing.
483 		 */
484 		if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == 0)
485 			senderr(ESRCH);
486 		if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
487 			panic ("rtrequest delete");
488 		rt = (struct rtentry *)rn;
489 
490 		/*
491 		 * Now search what's left of the subtree for any cloned
492 		 * routes which might have been formed from this node.
493 		 */
494 		if ((rt->rt_flags & (RTF_CLONING | RTF_PRCLONING)) &&
495 		    rt_mask(rt)) {
496 			rnh->rnh_walktree_from(rnh, dst, rt_mask(rt),
497 					       rt_fixdelete, rt);
498 		}
499 
500 		/*
501 		 * Remove any external references we may have.
502 		 * This might result in another rtentry being freed if
503 		 * we held its last reference.
504 		 */
505 		if (rt->rt_gwroute) {
506 			rt = rt->rt_gwroute;
507 			RTFREE(rt);
508 			(rt = (struct rtentry *)rn)->rt_gwroute = 0;
509 		}
510 
511 		/*
512 		 * NB: RTF_UP must be set during the search above,
513 		 * because we might delete the last ref, causing
514 		 * rt to get freed prematurely.
515 		 *  eh? then why not just add a reference?
516 		 * I'm not sure how RTF_UP helps matters. (JRE)
517 		 */
518 		rt->rt_flags &= ~RTF_UP;
519 
520 		/*
521 		 * give the protocol a chance to keep things in sync.
522 		 */
523 		if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
524 			ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0));
525 
526 		/*
527 		 * one more rtentry floating around that is not
528 		 * linked to the routing table.
529 		 */
530 		rttrash++;
531 
532 		/*
533 		 * If the caller wants it, then it can have it,
534 		 * but it's up to it to free the rtentry as we won't be
535 		 * doing it.
536 		 */
537 		if (ret_nrt)
538 			*ret_nrt = rt;
539 		else if (rt->rt_refcnt <= 0) {
540 			rt->rt_refcnt++; /* make a 1->0 transition */
541 			rtfree(rt);
542 		}
543 		break;
544 
545 	case RTM_RESOLVE:
546 		if (ret_nrt == 0 || (rt = *ret_nrt) == 0)
547 			senderr(EINVAL);
548 		ifa = rt->rt_ifa;
549 		flags = rt->rt_flags &
550 		    ~(RTF_CLONING | RTF_PRCLONING | RTF_STATIC);
551 		flags |= RTF_WASCLONED;
552 		gateway = rt->rt_gateway;
553 		if ((netmask = rt->rt_genmask) == 0)
554 			flags |= RTF_HOST;
555 		goto makeroute;
556 
557 	case RTM_ADD:
558 		if ((flags & RTF_GATEWAY) && !gateway)
559 			panic("rtrequest: GATEWAY but no gateway");
560 
561 		if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0)
562 			senderr(ENETUNREACH);
563 
564 	makeroute:
565 		R_Malloc(rt, struct rtentry *, sizeof(*rt));
566 		if (rt == 0)
567 			senderr(ENOBUFS);
568 		Bzero(rt, sizeof(*rt));
569 		rt->rt_flags = RTF_UP | flags;
570 		/*
571 		 * Add the gateway. Possibly re-malloc-ing the storage for it
572 		 * also add the rt_gwroute if possible.
573 		 */
574 		if ((error = rt_setgate(rt, dst, gateway)) != 0) {
575 			Free(rt);
576 			senderr(error);
577 		}
578 
579 		/*
580 		 * point to the (possibly newly malloc'd) dest address.
581 		 */
582 		ndst = rt_key(rt);
583 
584 		/*
585 		 * make sure it contains the value we want (masked if needed).
586 		 */
587 		if (netmask) {
588 			rt_maskedcopy(dst, ndst, netmask);
589 		} else
590 			Bcopy(dst, ndst, dst->sa_len);
591 
592 		/*
593 		 * Note that we now have a reference to the ifa.
594 		 * This moved from below so that rnh->rnh_addaddr() can
595 		 * examine the ifa and  ifa->ifa_ifp if it so desires.
596 		 */
597 		ifa->ifa_refcnt++;
598 		rt->rt_ifa = ifa;
599 		rt->rt_ifp = ifa->ifa_ifp;
600 		/* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
601 
602 		rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask,
603 					rnh, rt->rt_nodes);
604 		if (rn == 0) {
605 			struct rtentry *rt2;
606 			/*
607 			 * Uh-oh, we already have one of these in the tree.
608 			 * We do a special hack: if the route that's already
609 			 * there was generated by the protocol-cloning
610 			 * mechanism, then we just blow it away and retry
611 			 * the insertion of the new one.
612 			 */
613 			rt2 = rtalloc1(dst, 0, RTF_PRCLONING);
614 			if (rt2 && rt2->rt_parent) {
615 				rtrequest(RTM_DELETE,
616 					  (struct sockaddr *)rt_key(rt2),
617 					  rt2->rt_gateway,
618 					  rt_mask(rt2), rt2->rt_flags, 0);
619 				RTFREE(rt2);
620 				rn = rnh->rnh_addaddr((caddr_t)ndst,
621 						      (caddr_t)netmask,
622 						      rnh, rt->rt_nodes);
623 			} else if (rt2) {
624 				/* undo the extra ref we got */
625 				RTFREE(rt2);
626 			}
627 		}
628 
629 		/*
630 		 * If it still failed to go into the tree,
631 		 * then un-make it (this should be a function)
632 		 */
633 		if (rn == 0) {
634 			if (rt->rt_gwroute)
635 				rtfree(rt->rt_gwroute);
636 			if (rt->rt_ifa) {
637 				IFAFREE(rt->rt_ifa);
638 			}
639 			Free(rt_key(rt));
640 			Free(rt);
641 			senderr(EEXIST);
642 		}
643 
644 		rt->rt_parent = 0;
645 
646 		/*
647 		 * If we got here from RESOLVE, then we are cloning
648 		 * so clone the rest, and note that we
649 		 * are a clone (and increment the parent's references)
650 		 */
651 		if (req == RTM_RESOLVE) {
652 			rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
653 			if ((*ret_nrt)->rt_flags & (RTF_CLONING | RTF_PRCLONING)) {
654 				rt->rt_parent = (*ret_nrt);
655 				(*ret_nrt)->rt_refcnt++;
656 			}
657 		}
658 
659 		/*
660 		 * if this protocol has something to add to this then
661 		 * allow it to do that as well.
662 		 */
663 		if (ifa->ifa_rtrequest)
664 			ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0));
665 
666 		/*
667 		 * We repeat the same procedure from rt_setgate() here because
668 		 * it doesn't fire when we call it there because the node
669 		 * hasn't been added to the tree yet.
670 		 */
671 		if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) {
672 			struct rtfc_arg arg;
673 			arg.rnh = rnh;
674 			arg.rt0 = rt;
675 			rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
676 					       rt_fixchange, &arg);
677 		}
678 
679 		/*
680 		 * actually return a resultant rtentry and
681 		 * give the caller a single reference.
682 		 */
683 		if (ret_nrt) {
684 			*ret_nrt = rt;
685 			rt->rt_refcnt++;
686 		}
687 		break;
688 	}
689 bad:
690 	splx(s);
691 	return (error);
692 }
693 
694 /*
695  * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family''
696  * (i.e., the routes related to it by the operation of cloning).  This
697  * routine is iterated over all potential former-child-routes by way of
698  * rnh->rnh_walktree_from() above, and those that actually are children of
699  * the late parent (passed in as VP here) are themselves deleted.
700  */
701 static int
702 rt_fixdelete(rn, vp)
703 	struct radix_node *rn;
704 	void *vp;
705 {
706 	struct rtentry *rt = (struct rtentry *)rn;
707 	struct rtentry *rt0 = vp;
708 
709 	if (rt->rt_parent == rt0 && !(rt->rt_flags & RTF_PINNED)) {
710 		return rtrequest(RTM_DELETE, rt_key(rt),
711 				 (struct sockaddr *)0, rt_mask(rt),
712 				 rt->rt_flags, (struct rtentry **)0);
713 	}
714 	return 0;
715 }
716 
717 /*
718  * This routine is called from rt_setgate() to do the analogous thing for
719  * adds and changes.  There is the added complication in this case of a
720  * middle insert; i.e., insertion of a new network route between an older
721  * network route and (cloned) host routes.  For this reason, a simple check
722  * of rt->rt_parent is insufficient; each candidate route must be tested
723  * against the (mask, value) of the new route (passed as before in vp)
724  * to see if the new route matches it.
725  *
726  * XXX - it may be possible to do fixdelete() for changes and reserve this
727  * routine just for adds.  I'm not sure why I thought it was necessary to do
728  * changes this way.
729  */
730 #ifdef DEBUG
731 static int rtfcdebug = 0;
732 #endif
733 
734 static int
735 rt_fixchange(rn, vp)
736 	struct radix_node *rn;
737 	void *vp;
738 {
739 	struct rtentry *rt = (struct rtentry *)rn;
740 	struct rtfc_arg *ap = vp;
741 	struct rtentry *rt0 = ap->rt0;
742 	struct radix_node_head *rnh = ap->rnh;
743 	u_char *xk1, *xm1, *xk2, *xmp;
744 	int i, len, mlen;
745 
746 #ifdef DEBUG
747 	if (rtfcdebug)
748 		printf("rt_fixchange: rt %p, rt0 %p\n", rt, rt0);
749 #endif
750 
751 	if (!rt->rt_parent || (rt->rt_flags & RTF_PINNED)) {
752 #ifdef DEBUG
753 		if(rtfcdebug) printf("no parent or pinned\n");
754 #endif
755 		return 0;
756 	}
757 
758 	if (rt->rt_parent == rt0) {
759 #ifdef DEBUG
760 		if(rtfcdebug) printf("parent match\n");
761 #endif
762 		return rtrequest(RTM_DELETE, rt_key(rt),
763 				 (struct sockaddr *)0, rt_mask(rt),
764 				 rt->rt_flags, (struct rtentry **)0);
765 	}
766 
767 	/*
768 	 * There probably is a function somewhere which does this...
769 	 * if not, there should be.
770 	 */
771 	len = imin(((struct sockaddr *)rt_key(rt0))->sa_len,
772 		   ((struct sockaddr *)rt_key(rt))->sa_len);
773 
774 	xk1 = (u_char *)rt_key(rt0);
775 	xm1 = (u_char *)rt_mask(rt0);
776 	xk2 = (u_char *)rt_key(rt);
777 
778 	/* avoid applying a less specific route */
779 	xmp = (u_char *)rt_mask(rt->rt_parent);
780 	mlen = ((struct sockaddr *)rt_key(rt->rt_parent))->sa_len;
781 	if (mlen > ((struct sockaddr *)rt_key(rt0))->sa_len) {
782 #ifdef DEBUG
783 		if (rtfcdebug)
784 			printf("rt_fixchange: inserting a less "
785 			       "specific route\n");
786 #endif
787 		return 0;
788 	}
789 	for (i = rnh->rnh_treetop->rn_offset; i < mlen; i++) {
790 		if ((xmp[i] & ~(xmp[i] ^ xm1[i])) != xmp[i]) {
791 #ifdef DEBUG
792 			if (rtfcdebug)
793 				printf("rt_fixchange: inserting a less "
794 				       "specific route\n");
795 #endif
796 			return 0;
797 		}
798 	}
799 
800 	for (i = rnh->rnh_treetop->rn_offset; i < len; i++) {
801 		if ((xk2[i] & xm1[i]) != xk1[i]) {
802 #ifdef DEBUG
803 			if(rtfcdebug) printf("no match\n");
804 #endif
805 			return 0;
806 		}
807 	}
808 
809 	/*
810 	 * OK, this node is a clone, and matches the node currently being
811 	 * changed/added under the node's mask.  So, get rid of it.
812 	 */
813 #ifdef DEBUG
814 	if(rtfcdebug) printf("deleting\n");
815 #endif
816 	return rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,
817 			 rt_mask(rt), rt->rt_flags, (struct rtentry **)0);
818 }
819 
820 int
821 rt_setgate(rt0, dst, gate)
822 	struct rtentry *rt0;
823 	struct sockaddr *dst, *gate;
824 {
825 	caddr_t new, old;
826 	int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len);
827 	register struct rtentry *rt = rt0;
828 	struct radix_node_head *rnh = rt_tables[dst->sa_family];
829 
830 	/*
831 	 * A host route with the destination equal to the gateway
832 	 * will interfere with keeping LLINFO in the routing
833 	 * table, so disallow it.
834 	 */
835 	if (((rt0->rt_flags & (RTF_HOST|RTF_GATEWAY|RTF_LLINFO)) ==
836 					(RTF_HOST|RTF_GATEWAY)) &&
837 	    (dst->sa_len == gate->sa_len) &&
838 	    (bcmp(dst, gate, dst->sa_len) == 0)) {
839 		/*
840 		 * The route might already exist if this is an RTM_CHANGE
841 		 * or a routing redirect, so try to delete it.
842 		 */
843 		if (rt_key(rt0))
844 			rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt0),
845 			    rt0->rt_gateway, rt_mask(rt0), rt0->rt_flags, 0);
846 		return EADDRNOTAVAIL;
847 	}
848 
849 	/*
850 	 * Both dst and gateway are stored in the same malloc'd chunk
851 	 * (If I ever get my hands on....)
852 	 * if we need to malloc a new chunk, then keep the old one around
853 	 * till we don't need it any more.
854 	 */
855 	if (rt->rt_gateway == 0 || glen > ROUNDUP(rt->rt_gateway->sa_len)) {
856 		old = (caddr_t)rt_key(rt);
857 		R_Malloc(new, caddr_t, dlen + glen);
858 		if (new == 0)
859 			return ENOBUFS;
860 		rt->rt_nodes->rn_key = new;
861 	} else {
862 		/*
863 		 * otherwise just overwrite the old one
864 		 */
865 		new = rt->rt_nodes->rn_key;
866 		old = 0;
867 	}
868 
869 	/*
870 	 * copy the new gateway value into the memory chunk
871 	 */
872 	Bcopy(gate, (rt->rt_gateway = (struct sockaddr *)(new + dlen)), glen);
873 
874 	/*
875 	 * if we are replacing the chunk (or it's new) we need to
876 	 * replace the dst as well
877 	 */
878 	if (old) {
879 		Bcopy(dst, new, dlen);
880 		Free(old);
881 	}
882 
883 	/*
884 	 * If there is already a gwroute, it's now almost definitly wrong
885 	 * so drop it.
886 	 */
887 	if (rt->rt_gwroute) {
888 		rt = rt->rt_gwroute; RTFREE(rt);
889 		rt = rt0; rt->rt_gwroute = 0;
890 	}
891 	/*
892 	 * Cloning loop avoidance:
893 	 * In the presence of protocol-cloning and bad configuration,
894 	 * it is possible to get stuck in bottomless mutual recursion
895 	 * (rtrequest rt_setgate rtalloc1).  We avoid this by not allowing
896 	 * protocol-cloning to operate for gateways (which is probably the
897 	 * correct choice anyway), and avoid the resulting reference loops
898 	 * by disallowing any route to run through itself as a gateway.
899 	 * This is obviously mandatory when we get rt->rt_output().
900 	 */
901 	if (rt->rt_flags & RTF_GATEWAY) {
902 		rt->rt_gwroute = rtalloc1(gate, 1, RTF_PRCLONING);
903 		if (rt->rt_gwroute == rt) {
904 			RTFREE(rt->rt_gwroute);
905 			rt->rt_gwroute = 0;
906 			return EDQUOT; /* failure */
907 		}
908 	}
909 
910 	/*
911 	 * This isn't going to do anything useful for host routes, so
912 	 * don't bother.  Also make sure we have a reasonable mask
913 	 * (we don't yet have one during adds).
914 	 */
915 	if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != 0) {
916 		struct rtfc_arg arg;
917 		arg.rnh = rnh;
918 		arg.rt0 = rt;
919 		rnh->rnh_walktree_from(rnh, rt_key(rt), rt_mask(rt),
920 				       rt_fixchange, &arg);
921 	}
922 
923 	return 0;
924 }
925 
926 static void
927 rt_maskedcopy(src, dst, netmask)
928 	struct sockaddr *src, *dst, *netmask;
929 {
930 	register u_char *cp1 = (u_char *)src;
931 	register u_char *cp2 = (u_char *)dst;
932 	register u_char *cp3 = (u_char *)netmask;
933 	u_char *cplim = cp2 + *cp3;
934 	u_char *cplim2 = cp2 + *cp1;
935 
936 	*cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */
937 	cp3 += 2;
938 	if (cplim > cplim2)
939 		cplim = cplim2;
940 	while (cp2 < cplim)
941 		*cp2++ = *cp1++ & *cp3++;
942 	if (cp2 < cplim2)
943 		bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
944 }
945 
946 /*
947  * Set up a routing table entry, normally
948  * for an interface.
949  */
950 int
951 rtinit(ifa, cmd, flags)
952 	register struct ifaddr *ifa;
953 	int cmd, flags;
954 {
955 	register struct rtentry *rt;
956 	register struct sockaddr *dst;
957 	register struct sockaddr *deldst;
958 	struct mbuf *m = 0;
959 	struct rtentry *nrt = 0;
960 	int error;
961 
962 	dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
963 	/*
964 	 * If it's a delete, check that if it exists, it's on the correct
965 	 * interface or we might scrub a route to another ifa which would
966 	 * be confusing at best and possibly worse.
967 	 */
968 	if (cmd == RTM_DELETE) {
969 		/*
970 		 * It's a delete, so it should already exist..
971 		 * If it's a net, mask off the host bits
972 		 * (Assuming we have a mask)
973 		 */
974 		if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
975 			m = m_get(M_DONTWAIT, MT_SONAME);
976 			if (m == NULL)
977 				return(ENOBUFS);
978 			deldst = mtod(m, struct sockaddr *);
979 			rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
980 			dst = deldst;
981 		}
982 		/*
983 		 * Get an rtentry that is in the routing tree and
984 		 * contains the correct info. (if this fails, can't get there).
985 		 * We set "report" to FALSE so that if it doesn't exist,
986 		 * it doesn't report an error or clone a route, etc. etc.
987 		 */
988 		rt = rtalloc1(dst, 0, 0UL);
989 		if (rt) {
990 			/*
991 			 * Ok so we found the rtentry. it has an extra reference
992 			 * for us at this stage. we won't need that so
993 			 * lop that off now.
994 			 */
995 			rt->rt_refcnt--;
996 			if (rt->rt_ifa != ifa) {
997 				/*
998 				 * If the interface in the rtentry doesn't match
999 				 * the interface we are using, then we don't
1000 				 * want to delete it, so return an error.
1001 				 * This seems to be the only point of
1002 				 * this whole RTM_DELETE clause.
1003 				 */
1004 				if (m)
1005 					(void) m_free(m);
1006 				return (flags & RTF_HOST ? EHOSTUNREACH
1007 							: ENETUNREACH);
1008 			}
1009 		}
1010 		/* XXX */
1011 #if 0
1012 		else {
1013 			/*
1014 			 * One would think that as we are deleting, and we know
1015 			 * it doesn't exist, we could just return at this point
1016 			 * with an "ELSE" clause, but apparently not..
1017 			 */
1018 			return (flags & RTF_HOST ? EHOSTUNREACH
1019 							: ENETUNREACH);
1020 		}
1021 #endif
1022 	}
1023 	/*
1024 	 * Do the actual request
1025 	 */
1026 	error = rtrequest(cmd, dst, ifa->ifa_addr, ifa->ifa_netmask,
1027 			flags | ifa->ifa_flags, &nrt);
1028 	if (m)
1029 		(void) m_free(m);
1030 	/*
1031 	 * If we are deleting, and we found an entry, then
1032 	 * it's been removed from the tree.. now throw it away.
1033 	 */
1034 	if (cmd == RTM_DELETE && error == 0 && (rt = nrt)) {
1035 		/*
1036 		 * notify any listenning routing agents of the change
1037 		 */
1038 		rt_newaddrmsg(cmd, ifa, error, nrt);
1039 		if (rt->rt_refcnt <= 0) {
1040 			rt->rt_refcnt++; /* need a 1->0 transition to free */
1041 			rtfree(rt);
1042 		}
1043 	}
1044 
1045 	/*
1046 	 * We are adding, and we have a returned routing entry.
1047 	 * We need to sanity check the result.
1048 	 */
1049 	if (cmd == RTM_ADD && error == 0 && (rt = nrt)) {
1050 		/*
1051 		 * We just wanted to add it.. we don't actually need a reference
1052 		 */
1053 		rt->rt_refcnt--;
1054 		/*
1055 		 * If it came back with an unexpected interface, then it must
1056 		 * have already existed or something. (XXX)
1057 		 */
1058 		if (rt->rt_ifa != ifa) {
1059 			if (!(rt->rt_ifa->ifa_ifp->if_flags &
1060 			    (IFF_POINTOPOINT|IFF_LOOPBACK)))
1061 				printf("rtinit: wrong ifa (%p) was (%p)\n",
1062 				    ifa, rt->rt_ifa);
1063 			/*
1064 			 * Ask that the protocol in question
1065 			 * remove anything it has associated with
1066 			 * this route and ifaddr.
1067 			 */
1068 			if (rt->rt_ifa->ifa_rtrequest)
1069 			    rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0));
1070 			/*
1071 			 * Remove the reference to its ifaddr.
1072 			 */
1073 			IFAFREE(rt->rt_ifa);
1074 			/*
1075 			 * And substitute in references to the ifaddr
1076 			 * we are adding.
1077 			 */
1078 			rt->rt_ifa = ifa;
1079 			rt->rt_ifp = ifa->ifa_ifp;
1080 			rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu;	/*XXX*/
1081 			ifa->ifa_refcnt++;
1082 			/*
1083 			 * Now ask the protocol to check if it needs
1084 			 * any special processing in its new form.
1085 			 */
1086 			if (ifa->ifa_rtrequest)
1087 			    ifa->ifa_rtrequest(RTM_ADD, rt, SA(0));
1088 		}
1089 		/*
1090 		 * notify any listenning routing agents of the change
1091 		 */
1092 		rt_newaddrmsg(cmd, ifa, error, nrt);
1093 	}
1094 	return (error);
1095 }
1096 
1097 /* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */
1098 SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);
1099