]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/route.c
Remove unused VNET_SET() and related macros; only VNET_GET() is
[FreeBSD/FreeBSD.git] / sys / net / route.c
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  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  *      @(#)route.c     8.3.1.1 (Berkeley) 2/23/95
30  * $FreeBSD$
31  */
32 /************************************************************************
33  * Note: In this file a 'fib' is a "forwarding information base"        *
34  * Which is the new name for an in kernel routing (next hop) table.     *
35  ***********************************************************************/
36
37 #include "opt_inet.h"
38 #include "opt_route.h"
39 #include "opt_mrouting.h"
40 #include "opt_mpath.h"
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/syslog.h>
45 #include <sys/malloc.h>
46 #include <sys/mbuf.h>
47 #include <sys/socket.h>
48 #include <sys/sysctl.h>
49 #include <sys/syslog.h>
50 #include <sys/sysproto.h>
51 #include <sys/proc.h>
52 #include <sys/domain.h>
53 #include <sys/kernel.h>
54 #include <sys/vimage.h>
55
56 #include <net/if.h>
57 #include <net/if_dl.h>
58 #include <net/route.h>
59
60 #ifdef RADIX_MPATH
61 #include <net/radix_mpath.h>
62 #endif
63
64 #include <netinet/in.h>
65 #include <netinet/ip_mroute.h>
66
67 #include <vm/uma.h>
68
69 u_int rt_numfibs = RT_NUMFIBS;
70 SYSCTL_INT(_net, OID_AUTO, fibs, CTLFLAG_RD, &rt_numfibs, 0, "");
71 /*
72  * Allow the boot code to allow LESS than RT_MAXFIBS to be used.
73  * We can't do more because storage is statically allocated for now.
74  * (for compatibility reasons.. this will change).
75  */
76 TUNABLE_INT("net.fibs", &rt_numfibs);
77
78 /*
79  * By default add routes to all fibs for new interfaces.
80  * Once this is set to 0 then only allocate routes on interface
81  * changes for the FIB of the caller when adding a new set of addresses
82  * to an interface.  XXX this is a shotgun aproach to a problem that needs
83  * a more fine grained solution.. that will come.
84  */
85 u_int rt_add_addr_allfibs = 1;
86 SYSCTL_INT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RW,
87     &rt_add_addr_allfibs, 0, "");
88 TUNABLE_INT("net.add_addr_allfibs", &rt_add_addr_allfibs);
89
90 VNET_DEFINE(struct radix_node_head *, rt_tables);
91 static VNET_DEFINE(uma_zone_t, rtzone);         /* Routing table UMA zone. */
92 VNET_DEFINE(int, rttrash);              /* routes not in table but not freed */
93 VNET_DEFINE(struct rtstat, rtstat);
94
95 #define V_rt_tables     VNET(rt_tables)
96 #define V_rtzone        VNET(rtzone)
97 #define V_rttrash       VNET(rttrash)
98 #define V_rtstat        VNET(rtstat)
99
100 static void rt_maskedcopy(struct sockaddr *,
101             struct sockaddr *, struct sockaddr *);
102 static int vnet_route_iattach(const void *);
103 #ifdef VIMAGE
104 static int vnet_route_idetach(const void *);
105
106 static const vnet_modinfo_t vnet_rtable_modinfo = {
107         .vmi_id         = VNET_MOD_RTABLE,
108         .vmi_name       = "rtable",
109         .vmi_iattach    = vnet_route_iattach,
110         .vmi_idetach    = vnet_route_idetach
111 };
112 #endif
113
114 /* compare two sockaddr structures */
115 #define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
116
117 /*
118  * Convert a 'struct radix_node *' to a 'struct rtentry *'.
119  * The operation can be done safely (in this code) because a
120  * 'struct rtentry' starts with two 'struct radix_node''s, the first
121  * one representing leaf nodes in the routing tree, which is
122  * what the code in radix.c passes us as a 'struct radix_node'.
123  *
124  * But because there are a lot of assumptions in this conversion,
125  * do not cast explicitly, but always use the macro below.
126  */
127 #define RNTORT(p)       ((struct rtentry *)(p))
128
129 #if 0
130 /* default fib for tunnels to use */
131 u_int tunnel_fib = 0;
132 SYSCTL_INT(_net, OID_AUTO, tunnelfib, CTLFLAG_RD, &tunnel_fib, 0, "");
133 #endif
134
135 /*
136  * handler for net.my_fibnum
137  */
138 static int
139 sysctl_my_fibnum(SYSCTL_HANDLER_ARGS)
140 {
141         int fibnum;
142         int error;
143  
144         fibnum = curthread->td_proc->p_fibnum;
145         error = sysctl_handle_int(oidp, &fibnum, 0, req);
146         return (error);
147 }
148
149 SYSCTL_PROC(_net, OID_AUTO, my_fibnum, CTLTYPE_INT|CTLFLAG_RD,
150             NULL, 0, &sysctl_my_fibnum, "I", "default FIB of caller");
151
152 static __inline struct radix_node_head **
153 rt_tables_get_rnh_ptr(int table, int fam)
154 {
155         struct radix_node_head **rnh;
156
157         KASSERT(table >= 0 && table < rt_numfibs, ("%s: table out of bounds.",
158             __func__));
159         KASSERT(fam >= 0 && fam < (AF_MAX+1), ("%s: fam out of bounds.",
160             __func__));
161
162         /* rnh is [fib=0][af=0]. */
163         rnh = (struct radix_node_head **)V_rt_tables;
164         /* Get the offset to the requested table and fam. */
165         rnh += table * (AF_MAX+1) + fam;
166
167         return (rnh);
168 }
169
170 struct radix_node_head *
171 rt_tables_get_rnh(int table, int fam)
172 {
173
174         return (*rt_tables_get_rnh_ptr(table, fam));
175 }
176
177 static void
178 route_init(void)
179 {
180
181         /* whack the tunable ints into  line. */
182         if (rt_numfibs > RT_MAXFIBS)
183                 rt_numfibs = RT_MAXFIBS;
184         if (rt_numfibs == 0)
185                 rt_numfibs = 1;
186         rn_init();      /* initialize all zeroes, all ones, mask table */
187
188 #ifdef VIMAGE
189         vnet_mod_register(&vnet_rtable_modinfo);
190 #else
191         vnet_route_iattach(NULL);
192 #endif
193 }
194
195 static int
196 vnet_route_iattach(const void *unused __unused)
197 {
198         struct domain *dom;
199         struct radix_node_head **rnh;
200         int table;
201         int fam;
202
203         V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) *
204             sizeof(struct radix_node_head *), M_RTABLE, M_WAITOK|M_ZERO);
205
206         V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), NULL, NULL,
207             NULL, NULL, UMA_ALIGN_PTR, 0);
208         for (dom = domains; dom; dom = dom->dom_next) {
209                 if (dom->dom_rtattach)  {
210                         for  (table = 0; table < rt_numfibs; table++) {
211                                 if ( (fam = dom->dom_family) == AF_INET ||
212                                     table == 0) {
213                                         /* for now only AF_INET has > 1 table */
214                                         /* XXX MRT 
215                                          * rtattach will be also called
216                                          * from vfs_export.c but the
217                                          * offset will be 0
218                                          * (only for AF_INET and AF_INET6
219                                          * which don't need it anyhow)
220                                          */
221                                         rnh = rt_tables_get_rnh_ptr(table, fam);
222                                         if (rnh == NULL)
223                                                 panic("%s: rnh NULL", __func__);
224                                         dom->dom_rtattach((void **)rnh,
225                                             dom->dom_rtoffset);
226                                 } else {
227                                         break;
228                                 }
229                         }
230                 }
231         }
232
233         return (0);
234 }
235
236 #ifdef VIMAGE
237 static int
238 vnet_route_idetach(const void *unused __unused)
239 {
240         int table;
241         int fam;
242         struct domain *dom;
243         struct radix_node_head **rnh;
244
245         for (dom = domains; dom; dom = dom->dom_next) {
246                 if (dom->dom_rtdetach) {
247                         for (table = 0; table < rt_numfibs; table++) {
248                                 if ( (fam = dom->dom_family) == AF_INET ||
249                                     table == 0) {
250                                         /* For now only AF_INET has > 1 tbl. */
251                                         rnh = rt_tables_get_rnh_ptr(table, fam);
252                                         if (rnh == NULL)
253                                                 panic("%s: rnh NULL", __func__);
254                                         dom->dom_rtdetach((void **)rnh,
255                                             dom->dom_rtoffset);
256                                 } else {
257                                         break;
258                                 }
259                         }
260                 }
261         }
262         return (0);
263 }
264 #endif
265
266 #ifndef _SYS_SYSPROTO_H_
267 struct setfib_args {
268         int     fibnum;
269 };
270 #endif
271 int
272 setfib(struct thread *td, struct setfib_args *uap)
273 {
274         if (uap->fibnum < 0 || uap->fibnum >= rt_numfibs)
275                 return EINVAL;
276         td->td_proc->p_fibnum = uap->fibnum;
277         return (0);
278 }
279
280 /*
281  * Packet routing routines.
282  */
283 void
284 rtalloc(struct route *ro)
285 {
286         rtalloc_ign_fib(ro, 0UL, 0);
287 }
288
289 void
290 rtalloc_fib(struct route *ro, u_int fibnum)
291 {
292         rtalloc_ign_fib(ro, 0UL, fibnum);
293 }
294
295 void
296 rtalloc_ign(struct route *ro, u_long ignore)
297 {
298         struct rtentry *rt;
299
300         if ((rt = ro->ro_rt) != NULL) {
301                 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
302                         return;
303                 RTFREE(rt);
304                 ro->ro_rt = NULL;
305         }
306         ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, 0);
307         if (ro->ro_rt)
308                 RT_UNLOCK(ro->ro_rt);
309 }
310
311 void
312 rtalloc_ign_fib(struct route *ro, u_long ignore, u_int fibnum)
313 {
314         struct rtentry *rt;
315
316         if ((rt = ro->ro_rt) != NULL) {
317                 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
318                         return;
319                 RTFREE(rt);
320                 ro->ro_rt = NULL;
321         }
322         ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, fibnum);
323         if (ro->ro_rt)
324                 RT_UNLOCK(ro->ro_rt);
325 }
326
327 /*
328  * Look up the route that matches the address given
329  * Or, at least try.. Create a cloned route if needed.
330  *
331  * The returned route, if any, is locked.
332  */
333 struct rtentry *
334 rtalloc1(struct sockaddr *dst, int report, u_long ignflags)
335 {
336         return (rtalloc1_fib(dst, report, ignflags, 0));
337 }
338
339 struct rtentry *
340 rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags,
341                     u_int fibnum)
342 {
343         struct radix_node_head *rnh;
344         struct rtentry *rt;
345         struct radix_node *rn;
346         struct rtentry *newrt;
347         struct rt_addrinfo info;
348         int err = 0, msgtype = RTM_MISS;
349         int needlock;
350
351         KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
352         if (dst->sa_family != AF_INET)  /* Only INET supports > 1 fib now */
353                 fibnum = 0;
354         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
355         newrt = NULL;
356         /*
357          * Look up the address in the table for that Address Family
358          */
359         if (rnh == NULL) {
360                 V_rtstat.rts_unreach++;
361                 goto miss;
362         }
363         needlock = !(ignflags & RTF_RNH_LOCKED);
364         if (needlock)
365                 RADIX_NODE_HEAD_RLOCK(rnh);
366 #ifdef INVARIANTS       
367         else
368                 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
369 #endif
370         rn = rnh->rnh_matchaddr(dst, rnh);
371         if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
372                 newrt = rt = RNTORT(rn);
373                 RT_LOCK(newrt);
374                 RT_ADDREF(newrt);
375                 if (needlock)
376                         RADIX_NODE_HEAD_RUNLOCK(rnh);
377                 goto done;
378
379         } else if (needlock)
380                 RADIX_NODE_HEAD_RUNLOCK(rnh);
381         
382         /*
383          * Either we hit the root or couldn't find any match,
384          * Which basically means
385          * "caint get there frm here"
386          */
387         V_rtstat.rts_unreach++;
388 miss:
389         if (report) {
390                 /*
391                  * If required, report the failure to the supervising
392                  * Authorities.
393                  * For a delete, this is not an error. (report == 0)
394                  */
395                 bzero(&info, sizeof(info));
396                 info.rti_info[RTAX_DST] = dst;
397                 rt_missmsg(msgtype, &info, 0, err);
398         }       
399 done:
400         if (newrt)
401                 RT_LOCK_ASSERT(newrt);
402         return (newrt);
403 }
404
405 /*
406  * Remove a reference count from an rtentry.
407  * If the count gets low enough, take it out of the routing table
408  */
409 void
410 rtfree(struct rtentry *rt)
411 {
412         struct radix_node_head *rnh;
413
414         KASSERT(rt != NULL,("%s: NULL rt", __func__));
415         rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
416         KASSERT(rnh != NULL,("%s: NULL rnh", __func__));
417
418         RT_LOCK_ASSERT(rt);
419
420         /*
421          * The callers should use RTFREE_LOCKED() or RTFREE(), so
422          * we should come here exactly with the last reference.
423          */
424         RT_REMREF(rt);
425         if (rt->rt_refcnt > 0) {
426                 log(LOG_DEBUG, "%s: %p has %d refs\n", __func__, rt, rt->rt_refcnt);
427                 goto done;
428         }
429
430         /*
431          * On last reference give the "close method" a chance
432          * to cleanup private state.  This also permits (for
433          * IPv4 and IPv6) a chance to decide if the routing table
434          * entry should be purged immediately or at a later time.
435          * When an immediate purge is to happen the close routine
436          * typically calls rtexpunge which clears the RTF_UP flag
437          * on the entry so that the code below reclaims the storage.
438          */
439         if (rt->rt_refcnt == 0 && rnh->rnh_close)
440                 rnh->rnh_close((struct radix_node *)rt, rnh);
441
442         /*
443          * If we are no longer "up" (and ref == 0)
444          * then we can free the resources associated
445          * with the route.
446          */
447         if ((rt->rt_flags & RTF_UP) == 0) {
448                 if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
449                         panic("rtfree 2");
450                 /*
451                  * the rtentry must have been removed from the routing table
452                  * so it is represented in rttrash.. remove that now.
453                  */
454                 V_rttrash--;
455 #ifdef  DIAGNOSTIC
456                 if (rt->rt_refcnt < 0) {
457                         printf("rtfree: %p not freed (neg refs)\n", rt);
458                         goto done;
459                 }
460 #endif
461                 /*
462                  * release references on items we hold them on..
463                  * e.g other routes and ifaddrs.
464                  */
465                 if (rt->rt_ifa)
466                         ifa_free(rt->rt_ifa);
467                 /*
468                  * The key is separatly alloc'd so free it (see rt_setgate()).
469                  * This also frees the gateway, as they are always malloc'd
470                  * together.
471                  */
472                 Free(rt_key(rt));
473
474                 /*
475                  * and the rtentry itself of course
476                  */
477                 RT_LOCK_DESTROY(rt);
478                 uma_zfree(V_rtzone, rt);
479                 return;
480         }
481 done:
482         RT_UNLOCK(rt);
483 }
484
485
486 /*
487  * Force a routing table entry to the specified
488  * destination to go through the given gateway.
489  * Normally called as a result of a routing redirect
490  * message from the network layer.
491  */
492 void
493 rtredirect(struct sockaddr *dst,
494         struct sockaddr *gateway,
495         struct sockaddr *netmask,
496         int flags,
497         struct sockaddr *src)
498 {
499         rtredirect_fib(dst, gateway, netmask, flags, src, 0);
500 }
501
502 void
503 rtredirect_fib(struct sockaddr *dst,
504         struct sockaddr *gateway,
505         struct sockaddr *netmask,
506         int flags,
507         struct sockaddr *src,
508         u_int fibnum)
509 {
510         struct rtentry *rt, *rt0 = NULL;
511         int error = 0;
512         short *stat = NULL;
513         struct rt_addrinfo info;
514         struct ifaddr *ifa;
515         struct radix_node_head *rnh;
516
517         ifa = NULL;
518         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
519         if (rnh == NULL) {
520                 error = EAFNOSUPPORT;
521                 goto out;
522         }
523
524         /* verify the gateway is directly reachable */
525         if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
526                 error = ENETUNREACH;
527                 goto out;
528         }
529         rt = rtalloc1_fib(dst, 0, 0UL, fibnum); /* NB: rt is locked */
530         /*
531          * If the redirect isn't from our current router for this dst,
532          * it's either old or wrong.  If it redirects us to ourselves,
533          * we have a routing loop, perhaps as a result of an interface
534          * going down recently.
535          */
536         if (!(flags & RTF_DONE) && rt &&
537              (!sa_equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
538                 error = EINVAL;
539         else if (ifa_ifwithaddr_check(gateway))
540                 error = EHOSTUNREACH;
541         if (error)
542                 goto done;
543         /*
544          * Create a new entry if we just got back a wildcard entry
545          * or the the lookup failed.  This is necessary for hosts
546          * which use routing redirects generated by smart gateways
547          * to dynamically build the routing tables.
548          */
549         if (rt == NULL || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
550                 goto create;
551         /*
552          * Don't listen to the redirect if it's
553          * for a route to an interface.
554          */
555         if (rt->rt_flags & RTF_GATEWAY) {
556                 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
557                         /*
558                          * Changing from route to net => route to host.
559                          * Create new route, rather than smashing route to net.
560                          */
561                 create:
562                         rt0 = rt;
563                         rt = NULL;
564                 
565                         flags |=  RTF_GATEWAY | RTF_DYNAMIC;
566                         bzero((caddr_t)&info, sizeof(info));
567                         info.rti_info[RTAX_DST] = dst;
568                         info.rti_info[RTAX_GATEWAY] = gateway;
569                         info.rti_info[RTAX_NETMASK] = netmask;
570                         info.rti_ifa = ifa;
571                         info.rti_flags = flags;
572                         if (rt0 != NULL)
573                                 RT_UNLOCK(rt0); /* drop lock to avoid LOR with RNH */
574                         error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
575                         if (rt != NULL) {
576                                 RT_LOCK(rt);
577                                 if (rt0 != NULL)
578                                         EVENTHANDLER_INVOKE(route_redirect_event, rt0, rt, dst);
579                                 flags = rt->rt_flags;
580                         }
581                         if (rt0 != NULL)
582                                 RTFREE(rt0);
583                         
584                         stat = &V_rtstat.rts_dynamic;
585                 } else {
586                         struct rtentry *gwrt;
587
588                         /*
589                          * Smash the current notion of the gateway to
590                          * this destination.  Should check about netmask!!!
591                          */
592                         rt->rt_flags |= RTF_MODIFIED;
593                         flags |= RTF_MODIFIED;
594                         stat = &V_rtstat.rts_newgateway;
595                         /*
596                          * add the key and gateway (in one malloc'd chunk).
597                          */
598                         RT_UNLOCK(rt);
599                         RADIX_NODE_HEAD_LOCK(rnh);
600                         RT_LOCK(rt);
601                         rt_setgate(rt, rt_key(rt), gateway);
602                         gwrt = rtalloc1(gateway, 1, RTF_RNH_LOCKED);
603                         RADIX_NODE_HEAD_UNLOCK(rnh);
604                         EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst);
605                         RTFREE_LOCKED(gwrt);
606                 }
607         } else
608                 error = EHOSTUNREACH;
609 done:
610         if (rt)
611                 RTFREE_LOCKED(rt);
612 out:
613         if (error)
614                 V_rtstat.rts_badredirect++;
615         else if (stat != NULL)
616                 (*stat)++;
617         bzero((caddr_t)&info, sizeof(info));
618         info.rti_info[RTAX_DST] = dst;
619         info.rti_info[RTAX_GATEWAY] = gateway;
620         info.rti_info[RTAX_NETMASK] = netmask;
621         info.rti_info[RTAX_AUTHOR] = src;
622         rt_missmsg(RTM_REDIRECT, &info, flags, error);
623         if (ifa != NULL)
624                 ifa_free(ifa);
625 }
626
627 int
628 rtioctl(u_long req, caddr_t data)
629 {
630         return (rtioctl_fib(req, data, 0));
631 }
632
633 /*
634  * Routing table ioctl interface.
635  */
636 int
637 rtioctl_fib(u_long req, caddr_t data, u_int fibnum)
638 {
639
640         /*
641          * If more ioctl commands are added here, make sure the proper
642          * super-user checks are being performed because it is possible for
643          * prison-root to make it this far if raw sockets have been enabled
644          * in jails.
645          */
646 #ifdef INET
647         /* Multicast goop, grrr... */
648         return mrt_ioctl ? mrt_ioctl(req, data, fibnum) : EOPNOTSUPP;
649 #else /* INET */
650         return ENXIO;
651 #endif /* INET */
652 }
653
654 /*
655  * For both ifa_ifwithroute() routines, 'ifa' is returned referenced.
656  */
657 struct ifaddr *
658 ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway)
659 {
660         return (ifa_ifwithroute_fib(flags, dst, gateway, 0));
661 }
662
663 struct ifaddr *
664 ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway,
665                                 u_int fibnum)
666 {
667         register struct ifaddr *ifa;
668         int not_found = 0;
669
670         if ((flags & RTF_GATEWAY) == 0) {
671                 /*
672                  * If we are adding a route to an interface,
673                  * and the interface is a pt to pt link
674                  * we should search for the destination
675                  * as our clue to the interface.  Otherwise
676                  * we can use the local address.
677                  */
678                 ifa = NULL;
679                 if (flags & RTF_HOST)
680                         ifa = ifa_ifwithdstaddr(dst);
681                 if (ifa == NULL)
682                         ifa = ifa_ifwithaddr(gateway);
683         } else {
684                 /*
685                  * If we are adding a route to a remote net
686                  * or host, the gateway may still be on the
687                  * other end of a pt to pt link.
688                  */
689                 ifa = ifa_ifwithdstaddr(gateway);
690         }
691         if (ifa == NULL)
692                 ifa = ifa_ifwithnet(gateway);
693         if (ifa == NULL) {
694                 struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum);
695                 if (rt == NULL)
696                         return (NULL);
697                 /*
698                  * dismiss a gateway that is reachable only
699                  * through the default router
700                  */
701                 switch (gateway->sa_family) {
702                 case AF_INET:
703                         if (satosin(rt_key(rt))->sin_addr.s_addr == INADDR_ANY)
704                                 not_found = 1;
705                         break;
706                 case AF_INET6:
707                         if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(rt))->sin6_addr))
708                                 not_found = 1;
709                         break;
710                 default:
711                         break;
712                 }
713                 if (!not_found && rt->rt_ifa != NULL) {
714                         ifa = rt->rt_ifa;
715                         ifa_ref(ifa);
716                 }
717                 RT_REMREF(rt);
718                 RT_UNLOCK(rt);
719                 if (not_found || ifa == NULL)
720                         return (NULL);
721         }
722         if (ifa->ifa_addr->sa_family != dst->sa_family) {
723                 struct ifaddr *oifa = ifa;
724                 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
725                 if (ifa == NULL)
726                         ifa = oifa;
727                 else
728                         ifa_free(oifa);
729         }
730         return (ifa);
731 }
732
733 /*
734  * Do appropriate manipulations of a routing tree given
735  * all the bits of info needed
736  */
737 int
738 rtrequest(int req,
739         struct sockaddr *dst,
740         struct sockaddr *gateway,
741         struct sockaddr *netmask,
742         int flags,
743         struct rtentry **ret_nrt)
744 {
745         return (rtrequest_fib(req, dst, gateway, netmask, flags, ret_nrt, 0));
746 }
747
748 int
749 rtrequest_fib(int req,
750         struct sockaddr *dst,
751         struct sockaddr *gateway,
752         struct sockaddr *netmask,
753         int flags,
754         struct rtentry **ret_nrt,
755         u_int fibnum)
756 {
757         struct rt_addrinfo info;
758
759         if (dst->sa_len == 0)
760                 return(EINVAL);
761
762         bzero((caddr_t)&info, sizeof(info));
763         info.rti_flags = flags;
764         info.rti_info[RTAX_DST] = dst;
765         info.rti_info[RTAX_GATEWAY] = gateway;
766         info.rti_info[RTAX_NETMASK] = netmask;
767         return rtrequest1_fib(req, &info, ret_nrt, fibnum);
768 }
769
770 /*
771  * These (questionable) definitions of apparent local variables apply
772  * to the next two functions.  XXXXXX!!!
773  */
774 #define dst     info->rti_info[RTAX_DST]
775 #define gateway info->rti_info[RTAX_GATEWAY]
776 #define netmask info->rti_info[RTAX_NETMASK]
777 #define ifaaddr info->rti_info[RTAX_IFA]
778 #define ifpaddr info->rti_info[RTAX_IFP]
779 #define flags   info->rti_flags
780
781 int
782 rt_getifa(struct rt_addrinfo *info)
783 {
784         return (rt_getifa_fib(info, 0));
785 }
786
787 /*
788  * Look up rt_addrinfo for a specific fib.  Note that if rti_ifa is defined,
789  * it will be referenced so the caller must free it.
790  */
791 int
792 rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
793 {
794         struct ifaddr *ifa;
795         int error = 0;
796
797         /*
798          * ifp may be specified by sockaddr_dl
799          * when protocol address is ambiguous.
800          */
801         if (info->rti_ifp == NULL && ifpaddr != NULL &&
802             ifpaddr->sa_family == AF_LINK &&
803             (ifa = ifa_ifwithnet(ifpaddr)) != NULL) {
804                 info->rti_ifp = ifa->ifa_ifp;
805                 ifa_free(ifa);
806         }
807         if (info->rti_ifa == NULL && ifaaddr != NULL)
808                 info->rti_ifa = ifa_ifwithaddr(ifaaddr);
809         if (info->rti_ifa == NULL) {
810                 struct sockaddr *sa;
811
812                 sa = ifaaddr != NULL ? ifaaddr :
813                     (gateway != NULL ? gateway : dst);
814                 if (sa != NULL && info->rti_ifp != NULL)
815                         info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp);
816                 else if (dst != NULL && gateway != NULL)
817                         info->rti_ifa = ifa_ifwithroute_fib(flags, dst, gateway,
818                                                         fibnum);
819                 else if (sa != NULL)
820                         info->rti_ifa = ifa_ifwithroute_fib(flags, sa, sa,
821                                                         fibnum);
822         }
823         if ((ifa = info->rti_ifa) != NULL) {
824                 if (info->rti_ifp == NULL)
825                         info->rti_ifp = ifa->ifa_ifp;
826         } else
827                 error = ENETUNREACH;
828         return (error);
829 }
830
831 /*
832  * Expunges references to a route that's about to be reclaimed.
833  * The route must be locked.
834  */
835 int
836 rtexpunge(struct rtentry *rt)
837 {
838         struct radix_node *rn;
839         struct radix_node_head *rnh;
840         struct ifaddr *ifa;
841         int error = 0;
842
843         /*
844          * Find the correct routing tree to use for this Address Family
845          */
846         rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
847         RT_LOCK_ASSERT(rt);
848         if (rnh == NULL)
849                 return (EAFNOSUPPORT);
850         RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
851 #if 0
852         /*
853          * We cannot assume anything about the reference count
854          * because protocols call us in many situations; often
855          * before unwinding references to the table entry.
856          */
857         KASSERT(rt->rt_refcnt <= 1, ("bogus refcnt %ld", rt->rt_refcnt));
858 #endif
859         /*
860          * Remove the item from the tree; it should be there,
861          * but when callers invoke us blindly it may not (sigh).
862          */
863         rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), rnh);
864         if (rn == NULL) {
865                 error = ESRCH;
866                 goto bad;
867         }
868         KASSERT((rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) == 0,
869                 ("unexpected flags 0x%x", rn->rn_flags));
870         KASSERT(rt == RNTORT(rn),
871                 ("lookup mismatch, rt %p rn %p", rt, rn));
872
873         rt->rt_flags &= ~RTF_UP;
874
875         /*
876          * Give the protocol a chance to keep things in sync.
877          */
878         if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) {
879                 struct rt_addrinfo info;
880
881                 bzero((caddr_t)&info, sizeof(info));
882                 info.rti_flags = rt->rt_flags;
883                 info.rti_info[RTAX_DST] = rt_key(rt);
884                 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
885                 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
886                 ifa->ifa_rtrequest(RTM_DELETE, rt, &info);
887         }
888
889         /*
890          * one more rtentry floating around that is not
891          * linked to the routing table.
892          */
893         V_rttrash++;
894 bad:
895         return (error);
896 }
897
898 #ifdef RADIX_MPATH
899 static int
900 rn_mpath_update(int req, struct rt_addrinfo *info,
901     struct radix_node_head *rnh, struct rtentry **ret_nrt)
902 {
903         /*
904          * if we got multipath routes, we require users to specify
905          * a matching RTAX_GATEWAY.
906          */
907         struct rtentry *rt, *rto = NULL;
908         register struct radix_node *rn;
909         int error = 0;
910
911         rn = rnh->rnh_matchaddr(dst, rnh);
912         if (rn == NULL)
913                 return (ESRCH);
914         rto = rt = RNTORT(rn);
915         rt = rt_mpath_matchgate(rt, gateway);
916         if (rt == NULL)
917                 return (ESRCH);
918         /*
919          * this is the first entry in the chain
920          */
921         if (rto == rt) {
922                 rn = rn_mpath_next((struct radix_node *)rt);
923                 /*
924                  * there is another entry, now it's active
925                  */
926                 if (rn) {
927                         rto = RNTORT(rn);
928                         RT_LOCK(rto);
929                         rto->rt_flags |= RTF_UP;
930                         RT_UNLOCK(rto);
931                 } else if (rt->rt_flags & RTF_GATEWAY) {
932                         /*
933                          * For gateway routes, we need to 
934                          * make sure that we we are deleting
935                          * the correct gateway. 
936                          * rt_mpath_matchgate() does not 
937                          * check the case when there is only
938                          * one route in the chain.  
939                          */
940                         if (gateway &&
941                             (rt->rt_gateway->sa_len != gateway->sa_len ||
942                                 memcmp(rt->rt_gateway, gateway, gateway->sa_len)))
943                                 error = ESRCH;
944                         else {
945                                 /*
946                                  * remove from tree before returning it
947                                  * to the caller
948                                  */
949                                 rn = rnh->rnh_deladdr(dst, netmask, rnh);
950                                 KASSERT(rt == RNTORT(rn), ("radix node disappeared"));
951                                 goto gwdelete;
952                         }
953                         
954                 }
955                 /*
956                  * use the normal delete code to remove
957                  * the first entry
958                  */
959                 if (req != RTM_DELETE) 
960                         goto nondelete;
961
962                 error = ENOENT;
963                 goto done;
964         }
965                 
966         /*
967          * if the entry is 2nd and on up
968          */
969         if ((req == RTM_DELETE) && !rt_mpath_deldup(rto, rt))
970                 panic ("rtrequest1: rt_mpath_deldup");
971 gwdelete:
972         RT_LOCK(rt);
973         RT_ADDREF(rt);
974         if (req == RTM_DELETE) {
975                 rt->rt_flags &= ~RTF_UP;
976                 /*
977                  * One more rtentry floating around that is not
978                  * linked to the routing table. rttrash will be decremented
979                  * when RTFREE(rt) is eventually called.
980                  */
981                 V_rttrash++;
982         }
983         
984 nondelete:
985         if (req != RTM_DELETE)
986                 panic("unrecognized request %d", req);
987         
988
989         /*
990          * If the caller wants it, then it can have it,
991          * but it's up to it to free the rtentry as we won't be
992          * doing it.
993          */
994         if (ret_nrt) {
995                 *ret_nrt = rt;
996                 RT_UNLOCK(rt);
997         } else
998                 RTFREE_LOCKED(rt);
999 done:
1000         return (error);
1001 }
1002 #endif
1003
1004 int
1005 rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
1006                                 u_int fibnum)
1007 {
1008         int error = 0, needlock = 0;
1009         register struct rtentry *rt;
1010         register struct radix_node *rn;
1011         register struct radix_node_head *rnh;
1012         struct ifaddr *ifa;
1013         struct sockaddr *ndst;
1014 #define senderr(x) { error = x ; goto bad; }
1015
1016         KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
1017         if (dst->sa_family != AF_INET)  /* Only INET supports > 1 fib now */
1018                 fibnum = 0;
1019         /*
1020          * Find the correct routing tree to use for this Address Family
1021          */
1022         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
1023         if (rnh == NULL)
1024                 return (EAFNOSUPPORT);
1025         needlock = ((flags & RTF_RNH_LOCKED) == 0);
1026         flags &= ~RTF_RNH_LOCKED;
1027         if (needlock)
1028                 RADIX_NODE_HEAD_LOCK(rnh);
1029         else
1030                 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
1031         /*
1032          * If we are adding a host route then we don't want to put
1033          * a netmask in the tree, nor do we want to clone it.
1034          */
1035         if (flags & RTF_HOST)
1036                 netmask = NULL;
1037
1038         switch (req) {
1039         case RTM_DELETE:
1040 #ifdef RADIX_MPATH
1041                 if (rn_mpath_capable(rnh)) {
1042                         error = rn_mpath_update(req, info, rnh, ret_nrt);
1043                         /*
1044                          * "bad" holds true for the success case
1045                          * as well
1046                          */
1047                         if (error != ENOENT)
1048                                 goto bad;
1049                 }
1050 #endif
1051                 /*
1052                  * Remove the item from the tree and return it.
1053                  * Complain if it is not there and do no more processing.
1054                  */
1055                 rn = rnh->rnh_deladdr(dst, netmask, rnh);
1056                 if (rn == NULL)
1057                         senderr(ESRCH);
1058                 if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
1059                         panic ("rtrequest delete");
1060                 rt = RNTORT(rn);
1061                 RT_LOCK(rt);
1062                 RT_ADDREF(rt);
1063                 rt->rt_flags &= ~RTF_UP;
1064
1065                 /*
1066                  * give the protocol a chance to keep things in sync.
1067                  */
1068                 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
1069                         ifa->ifa_rtrequest(RTM_DELETE, rt, info);
1070
1071                 /*
1072                  * One more rtentry floating around that is not
1073                  * linked to the routing table. rttrash will be decremented
1074                  * when RTFREE(rt) is eventually called.
1075                  */
1076                 V_rttrash++;
1077
1078                 /*
1079                  * If the caller wants it, then it can have it,
1080                  * but it's up to it to free the rtentry as we won't be
1081                  * doing it.
1082                  */
1083                 if (ret_nrt) {
1084                         *ret_nrt = rt;
1085                         RT_UNLOCK(rt);
1086                 } else
1087                         RTFREE_LOCKED(rt);
1088                 break;
1089         case RTM_RESOLVE:
1090                 /*
1091                  * resolve was only used for route cloning
1092                  * here for compat
1093                  */
1094                 break;
1095         case RTM_ADD:
1096                 if ((flags & RTF_GATEWAY) && !gateway)
1097                         senderr(EINVAL);
1098                 if (dst && gateway && (dst->sa_family != gateway->sa_family) && 
1099                     (gateway->sa_family != AF_UNSPEC) && (gateway->sa_family != AF_LINK))
1100                         senderr(EINVAL);
1101
1102                 if (info->rti_ifa == NULL) {
1103                         error = rt_getifa_fib(info, fibnum);
1104                         if (error)
1105                                 senderr(error);
1106                 } else
1107                         ifa_ref(info->rti_ifa);
1108                 ifa = info->rti_ifa;
1109                 rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO);
1110                 if (rt == NULL) {
1111                         if (ifa != NULL)
1112                                 ifa_free(ifa);
1113                         senderr(ENOBUFS);
1114                 }
1115                 RT_LOCK_INIT(rt);
1116                 rt->rt_flags = RTF_UP | flags;
1117                 rt->rt_fibnum = fibnum;
1118                 /*
1119                  * Add the gateway. Possibly re-malloc-ing the storage for it
1120                  * 
1121                  */
1122                 RT_LOCK(rt);
1123                 if ((error = rt_setgate(rt, dst, gateway)) != 0) {
1124                         RT_LOCK_DESTROY(rt);
1125                         if (ifa != NULL)
1126                                 ifa_free(ifa);
1127                         uma_zfree(V_rtzone, rt);
1128                         senderr(error);
1129                 }
1130
1131                 /*
1132                  * point to the (possibly newly malloc'd) dest address.
1133                  */
1134                 ndst = (struct sockaddr *)rt_key(rt);
1135
1136                 /*
1137                  * make sure it contains the value we want (masked if needed).
1138                  */
1139                 if (netmask) {
1140                         rt_maskedcopy(dst, ndst, netmask);
1141                 } else
1142                         bcopy(dst, ndst, dst->sa_len);
1143
1144                 /*
1145                  * We use the ifa reference returned by rt_getifa_fib().
1146                  * This moved from below so that rnh->rnh_addaddr() can
1147                  * examine the ifa and  ifa->ifa_ifp if it so desires.
1148                  */
1149                 rt->rt_ifa = ifa;
1150                 rt->rt_ifp = ifa->ifa_ifp;
1151                 rt->rt_rmx.rmx_weight = 1;
1152
1153 #ifdef RADIX_MPATH
1154                 /* do not permit exactly the same dst/mask/gw pair */
1155                 if (rn_mpath_capable(rnh) &&
1156                         rt_mpath_conflict(rnh, rt, netmask)) {
1157                         if (rt->rt_ifa) {
1158                                 ifa_free(rt->rt_ifa);
1159                         }
1160                         Free(rt_key(rt));
1161                         RT_LOCK_DESTROY(rt);
1162                         uma_zfree(V_rtzone, rt);
1163                         senderr(EEXIST);
1164                 }
1165 #endif
1166
1167                 /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
1168                 rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
1169                 /*
1170                  * If it still failed to go into the tree,
1171                  * then un-make it (this should be a function)
1172                  */
1173                 if (rn == NULL) {
1174                         if (rt->rt_ifa)
1175                                 ifa_free(rt->rt_ifa);
1176                         Free(rt_key(rt));
1177                         RT_LOCK_DESTROY(rt);
1178                         uma_zfree(V_rtzone, rt);
1179                         senderr(EEXIST);
1180                 }
1181
1182                 /*
1183                  * If this protocol has something to add to this then
1184                  * allow it to do that as well.
1185                  */
1186                 if (ifa->ifa_rtrequest)
1187                         ifa->ifa_rtrequest(req, rt, info);
1188
1189                 /*
1190                  * actually return a resultant rtentry and
1191                  * give the caller a single reference.
1192                  */
1193                 if (ret_nrt) {
1194                         *ret_nrt = rt;
1195                         RT_ADDREF(rt);
1196                 }
1197                 RT_UNLOCK(rt);
1198                 break;
1199         default:
1200                 error = EOPNOTSUPP;
1201         }
1202 bad:
1203         if (needlock)
1204                 RADIX_NODE_HEAD_UNLOCK(rnh);
1205         return (error);
1206 #undef senderr
1207 }
1208
1209 #undef dst
1210 #undef gateway
1211 #undef netmask
1212 #undef ifaaddr
1213 #undef ifpaddr
1214 #undef flags
1215
1216 int
1217 rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
1218 {
1219         /* XXX dst may be overwritten, can we move this to below */
1220         int dlen = SA_SIZE(dst), glen = SA_SIZE(gate);
1221 #ifdef INVARIANTS
1222         struct radix_node_head *rnh;
1223
1224         rnh = rt_tables_get_rnh(rt->rt_fibnum, dst->sa_family);
1225 #endif
1226
1227         RT_LOCK_ASSERT(rt);
1228         RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
1229         
1230         /*
1231          * Prepare to store the gateway in rt->rt_gateway.
1232          * Both dst and gateway are stored one after the other in the same
1233          * malloc'd chunk. If we have room, we can reuse the old buffer,
1234          * rt_gateway already points to the right place.
1235          * Otherwise, malloc a new block and update the 'dst' address.
1236          */
1237         if (rt->rt_gateway == NULL || glen > SA_SIZE(rt->rt_gateway)) {
1238                 caddr_t new;
1239
1240                 R_Malloc(new, caddr_t, dlen + glen);
1241                 if (new == NULL)
1242                         return ENOBUFS;
1243                 /*
1244                  * XXX note, we copy from *dst and not *rt_key(rt) because
1245                  * rt_setgate() can be called to initialize a newly
1246                  * allocated route entry, in which case rt_key(rt) == NULL
1247                  * (and also rt->rt_gateway == NULL).
1248                  * Free()/free() handle a NULL argument just fine.
1249                  */
1250                 bcopy(dst, new, dlen);
1251                 Free(rt_key(rt));       /* free old block, if any */
1252                 rt_key(rt) = (struct sockaddr *)new;
1253                 rt->rt_gateway = (struct sockaddr *)(new + dlen);
1254         }
1255
1256         /*
1257          * Copy the new gateway value into the memory chunk.
1258          */
1259         bcopy(gate, rt->rt_gateway, glen);
1260
1261         return (0);
1262 }
1263
1264 static void
1265 rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
1266 {
1267         register u_char *cp1 = (u_char *)src;
1268         register u_char *cp2 = (u_char *)dst;
1269         register u_char *cp3 = (u_char *)netmask;
1270         u_char *cplim = cp2 + *cp3;
1271         u_char *cplim2 = cp2 + *cp1;
1272
1273         *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */
1274         cp3 += 2;
1275         if (cplim > cplim2)
1276                 cplim = cplim2;
1277         while (cp2 < cplim)
1278                 *cp2++ = *cp1++ & *cp3++;
1279         if (cp2 < cplim2)
1280                 bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
1281 }
1282
1283 /*
1284  * Set up a routing table entry, normally
1285  * for an interface.
1286  */
1287 #define _SOCKADDR_TMPSIZE 128 /* Not too big.. kernel stack size is limited */
1288 static inline  int
1289 rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
1290 {
1291         struct sockaddr *dst;
1292         struct sockaddr *netmask;
1293         struct rtentry *rt = NULL;
1294         struct rt_addrinfo info;
1295         int error = 0;
1296         int startfib, endfib;
1297         char tempbuf[_SOCKADDR_TMPSIZE];
1298         int didwork = 0;
1299         int a_failure = 0;
1300         static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1301
1302         if (flags & RTF_HOST) {
1303                 dst = ifa->ifa_dstaddr;
1304                 netmask = NULL;
1305         } else {
1306                 dst = ifa->ifa_addr;
1307                 netmask = ifa->ifa_netmask;
1308         }
1309         if ( dst->sa_family != AF_INET)
1310                 fibnum = 0;
1311         if (fibnum == -1) {
1312                 if (rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) {
1313                         startfib = endfib = curthread->td_proc->p_fibnum;
1314                 } else {
1315                         startfib = 0;
1316                         endfib = rt_numfibs - 1;
1317                 }
1318         } else {
1319                 KASSERT((fibnum < rt_numfibs), ("rtinit1: bad fibnum"));
1320                 startfib = fibnum;
1321                 endfib = fibnum;
1322         }
1323         if (dst->sa_len == 0)
1324                 return(EINVAL);
1325
1326         /*
1327          * If it's a delete, check that if it exists,
1328          * it's on the correct interface or we might scrub
1329          * a route to another ifa which would
1330          * be confusing at best and possibly worse.
1331          */
1332         if (cmd == RTM_DELETE) {
1333                 /*
1334                  * It's a delete, so it should already exist..
1335                  * If it's a net, mask off the host bits
1336                  * (Assuming we have a mask)
1337                  * XXX this is kinda inet specific..
1338                  */
1339                 if (netmask != NULL) {
1340                         rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask);
1341                         dst = (struct sockaddr *)tempbuf;
1342                 }
1343         }
1344         /*
1345          * Now go through all the requested tables (fibs) and do the
1346          * requested action. Realistically, this will either be fib 0
1347          * for protocols that don't do multiple tables or all the
1348          * tables for those that do. XXX For this version only AF_INET.
1349          * When that changes code should be refactored to protocol
1350          * independent parts and protocol dependent parts.
1351          */
1352         for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
1353                 if (cmd == RTM_DELETE) {
1354                         struct radix_node_head *rnh;
1355                         struct radix_node *rn;
1356                         /*
1357                          * Look up an rtentry that is in the routing tree and
1358                          * contains the correct info.
1359                          */
1360                         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
1361                         if (rnh == NULL)
1362                                 /* this table doesn't exist but others might */
1363                                 continue;
1364                         RADIX_NODE_HEAD_LOCK(rnh);
1365 #ifdef RADIX_MPATH
1366                         if (rn_mpath_capable(rnh)) {
1367
1368                                 rn = rnh->rnh_matchaddr(dst, rnh);
1369                                 if (rn == NULL) 
1370                                         error = ESRCH;
1371                                 else {
1372                                         rt = RNTORT(rn);
1373                                         /*
1374                                          * for interface route the
1375                                          * rt->rt_gateway is sockaddr_intf
1376                                          * for cloning ARP entries, so
1377                                          * rt_mpath_matchgate must use the
1378                                          * interface address
1379                                          */
1380                                         rt = rt_mpath_matchgate(rt,
1381                                             ifa->ifa_addr);
1382                                         if (!rt) 
1383                                                 error = ESRCH;
1384                                 }
1385                         }
1386                         else
1387 #endif
1388                         rn = rnh->rnh_lookup(dst, netmask, rnh);
1389                         error = (rn == NULL ||
1390                             (rn->rn_flags & RNF_ROOT) ||
1391                             RNTORT(rn)->rt_ifa != ifa ||
1392                             !sa_equal((struct sockaddr *)rn->rn_key, dst));
1393                         RADIX_NODE_HEAD_UNLOCK(rnh);
1394                         if (error) {
1395                                 /* this is only an error if bad on ALL tables */
1396                                 continue;
1397                         }
1398                 }
1399                 /*
1400                  * Do the actual request
1401                  */
1402                 bzero((caddr_t)&info, sizeof(info));
1403                 info.rti_ifa = ifa;
1404                 info.rti_flags = flags | ifa->ifa_flags;
1405                 info.rti_info[RTAX_DST] = dst;
1406                 /* 
1407                  * doing this for compatibility reasons
1408                  */
1409                 if (cmd == RTM_ADD)
1410                         info.rti_info[RTAX_GATEWAY] =
1411                             (struct sockaddr *)&null_sdl;
1412                 else
1413                         info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
1414                 info.rti_info[RTAX_NETMASK] = netmask;
1415                 error = rtrequest1_fib(cmd, &info, &rt, fibnum);
1416                 if (error == 0 && rt != NULL) {
1417                         /*
1418                          * notify any listening routing agents of the change
1419                          */
1420                         RT_LOCK(rt);
1421 #ifdef RADIX_MPATH
1422                         /*
1423                          * in case address alias finds the first address
1424                          * e.g. ifconfig bge0 192.103.54.246/24
1425                          * e.g. ifconfig bge0 192.103.54.247/24
1426                          * the address set in the route is 192.103.54.246
1427                          * so we need to replace it with 192.103.54.247
1428                          */
1429                         if (memcmp(rt->rt_ifa->ifa_addr,
1430                             ifa->ifa_addr, ifa->ifa_addr->sa_len)) {
1431                                 ifa_free(rt->rt_ifa);
1432                                 ifa_ref(ifa);
1433                                 rt->rt_ifp = ifa->ifa_ifp;
1434                                 rt->rt_ifa = ifa;
1435                         }
1436 #endif
1437                         /* 
1438                          * doing this for compatibility reasons
1439                          */
1440                         if (cmd == RTM_ADD) {
1441                             ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
1442                                 rt->rt_ifp->if_type;
1443                             ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
1444                                 rt->rt_ifp->if_index;
1445                         }
1446                         rt_newaddrmsg(cmd, ifa, error, rt);
1447                         if (cmd == RTM_DELETE) {
1448                                 /*
1449                                  * If we are deleting, and we found an entry,
1450                                  * then it's been removed from the tree..
1451                                  * now throw it away.
1452                                  */
1453                                 RTFREE_LOCKED(rt);
1454                         } else {
1455                                 if (cmd == RTM_ADD) {
1456                                         /*
1457                                          * We just wanted to add it..
1458                                          * we don't actually need a reference.
1459                                          */
1460                                         RT_REMREF(rt);
1461                                 }
1462                                 RT_UNLOCK(rt);
1463                         }
1464                         didwork = 1;
1465                 }
1466                 if (error)
1467                         a_failure = error;
1468         }
1469         if (cmd == RTM_DELETE) {
1470                 if (didwork) {
1471                         error = 0;
1472                 } else {
1473                         /* we only give an error if it wasn't in any table */
1474                         error = ((flags & RTF_HOST) ?
1475                             EHOSTUNREACH : ENETUNREACH);
1476                 }
1477         } else {
1478                 if (a_failure) {
1479                         /* return an error if any of them failed */
1480                         error = a_failure;
1481                 }
1482         }
1483         return (error);
1484 }
1485
1486 /* special one for inet internal use. may not use. */
1487 int
1488 rtinit_fib(struct ifaddr *ifa, int cmd, int flags)
1489 {
1490         return (rtinit1(ifa, cmd, flags, -1));
1491 }
1492
1493 /*
1494  * Set up a routing table entry, normally
1495  * for an interface.
1496  */
1497 int
1498 rtinit(struct ifaddr *ifa, int cmd, int flags)
1499 {
1500         struct sockaddr *dst;
1501         int fib = 0;
1502
1503         if (flags & RTF_HOST) {
1504                 dst = ifa->ifa_dstaddr;
1505         } else {
1506                 dst = ifa->ifa_addr;
1507         }
1508
1509         if (dst->sa_family == AF_INET)
1510                 fib = -1;
1511         return (rtinit1(ifa, cmd, flags, fib));
1512 }
1513
1514 /* This must be before ip6_init2(), which is now SI_ORDER_MIDDLE */
1515 SYSINIT(route, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);