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