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