]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/route.c
Partially merge r274887,r275334,r275577,r275578,r275586 to minimize
[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_inet6.h"
39 #include "opt_route.h"
40 #include "opt_sctp.h"
41 #include "opt_mrouting.h"
42 #include "opt_mpath.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.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_var.h>
58 #include <net/if_dl.h>
59 #include <net/route.h>
60 #include <net/vnet.h>
61 #include <net/flowtable.h>
62
63 #ifdef RADIX_MPATH
64 #include <net/radix_mpath.h>
65 #endif
66
67 #include <netinet/in.h>
68 #include <netinet/ip_mroute.h>
69
70 #include <vm/uma.h>
71
72 #define RT_MAXFIBS      UINT16_MAX
73
74 /* Kernel config default option. */
75 #ifdef ROUTETABLES
76 #if ROUTETABLES <= 0
77 #error "ROUTETABLES defined too low"
78 #endif
79 #if ROUTETABLES > RT_MAXFIBS
80 #error "ROUTETABLES defined too big"
81 #endif
82 #define RT_NUMFIBS      ROUTETABLES
83 #endif /* ROUTETABLES */
84 /* Initialize to default if not otherwise set. */
85 #ifndef RT_NUMFIBS
86 #define RT_NUMFIBS      1
87 #endif
88
89 #if defined(INET) || defined(INET6)
90 #ifdef SCTP
91 extern void sctp_addr_change(struct ifaddr *ifa, int cmd);
92 #endif /* SCTP */
93 #endif
94
95
96 /* This is read-only.. */
97 u_int rt_numfibs = RT_NUMFIBS;
98 SYSCTL_UINT(_net, OID_AUTO, fibs, CTLFLAG_RDTUN, &rt_numfibs, 0, "");
99
100 /*
101  * By default add routes to all fibs for new interfaces.
102  * Once this is set to 0 then only allocate routes on interface
103  * changes for the FIB of the caller when adding a new set of addresses
104  * to an interface.  XXX this is a shotgun aproach to a problem that needs
105  * a more fine grained solution.. that will come.
106  * XXX also has the problems getting the FIB from curthread which will not
107  * always work given the fib can be overridden and prefixes can be added
108  * from the network stack context.
109  */
110 VNET_DEFINE(u_int, rt_add_addr_allfibs) = 1;
111 SYSCTL_UINT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RWTUN | CTLFLAG_VNET,
112     &VNET_NAME(rt_add_addr_allfibs), 0, "");
113
114 VNET_DEFINE(struct rtstat, rtstat);
115 #define V_rtstat        VNET(rtstat)
116
117 VNET_DEFINE(struct radix_node_head *, rt_tables);
118 #define V_rt_tables     VNET(rt_tables)
119
120 VNET_DEFINE(int, rttrash);              /* routes not in table but not freed */
121 #define V_rttrash       VNET(rttrash)
122
123
124 /*
125  * Convert a 'struct radix_node *' to a 'struct rtentry *'.
126  * The operation can be done safely (in this code) because a
127  * 'struct rtentry' starts with two 'struct radix_node''s, the first
128  * one representing leaf nodes in the routing tree, which is
129  * what the code in radix.c passes us as a 'struct radix_node'.
130  *
131  * But because there are a lot of assumptions in this conversion,
132  * do not cast explicitly, but always use the macro below.
133  */
134 #define RNTORT(p)       ((struct rtentry *)(p))
135
136 static VNET_DEFINE(uma_zone_t, rtzone);         /* Routing table UMA zone. */
137 #define V_rtzone        VNET(rtzone)
138
139 static int rtrequest1_fib_change(struct radix_node_head *, struct rt_addrinfo *,
140     struct rtentry **, u_int);
141 static void rt_setmetrics(const struct rt_addrinfo *, struct rtentry *);
142 static int rt_ifdelroute(struct rtentry *rt, void *arg);
143
144 struct if_mtuinfo
145 {
146         struct ifnet    *ifp;
147         int             mtu;
148 };
149
150 static int      if_updatemtu_cb(struct radix_node *, void *);
151
152 /*
153  * handler for net.my_fibnum
154  */
155 static int
156 sysctl_my_fibnum(SYSCTL_HANDLER_ARGS)
157 {
158         int fibnum;
159         int error;
160  
161         fibnum = curthread->td_proc->p_fibnum;
162         error = sysctl_handle_int(oidp, &fibnum, 0, req);
163         return (error);
164 }
165
166 SYSCTL_PROC(_net, OID_AUTO, my_fibnum, CTLTYPE_INT|CTLFLAG_RD,
167             NULL, 0, &sysctl_my_fibnum, "I", "default FIB of caller");
168
169 static __inline struct radix_node_head **
170 rt_tables_get_rnh_ptr(int table, int fam)
171 {
172         struct radix_node_head **rnh;
173
174         KASSERT(table >= 0 && table < rt_numfibs, ("%s: table out of bounds.",
175             __func__));
176         KASSERT(fam >= 0 && fam < (AF_MAX+1), ("%s: fam out of bounds.",
177             __func__));
178
179         /* rnh is [fib=0][af=0]. */
180         rnh = (struct radix_node_head **)V_rt_tables;
181         /* Get the offset to the requested table and fam. */
182         rnh += table * (AF_MAX+1) + fam;
183
184         return (rnh);
185 }
186
187 struct radix_node_head *
188 rt_tables_get_rnh(int table, int fam)
189 {
190
191         return (*rt_tables_get_rnh_ptr(table, fam));
192 }
193
194 /*
195  * route initialization must occur before ip6_init2(), which happenas at
196  * SI_ORDER_MIDDLE.
197  */
198 static void
199 route_init(void)
200 {
201
202         /* whack the tunable ints into  line. */
203         if (rt_numfibs > RT_MAXFIBS)
204                 rt_numfibs = RT_MAXFIBS;
205         if (rt_numfibs == 0)
206                 rt_numfibs = 1;
207 }
208 SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0);
209
210 static int
211 rtentry_zinit(void *mem, int size, int how)
212 {
213         struct rtentry *rt = mem;
214
215         rt->rt_pksent = counter_u64_alloc(how);
216         if (rt->rt_pksent == NULL)
217                 return (ENOMEM);
218
219         RT_LOCK_INIT(rt);
220
221         return (0);
222 }
223
224 static void
225 rtentry_zfini(void *mem, int size)
226 {
227         struct rtentry *rt = mem;
228
229         RT_LOCK_DESTROY(rt);
230         counter_u64_free(rt->rt_pksent);
231 }
232
233 static int
234 rtentry_ctor(void *mem, int size, void *arg, int how)
235 {
236         struct rtentry *rt = mem;
237
238         bzero(rt, offsetof(struct rtentry, rt_endzero));
239         counter_u64_zero(rt->rt_pksent);
240
241         return (0);
242 }
243
244 static void
245 rtentry_dtor(void *mem, int size, void *arg)
246 {
247         struct rtentry *rt = mem;
248
249         RT_UNLOCK_COND(rt);
250 }
251
252 static void
253 vnet_route_init(const void *unused __unused)
254 {
255         struct domain *dom;
256         struct radix_node_head **rnh;
257         int table;
258         int fam;
259
260         V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) *
261             sizeof(struct radix_node_head *), M_RTABLE, M_WAITOK|M_ZERO);
262
263         V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry),
264             rtentry_ctor, rtentry_dtor,
265             rtentry_zinit, rtentry_zfini, UMA_ALIGN_PTR, 0);
266         for (dom = domains; dom; dom = dom->dom_next) {
267                 if (dom->dom_rtattach == NULL)
268                         continue;
269
270                 for  (table = 0; table < rt_numfibs; table++) {
271                         fam = dom->dom_family;
272                         if (table != 0 && fam != AF_INET6 && fam != AF_INET)
273                                 break;
274
275                         rnh = rt_tables_get_rnh_ptr(table, fam);
276                         if (rnh == NULL)
277                                 panic("%s: rnh NULL", __func__);
278                         dom->dom_rtattach((void **)rnh, 0);
279                 }
280         }
281 }
282 VNET_SYSINIT(vnet_route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH,
283     vnet_route_init, 0);
284
285 #ifdef VIMAGE
286 static void
287 vnet_route_uninit(const void *unused __unused)
288 {
289         int table;
290         int fam;
291         struct domain *dom;
292         struct radix_node_head **rnh;
293
294         for (dom = domains; dom; dom = dom->dom_next) {
295                 if (dom->dom_rtdetach == NULL)
296                         continue;
297
298                 for (table = 0; table < rt_numfibs; table++) {
299                         fam = dom->dom_family;
300
301                         if (table != 0 && fam != AF_INET6 && fam != AF_INET)
302                                 break;
303
304                         rnh = rt_tables_get_rnh_ptr(table, fam);
305                         if (rnh == NULL)
306                                 panic("%s: rnh NULL", __func__);
307                         dom->dom_rtdetach((void **)rnh, 0);
308                 }
309         }
310
311         free(V_rt_tables, M_RTABLE);
312         uma_zdestroy(V_rtzone);
313 }
314 VNET_SYSUNINIT(vnet_route_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
315     vnet_route_uninit, 0);
316 #endif
317
318 #ifndef _SYS_SYSPROTO_H_
319 struct setfib_args {
320         int     fibnum;
321 };
322 #endif
323 int
324 sys_setfib(struct thread *td, struct setfib_args *uap)
325 {
326         if (uap->fibnum < 0 || uap->fibnum >= rt_numfibs)
327                 return EINVAL;
328         td->td_proc->p_fibnum = uap->fibnum;
329         return (0);
330 }
331
332 /*
333  * Packet routing routines.
334  */
335 void
336 rtalloc(struct route *ro)
337 {
338
339         rtalloc_ign_fib(ro, 0UL, RT_DEFAULT_FIB);
340 }
341
342 void
343 rtalloc_fib(struct route *ro, u_int fibnum)
344 {
345         rtalloc_ign_fib(ro, 0UL, fibnum);
346 }
347
348 void
349 rtalloc_ign(struct route *ro, u_long ignore)
350 {
351         struct rtentry *rt;
352
353         if ((rt = ro->ro_rt) != NULL) {
354                 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
355                         return;
356                 RTFREE(rt);
357                 ro->ro_rt = NULL;
358         }
359         ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, RT_DEFAULT_FIB);
360         if (ro->ro_rt)
361                 RT_UNLOCK(ro->ro_rt);
362 }
363
364 void
365 rtalloc_ign_fib(struct route *ro, u_long ignore, u_int fibnum)
366 {
367         struct rtentry *rt;
368
369         if ((rt = ro->ro_rt) != NULL) {
370                 if (rt->rt_ifp != NULL && rt->rt_flags & RTF_UP)
371                         return;
372                 RTFREE(rt);
373                 ro->ro_rt = NULL;
374         }
375         ro->ro_rt = rtalloc1_fib(&ro->ro_dst, 1, ignore, fibnum);
376         if (ro->ro_rt)
377                 RT_UNLOCK(ro->ro_rt);
378 }
379
380 /*
381  * Look up the route that matches the address given
382  * Or, at least try.. Create a cloned route if needed.
383  *
384  * The returned route, if any, is locked.
385  */
386 struct rtentry *
387 rtalloc1(struct sockaddr *dst, int report, u_long ignflags)
388 {
389
390         return (rtalloc1_fib(dst, report, ignflags, RT_DEFAULT_FIB));
391 }
392
393 struct rtentry *
394 rtalloc1_fib(struct sockaddr *dst, int report, u_long ignflags,
395                     u_int fibnum)
396 {
397         struct radix_node_head *rnh;
398         struct radix_node *rn;
399         struct rtentry *newrt;
400         struct rt_addrinfo info;
401         int err = 0, msgtype = RTM_MISS;
402         int needlock;
403
404         KASSERT((fibnum < rt_numfibs), ("rtalloc1_fib: bad fibnum"));
405         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
406         newrt = NULL;
407         if (rnh == NULL)
408                 goto miss;
409
410         /*
411          * Look up the address in the table for that Address Family
412          */
413         needlock = !(ignflags & RTF_RNH_LOCKED);
414         if (needlock)
415                 RADIX_NODE_HEAD_RLOCK(rnh);
416 #ifdef INVARIANTS       
417         else
418                 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
419 #endif
420         rn = rnh->rnh_matchaddr(dst, rnh);
421         if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
422                 newrt = RNTORT(rn);
423                 RT_LOCK(newrt);
424                 RT_ADDREF(newrt);
425                 if (needlock)
426                         RADIX_NODE_HEAD_RUNLOCK(rnh);
427                 goto done;
428
429         } else if (needlock)
430                 RADIX_NODE_HEAD_RUNLOCK(rnh);
431         
432         /*
433          * Either we hit the root or couldn't find any match,
434          * Which basically means
435          * "caint get there frm here"
436          */
437 miss:
438         V_rtstat.rts_unreach++;
439
440         if (report) {
441                 /*
442                  * If required, report the failure to the supervising
443                  * Authorities.
444                  * For a delete, this is not an error. (report == 0)
445                  */
446                 bzero(&info, sizeof(info));
447                 info.rti_info[RTAX_DST] = dst;
448                 rt_missmsg_fib(msgtype, &info, 0, err, fibnum);
449         }       
450 done:
451         if (newrt)
452                 RT_LOCK_ASSERT(newrt);
453         return (newrt);
454 }
455
456 /*
457  * Remove a reference count from an rtentry.
458  * If the count gets low enough, take it out of the routing table
459  */
460 void
461 rtfree(struct rtentry *rt)
462 {
463         struct radix_node_head *rnh;
464
465         KASSERT(rt != NULL,("%s: NULL rt", __func__));
466         rnh = rt_tables_get_rnh(rt->rt_fibnum, rt_key(rt)->sa_family);
467         KASSERT(rnh != NULL,("%s: NULL rnh", __func__));
468
469         RT_LOCK_ASSERT(rt);
470
471         /*
472          * The callers should use RTFREE_LOCKED() or RTFREE(), so
473          * we should come here exactly with the last reference.
474          */
475         RT_REMREF(rt);
476         if (rt->rt_refcnt > 0) {
477                 log(LOG_DEBUG, "%s: %p has %d refs\n", __func__, rt, rt->rt_refcnt);
478                 goto done;
479         }
480
481         /*
482          * On last reference give the "close method" a chance
483          * to cleanup private state.  This also permits (for
484          * IPv4 and IPv6) a chance to decide if the routing table
485          * entry should be purged immediately or at a later time.
486          * When an immediate purge is to happen the close routine
487          * typically calls rtexpunge which clears the RTF_UP flag
488          * on the entry so that the code below reclaims the storage.
489          */
490         if (rt->rt_refcnt == 0 && rnh->rnh_close)
491                 rnh->rnh_close((struct radix_node *)rt, rnh);
492
493         /*
494          * If we are no longer "up" (and ref == 0)
495          * then we can free the resources associated
496          * with the route.
497          */
498         if ((rt->rt_flags & RTF_UP) == 0) {
499                 if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
500                         panic("rtfree 2");
501                 /*
502                  * the rtentry must have been removed from the routing table
503                  * so it is represented in rttrash.. remove that now.
504                  */
505                 V_rttrash--;
506 #ifdef  DIAGNOSTIC
507                 if (rt->rt_refcnt < 0) {
508                         printf("rtfree: %p not freed (neg refs)\n", rt);
509                         goto done;
510                 }
511 #endif
512                 /*
513                  * release references on items we hold them on..
514                  * e.g other routes and ifaddrs.
515                  */
516                 if (rt->rt_ifa)
517                         ifa_free(rt->rt_ifa);
518                 /*
519                  * The key is separatly alloc'd so free it (see rt_setgate()).
520                  * This also frees the gateway, as they are always malloc'd
521                  * together.
522                  */
523                 R_Free(rt_key(rt));
524
525                 /*
526                  * and the rtentry itself of course
527                  */
528                 uma_zfree(V_rtzone, rt);
529                 return;
530         }
531 done:
532         RT_UNLOCK(rt);
533 }
534
535
536 /*
537  * Force a routing table entry to the specified
538  * destination to go through the given gateway.
539  * Normally called as a result of a routing redirect
540  * message from the network layer.
541  */
542 void
543 rtredirect(struct sockaddr *dst,
544         struct sockaddr *gateway,
545         struct sockaddr *netmask,
546         int flags,
547         struct sockaddr *src)
548 {
549
550         rtredirect_fib(dst, gateway, netmask, flags, src, RT_DEFAULT_FIB);
551 }
552
553 void
554 rtredirect_fib(struct sockaddr *dst,
555         struct sockaddr *gateway,
556         struct sockaddr *netmask,
557         int flags,
558         struct sockaddr *src,
559         u_int fibnum)
560 {
561         struct rtentry *rt, *rt0 = NULL;
562         int error = 0;
563         short *stat = NULL;
564         struct rt_addrinfo info;
565         struct ifaddr *ifa;
566         struct radix_node_head *rnh;
567
568         ifa = NULL;
569         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
570         if (rnh == NULL) {
571                 error = EAFNOSUPPORT;
572                 goto out;
573         }
574
575         /* verify the gateway is directly reachable */
576         if ((ifa = ifa_ifwithnet(gateway, 0, fibnum)) == NULL) {
577                 error = ENETUNREACH;
578                 goto out;
579         }
580         rt = rtalloc1_fib(dst, 0, 0UL, fibnum); /* NB: rt is locked */
581         /*
582          * If the redirect isn't from our current router for this dst,
583          * it's either old or wrong.  If it redirects us to ourselves,
584          * we have a routing loop, perhaps as a result of an interface
585          * going down recently.
586          */
587         if (!(flags & RTF_DONE) && rt &&
588              (!sa_equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))
589                 error = EINVAL;
590         else if (ifa_ifwithaddr_check(gateway))
591                 error = EHOSTUNREACH;
592         if (error)
593                 goto done;
594         /*
595          * Create a new entry if we just got back a wildcard entry
596          * or the lookup failed.  This is necessary for hosts
597          * which use routing redirects generated by smart gateways
598          * to dynamically build the routing tables.
599          */
600         if (rt == NULL || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
601                 goto create;
602         /*
603          * Don't listen to the redirect if it's
604          * for a route to an interface.
605          */
606         if (rt->rt_flags & RTF_GATEWAY) {
607                 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
608                         /*
609                          * Changing from route to net => route to host.
610                          * Create new route, rather than smashing route to net.
611                          */
612                 create:
613                         rt0 = rt;
614                         rt = NULL;
615                 
616                         flags |=  RTF_GATEWAY | RTF_DYNAMIC;
617                         bzero((caddr_t)&info, sizeof(info));
618                         info.rti_info[RTAX_DST] = dst;
619                         info.rti_info[RTAX_GATEWAY] = gateway;
620                         info.rti_info[RTAX_NETMASK] = netmask;
621                         info.rti_ifa = ifa;
622                         info.rti_flags = flags;
623                         if (rt0 != NULL)
624                                 RT_UNLOCK(rt0); /* drop lock to avoid LOR with RNH */
625                         error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
626                         if (rt != NULL) {
627                                 RT_LOCK(rt);
628                                 if (rt0 != NULL)
629                                         EVENTHANDLER_INVOKE(route_redirect_event, rt0, rt, dst);
630                                 flags = rt->rt_flags;
631                         }
632                         if (rt0 != NULL)
633                                 RTFREE(rt0);
634                         
635                         stat = &V_rtstat.rts_dynamic;
636                 } else {
637                         struct rtentry *gwrt;
638
639                         /*
640                          * Smash the current notion of the gateway to
641                          * this destination.  Should check about netmask!!!
642                          */
643                         rt->rt_flags |= RTF_MODIFIED;
644                         flags |= RTF_MODIFIED;
645                         stat = &V_rtstat.rts_newgateway;
646                         /*
647                          * add the key and gateway (in one malloc'd chunk).
648                          */
649                         RT_UNLOCK(rt);
650                         RADIX_NODE_HEAD_LOCK(rnh);
651                         RT_LOCK(rt);
652                         rt_setgate(rt, rt_key(rt), gateway);
653                         gwrt = rtalloc1(gateway, 1, RTF_RNH_LOCKED);
654                         RADIX_NODE_HEAD_UNLOCK(rnh);
655                         EVENTHANDLER_INVOKE(route_redirect_event, rt, gwrt, dst);
656                         RTFREE_LOCKED(gwrt);
657                 }
658         } else
659                 error = EHOSTUNREACH;
660 done:
661         if (rt)
662                 RTFREE_LOCKED(rt);
663 out:
664         if (error)
665                 V_rtstat.rts_badredirect++;
666         else if (stat != NULL)
667                 (*stat)++;
668         bzero((caddr_t)&info, sizeof(info));
669         info.rti_info[RTAX_DST] = dst;
670         info.rti_info[RTAX_GATEWAY] = gateway;
671         info.rti_info[RTAX_NETMASK] = netmask;
672         info.rti_info[RTAX_AUTHOR] = src;
673         rt_missmsg_fib(RTM_REDIRECT, &info, flags, error, fibnum);
674         if (ifa != NULL)
675                 ifa_free(ifa);
676 }
677
678 int
679 rtioctl(u_long req, caddr_t data)
680 {
681
682         return (rtioctl_fib(req, data, RT_DEFAULT_FIB));
683 }
684
685 /*
686  * Routing table ioctl interface.
687  */
688 int
689 rtioctl_fib(u_long req, caddr_t data, u_int fibnum)
690 {
691
692         /*
693          * If more ioctl commands are added here, make sure the proper
694          * super-user checks are being performed because it is possible for
695          * prison-root to make it this far if raw sockets have been enabled
696          * in jails.
697          */
698 #ifdef INET
699         /* Multicast goop, grrr... */
700         return mrt_ioctl ? mrt_ioctl(req, data, fibnum) : EOPNOTSUPP;
701 #else /* INET */
702         return ENXIO;
703 #endif /* INET */
704 }
705
706 struct ifaddr *
707 ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
708                                 u_int fibnum)
709 {
710         struct ifaddr *ifa;
711         int not_found = 0;
712
713         if ((flags & RTF_GATEWAY) == 0) {
714                 /*
715                  * If we are adding a route to an interface,
716                  * and the interface is a pt to pt link
717                  * we should search for the destination
718                  * as our clue to the interface.  Otherwise
719                  * we can use the local address.
720                  */
721                 ifa = NULL;
722                 if (flags & RTF_HOST)
723                         ifa = ifa_ifwithdstaddr(dst, fibnum);
724                 if (ifa == NULL)
725                         ifa = ifa_ifwithaddr(gateway);
726         } else {
727                 /*
728                  * If we are adding a route to a remote net
729                  * or host, the gateway may still be on the
730                  * other end of a pt to pt link.
731                  */
732                 ifa = ifa_ifwithdstaddr(gateway, fibnum);
733         }
734         if (ifa == NULL)
735                 ifa = ifa_ifwithnet(gateway, 0, fibnum);
736         if (ifa == NULL) {
737                 struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum);
738                 if (rt == NULL)
739                         return (NULL);
740                 /*
741                  * dismiss a gateway that is reachable only
742                  * through the default router
743                  */
744                 switch (gateway->sa_family) {
745                 case AF_INET:
746                         if (satosin(rt_key(rt))->sin_addr.s_addr == INADDR_ANY)
747                                 not_found = 1;
748                         break;
749                 case AF_INET6:
750                         if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(rt))->sin6_addr))
751                                 not_found = 1;
752                         break;
753                 default:
754                         break;
755                 }
756                 if (!not_found && rt->rt_ifa != NULL) {
757                         ifa = rt->rt_ifa;
758                         ifa_ref(ifa);
759                 }
760                 RT_REMREF(rt);
761                 RT_UNLOCK(rt);
762                 if (not_found || ifa == NULL)
763                         return (NULL);
764         }
765         if (ifa->ifa_addr->sa_family != dst->sa_family) {
766                 struct ifaddr *oifa = ifa;
767                 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
768                 if (ifa == NULL)
769                         ifa = oifa;
770                 else
771                         ifa_free(oifa);
772         }
773         return (ifa);
774 }
775
776 /*
777  * Do appropriate manipulations of a routing tree given
778  * all the bits of info needed
779  */
780 int
781 rtrequest(int req,
782         struct sockaddr *dst,
783         struct sockaddr *gateway,
784         struct sockaddr *netmask,
785         int flags,
786         struct rtentry **ret_nrt)
787 {
788
789         return (rtrequest_fib(req, dst, gateway, netmask, flags, ret_nrt,
790             RT_DEFAULT_FIB));
791 }
792
793 int
794 rtrequest_fib(int req,
795         struct sockaddr *dst,
796         struct sockaddr *gateway,
797         struct sockaddr *netmask,
798         int flags,
799         struct rtentry **ret_nrt,
800         u_int fibnum)
801 {
802         struct rt_addrinfo info;
803
804         if (dst->sa_len == 0)
805                 return(EINVAL);
806
807         bzero((caddr_t)&info, sizeof(info));
808         info.rti_flags = flags;
809         info.rti_info[RTAX_DST] = dst;
810         info.rti_info[RTAX_GATEWAY] = gateway;
811         info.rti_info[RTAX_NETMASK] = netmask;
812         return rtrequest1_fib(req, &info, ret_nrt, fibnum);
813 }
814
815
816 void
817 rt_foreach_fib(int af, rt_setwarg_t *setwa_f, rt_walktree_f_t *wa_f, void *arg)
818 {
819         struct radix_node_head *rnh;
820         uint32_t fibnum;
821         int i;
822
823         for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
824                 /* Do we want some specific family? */
825                 if (af != AF_UNSPEC) {
826                         rnh = rt_tables_get_rnh(fibnum, af);
827                         if (rnh == NULL)
828                                 continue;
829                         if (setwa_f != NULL)
830                                 setwa_f(rnh, fibnum, i, arg);
831
832                         RADIX_NODE_HEAD_LOCK(rnh);
833                         rnh->rnh_walktree(rnh, (walktree_f_t *)wa_f, arg);
834                         RADIX_NODE_HEAD_UNLOCK(rnh);
835                         continue;
836                 }
837
838                 for (i = 1; i <= AF_MAX; i++) {
839                         rnh = rt_tables_get_rnh(fibnum, i);
840                         if (rnh == NULL)
841                                 continue;
842                         if (setwa_f != NULL)
843                                 setwa_f(rnh, fibnum, i, arg);
844
845                         RADIX_NODE_HEAD_LOCK(rnh);
846                         rnh->rnh_walktree(rnh, (walktree_f_t *)wa_f, arg);
847                         RADIX_NODE_HEAD_UNLOCK(rnh);
848                 }
849         }
850 }
851
852 /*
853  * Delete Routes for a Network Interface
854  *
855  * Called for each routing entry via the rnh->rnh_walktree() call above
856  * to delete all route entries referencing a detaching network interface.
857  *
858  * Arguments:
859  *      rt      pointer to rtentry
860  *      arg     argument passed to rnh->rnh_walktree() - detaching interface
861  *
862  * Returns:
863  *      0       successful
864  *      errno   failed - reason indicated
865  */
866 static int
867 rt_ifdelroute(struct rtentry *rt, void *arg)
868 {
869         struct ifnet    *ifp = arg;
870         int             err;
871
872         if (rt->rt_ifp != ifp)
873                 return (0);
874
875         /*
876          * Protect (sorta) against walktree recursion problems
877          * with cloned routes
878          */
879         if ((rt->rt_flags & RTF_UP) == 0)
880                 return (0);
881
882         err = rtrequest_fib(RTM_DELETE, rt_key(rt), rt->rt_gateway,
883                         rt_mask(rt),
884                         rt->rt_flags | RTF_RNH_LOCKED | RTF_PINNED,
885                         (struct rtentry **) NULL, rt->rt_fibnum);
886         if (err != 0)
887                 log(LOG_WARNING, "rt_ifdelroute: error %d\n", err);
888
889         return (0);
890 }
891
892 /*
893  * Delete all remaining routes using this interface
894  * Unfortuneatly the only way to do this is to slog through
895  * the entire routing table looking for routes which point
896  * to this interface...oh well...
897  */
898 void
899 rt_flushifroutes(struct ifnet *ifp)
900 {
901
902         rt_foreach_fib(AF_UNSPEC, NULL, rt_ifdelroute, ifp);
903 }
904
905 /*
906  * These (questionable) definitions of apparent local variables apply
907  * to the next two functions.  XXXXXX!!!
908  */
909 #define dst     info->rti_info[RTAX_DST]
910 #define gateway info->rti_info[RTAX_GATEWAY]
911 #define netmask info->rti_info[RTAX_NETMASK]
912 #define ifaaddr info->rti_info[RTAX_IFA]
913 #define ifpaddr info->rti_info[RTAX_IFP]
914 #define flags   info->rti_flags
915
916 int
917 rt_getifa(struct rt_addrinfo *info)
918 {
919
920         return (rt_getifa_fib(info, RT_DEFAULT_FIB));
921 }
922
923 /*
924  * Look up rt_addrinfo for a specific fib.  Note that if rti_ifa is defined,
925  * it will be referenced so the caller must free it.
926  */
927 int
928 rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
929 {
930         struct ifaddr *ifa;
931         int error = 0;
932
933         /*
934          * ifp may be specified by sockaddr_dl
935          * when protocol address is ambiguous.
936          */
937         if (info->rti_ifp == NULL && ifpaddr != NULL &&
938             ifpaddr->sa_family == AF_LINK &&
939             (ifa = ifa_ifwithnet(ifpaddr, 0, fibnum)) != NULL) {
940                 info->rti_ifp = ifa->ifa_ifp;
941                 ifa_free(ifa);
942         }
943         if (info->rti_ifa == NULL && ifaaddr != NULL)
944                 info->rti_ifa = ifa_ifwithaddr(ifaaddr);
945         if (info->rti_ifa == NULL) {
946                 struct sockaddr *sa;
947
948                 sa = ifaaddr != NULL ? ifaaddr :
949                     (gateway != NULL ? gateway : dst);
950                 if (sa != NULL && info->rti_ifp != NULL)
951                         info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp);
952                 else if (dst != NULL && gateway != NULL)
953                         info->rti_ifa = ifa_ifwithroute(flags, dst, gateway,
954                                                         fibnum);
955                 else if (sa != NULL)
956                         info->rti_ifa = ifa_ifwithroute(flags, sa, sa,
957                                                         fibnum);
958         }
959         if ((ifa = info->rti_ifa) != NULL) {
960                 if (info->rti_ifp == NULL)
961                         info->rti_ifp = ifa->ifa_ifp;
962         } else
963                 error = ENETUNREACH;
964         return (error);
965 }
966
967 /*
968  * Expunges references to a route that's about to be reclaimed.
969  * The route must be locked.
970  */
971 int
972 rt_expunge(struct radix_node_head *rnh, struct rtentry *rt)
973 {
974 #if !defined(RADIX_MPATH)
975         struct radix_node *rn;
976 #else
977         struct rt_addrinfo info;
978         int fib;
979         struct rtentry *rt0;
980 #endif
981         struct ifaddr *ifa;
982         int error = 0;
983
984         RT_LOCK_ASSERT(rt);
985         RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
986
987 #ifdef RADIX_MPATH
988         fib = rt->rt_fibnum;
989         bzero(&info, sizeof(info));
990         info.rti_ifp = rt->rt_ifp;
991         info.rti_flags = RTF_RNH_LOCKED;
992         info.rti_info[RTAX_DST] = rt_key(rt);
993         info.rti_info[RTAX_GATEWAY] = rt->rt_ifa->ifa_addr;
994
995         RT_UNLOCK(rt);
996         error = rtrequest1_fib(RTM_DELETE, &info, &rt0, fib);
997
998         if (error == 0 && rt0 != NULL) {
999                 rt = rt0;
1000                 RT_LOCK(rt);
1001         } else if (error != 0) {
1002                 RT_LOCK(rt);
1003                 return (error);
1004         }
1005 #else
1006         /*
1007          * Remove the item from the tree; it should be there,
1008          * but when callers invoke us blindly it may not (sigh).
1009          */
1010         rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), rnh);
1011         if (rn == NULL) {
1012                 error = ESRCH;
1013                 goto bad;
1014         }
1015         KASSERT((rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) == 0,
1016                 ("unexpected flags 0x%x", rn->rn_flags));
1017         KASSERT(rt == RNTORT(rn),
1018                 ("lookup mismatch, rt %p rn %p", rt, rn));
1019 #endif /* RADIX_MPATH */
1020
1021         rt->rt_flags &= ~RTF_UP;
1022
1023         /*
1024          * Give the protocol a chance to keep things in sync.
1025          */
1026         if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) {
1027                 struct rt_addrinfo info;
1028
1029                 bzero((caddr_t)&info, sizeof(info));
1030                 info.rti_flags = rt->rt_flags;
1031                 info.rti_info[RTAX_DST] = rt_key(rt);
1032                 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
1033                 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1034                 ifa->ifa_rtrequest(RTM_DELETE, rt, &info);
1035         }
1036
1037         /*
1038          * one more rtentry floating around that is not
1039          * linked to the routing table.
1040          */
1041         V_rttrash++;
1042 #if !defined(RADIX_MPATH)
1043 bad:
1044 #endif
1045         return (error);
1046 }
1047
1048 static int
1049 if_updatemtu_cb(struct radix_node *rn, void *arg)
1050 {
1051         struct rtentry *rt;
1052         struct if_mtuinfo *ifmtu;
1053
1054         rt = (struct rtentry *)rn;
1055         ifmtu = (struct if_mtuinfo *)arg;
1056
1057         if (rt->rt_ifp != ifmtu->ifp)
1058                 return (0);
1059
1060         if (rt->rt_mtu >= ifmtu->mtu) {
1061                 /* We have to decrease mtu regardless of flags */
1062                 rt->rt_mtu = ifmtu->mtu;
1063                 return (0);
1064         }
1065
1066         /*
1067          * New MTU is bigger. Check if are allowed to alter it
1068          */
1069         if ((rt->rt_flags & (RTF_FIXEDMTU | RTF_GATEWAY | RTF_HOST)) != 0) {
1070
1071                 /*
1072                  * Skip routes with user-supplied MTU and
1073                  * non-interface routes
1074                  */
1075                 return (0);
1076         }
1077
1078         /* We are safe to update route MTU */
1079         rt->rt_mtu = ifmtu->mtu;
1080
1081         return (0);
1082 }
1083
1084 void
1085 rt_updatemtu(struct ifnet *ifp)
1086 {
1087         struct if_mtuinfo ifmtu;
1088         struct radix_node_head *rnh;
1089         int i, j;
1090
1091         ifmtu.ifp = ifp;
1092
1093         /*
1094          * Try to update rt_mtu for all routes using this interface
1095          * Unfortunately the only way to do this is to traverse all
1096          * routing tables in all fibs/domains.
1097          */
1098         for (i = 1; i <= AF_MAX; i++) {
1099                 ifmtu.mtu = if_getmtu_family(ifp, i);
1100                 for (j = 0; j < rt_numfibs; j++) {
1101                         rnh = rt_tables_get_rnh(j, i);
1102                         if (rnh == NULL)
1103                                 continue;
1104                         RADIX_NODE_HEAD_LOCK(rnh);
1105                         rnh->rnh_walktree(rnh, if_updatemtu_cb, &ifmtu);
1106                         RADIX_NODE_HEAD_UNLOCK(rnh);
1107                 }
1108         }
1109 }
1110
1111
1112 #if 0
1113 int p_sockaddr(char *buf, int buflen, struct sockaddr *s);
1114 int rt_print(char *buf, int buflen, struct rtentry *rt);
1115
1116 int
1117 p_sockaddr(char *buf, int buflen, struct sockaddr *s)
1118 {
1119         void *paddr = NULL;
1120
1121         switch (s->sa_family) {
1122         case AF_INET:
1123                 paddr = &((struct sockaddr_in *)s)->sin_addr;
1124                 break;
1125         case AF_INET6:
1126                 paddr = &((struct sockaddr_in6 *)s)->sin6_addr;
1127                 break;
1128         }
1129
1130         if (paddr == NULL)
1131                 return (0);
1132
1133         if (inet_ntop(s->sa_family, paddr, buf, buflen) == NULL)
1134                 return (0);
1135         
1136         return (strlen(buf));
1137 }
1138
1139 int
1140 rt_print(char *buf, int buflen, struct rtentry *rt)
1141 {
1142         struct sockaddr *addr, *mask;
1143         int i = 0;
1144
1145         addr = rt_key(rt);
1146         mask = rt_mask(rt);
1147
1148         i = p_sockaddr(buf, buflen, addr);
1149         if (!(rt->rt_flags & RTF_HOST)) {
1150                 buf[i++] = '/';
1151                 i += p_sockaddr(buf + i, buflen - i, mask);
1152         }
1153
1154         if (rt->rt_flags & RTF_GATEWAY) {
1155                 buf[i++] = '>';
1156                 i += p_sockaddr(buf + i, buflen - i, rt->rt_gateway);
1157         }
1158
1159         return (i);
1160 }
1161 #endif
1162
1163 #ifdef RADIX_MPATH
1164 static int
1165 rn_mpath_update(int req, struct rt_addrinfo *info,
1166     struct radix_node_head *rnh, struct rtentry **ret_nrt)
1167 {
1168         /*
1169          * if we got multipath routes, we require users to specify
1170          * a matching RTAX_GATEWAY.
1171          */
1172         struct rtentry *rt, *rto = NULL;
1173         struct radix_node *rn;
1174         int error = 0;
1175
1176         rn = rnh->rnh_lookup(dst, netmask, rnh);
1177         if (rn == NULL)
1178                 return (ESRCH);
1179         rto = rt = RNTORT(rn);
1180
1181         rt = rt_mpath_matchgate(rt, gateway);
1182         if (rt == NULL)
1183                 return (ESRCH);
1184         /*
1185          * this is the first entry in the chain
1186          */
1187         if (rto == rt) {
1188                 rn = rn_mpath_next((struct radix_node *)rt);
1189                 /*
1190                  * there is another entry, now it's active
1191                  */
1192                 if (rn) {
1193                         rto = RNTORT(rn);
1194                         RT_LOCK(rto);
1195                         rto->rt_flags |= RTF_UP;
1196                         RT_UNLOCK(rto);
1197                 } else if (rt->rt_flags & RTF_GATEWAY) {
1198                         /*
1199                          * For gateway routes, we need to 
1200                          * make sure that we we are deleting
1201                          * the correct gateway. 
1202                          * rt_mpath_matchgate() does not 
1203                          * check the case when there is only
1204                          * one route in the chain.  
1205                          */
1206                         if (gateway &&
1207                             (rt->rt_gateway->sa_len != gateway->sa_len ||
1208                                 memcmp(rt->rt_gateway, gateway, gateway->sa_len)))
1209                                 error = ESRCH;
1210                         else {
1211                                 /*
1212                                  * remove from tree before returning it
1213                                  * to the caller
1214                                  */
1215                                 rn = rnh->rnh_deladdr(dst, netmask, rnh);
1216                                 KASSERT(rt == RNTORT(rn), ("radix node disappeared"));
1217                                 goto gwdelete;
1218                         }
1219                         
1220                 }
1221                 /*
1222                  * use the normal delete code to remove
1223                  * the first entry
1224                  */
1225                 if (req != RTM_DELETE) 
1226                         goto nondelete;
1227
1228                 error = ENOENT;
1229                 goto done;
1230         }
1231                 
1232         /*
1233          * if the entry is 2nd and on up
1234          */
1235         if ((req == RTM_DELETE) && !rt_mpath_deldup(rto, rt))
1236                 panic ("rtrequest1: rt_mpath_deldup");
1237 gwdelete:
1238         RT_LOCK(rt);
1239         RT_ADDREF(rt);
1240         if (req == RTM_DELETE) {
1241                 rt->rt_flags &= ~RTF_UP;
1242                 /*
1243                  * One more rtentry floating around that is not
1244                  * linked to the routing table. rttrash will be decremented
1245                  * when RTFREE(rt) is eventually called.
1246                  */
1247                 V_rttrash++;
1248         }
1249         
1250 nondelete:
1251         if (req != RTM_DELETE)
1252                 panic("unrecognized request %d", req);
1253         
1254
1255         /*
1256          * If the caller wants it, then it can have it,
1257          * but it's up to it to free the rtentry as we won't be
1258          * doing it.
1259          */
1260         if (ret_nrt) {
1261                 *ret_nrt = rt;
1262                 RT_UNLOCK(rt);
1263         } else
1264                 RTFREE_LOCKED(rt);
1265 done:
1266         return (error);
1267 }
1268 #endif
1269
1270 int
1271 rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt,
1272                                 u_int fibnum)
1273 {
1274         int error = 0, needlock = 0;
1275         struct rtentry *rt;
1276 #ifdef FLOWTABLE
1277         struct rtentry *rt0;
1278 #endif
1279         struct radix_node *rn;
1280         struct radix_node_head *rnh;
1281         struct ifaddr *ifa;
1282         struct sockaddr *ndst;
1283         struct sockaddr_storage mdst;
1284 #define senderr(x) { error = x ; goto bad; }
1285
1286         KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum"));
1287         switch (dst->sa_family) {
1288         case AF_INET6:
1289         case AF_INET:
1290                 /* We support multiple FIBs. */
1291                 break;
1292         default:
1293                 fibnum = RT_DEFAULT_FIB;
1294                 break;
1295         }
1296
1297         /*
1298          * Find the correct routing tree to use for this Address Family
1299          */
1300         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
1301         if (rnh == NULL)
1302                 return (EAFNOSUPPORT);
1303         needlock = ((flags & RTF_RNH_LOCKED) == 0);
1304         flags &= ~RTF_RNH_LOCKED;
1305         if (needlock)
1306                 RADIX_NODE_HEAD_LOCK(rnh);
1307         else
1308                 RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
1309         /*
1310          * If we are adding a host route then we don't want to put
1311          * a netmask in the tree, nor do we want to clone it.
1312          */
1313         if (flags & RTF_HOST)
1314                 netmask = NULL;
1315
1316         switch (req) {
1317         case RTM_DELETE:
1318                 if (netmask) {
1319                         rt_maskedcopy(dst, (struct sockaddr *)&mdst, netmask);
1320                         dst = (struct sockaddr *)&mdst;
1321                 }
1322 #ifdef RADIX_MPATH
1323                 if (rn_mpath_capable(rnh)) {
1324                         error = rn_mpath_update(req, info, rnh, ret_nrt);
1325                         /*
1326                          * "bad" holds true for the success case
1327                          * as well
1328                          */
1329                         if (error != ENOENT)
1330                                 goto bad;
1331                         error = 0;
1332                 }
1333 #endif
1334                 if ((flags & RTF_PINNED) == 0) {
1335                         /* Check if target route can be deleted */
1336                         rt = (struct rtentry *)rnh->rnh_lookup(dst,
1337                             netmask, rnh);
1338                         if ((rt != NULL) && (rt->rt_flags & RTF_PINNED))
1339                                 senderr(EADDRINUSE);
1340                 }
1341
1342                 /*
1343                  * Remove the item from the tree and return it.
1344                  * Complain if it is not there and do no more processing.
1345                  */
1346                 rn = rnh->rnh_deladdr(dst, netmask, rnh);
1347                 if (rn == NULL)
1348                         senderr(ESRCH);
1349                 if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
1350                         panic ("rtrequest delete");
1351                 rt = RNTORT(rn);
1352                 RT_LOCK(rt);
1353                 RT_ADDREF(rt);
1354                 rt->rt_flags &= ~RTF_UP;
1355
1356                 /*
1357                  * give the protocol a chance to keep things in sync.
1358                  */
1359                 if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)
1360                         ifa->ifa_rtrequest(RTM_DELETE, rt, info);
1361
1362                 /*
1363                  * One more rtentry floating around that is not
1364                  * linked to the routing table. rttrash will be decremented
1365                  * when RTFREE(rt) is eventually called.
1366                  */
1367                 V_rttrash++;
1368
1369                 /*
1370                  * If the caller wants it, then it can have it,
1371                  * but it's up to it to free the rtentry as we won't be
1372                  * doing it.
1373                  */
1374                 if (ret_nrt) {
1375                         *ret_nrt = rt;
1376                         RT_UNLOCK(rt);
1377                 } else
1378                         RTFREE_LOCKED(rt);
1379                 break;
1380         case RTM_RESOLVE:
1381                 /*
1382                  * resolve was only used for route cloning
1383                  * here for compat
1384                  */
1385                 break;
1386         case RTM_ADD:
1387                 if ((flags & RTF_GATEWAY) && !gateway)
1388                         senderr(EINVAL);
1389                 if (dst && gateway && (dst->sa_family != gateway->sa_family) && 
1390                     (gateway->sa_family != AF_UNSPEC) && (gateway->sa_family != AF_LINK))
1391                         senderr(EINVAL);
1392
1393                 if (info->rti_ifa == NULL) {
1394                         error = rt_getifa_fib(info, fibnum);
1395                         if (error)
1396                                 senderr(error);
1397                 } else
1398                         ifa_ref(info->rti_ifa);
1399                 ifa = info->rti_ifa;
1400                 rt = uma_zalloc(V_rtzone, M_NOWAIT);
1401                 if (rt == NULL) {
1402                         ifa_free(ifa);
1403                         senderr(ENOBUFS);
1404                 }
1405                 rt->rt_flags = RTF_UP | flags;
1406                 rt->rt_fibnum = fibnum;
1407                 /*
1408                  * Add the gateway. Possibly re-malloc-ing the storage for it.
1409                  */
1410                 RT_LOCK(rt);
1411                 if ((error = rt_setgate(rt, dst, gateway)) != 0) {
1412                         ifa_free(ifa);
1413                         uma_zfree(V_rtzone, rt);
1414                         senderr(error);
1415                 }
1416
1417                 /*
1418                  * point to the (possibly newly malloc'd) dest address.
1419                  */
1420                 ndst = (struct sockaddr *)rt_key(rt);
1421
1422                 /*
1423                  * make sure it contains the value we want (masked if needed).
1424                  */
1425                 if (netmask) {
1426                         rt_maskedcopy(dst, ndst, netmask);
1427                 } else
1428                         bcopy(dst, ndst, dst->sa_len);
1429
1430                 /*
1431                  * We use the ifa reference returned by rt_getifa_fib().
1432                  * This moved from below so that rnh->rnh_addaddr() can
1433                  * examine the ifa and  ifa->ifa_ifp if it so desires.
1434                  */
1435                 rt->rt_ifa = ifa;
1436                 rt->rt_ifp = ifa->ifa_ifp;
1437                 rt->rt_weight = 1;
1438
1439                 rt_setmetrics(info, rt);
1440
1441 #ifdef RADIX_MPATH
1442                 /* do not permit exactly the same dst/mask/gw pair */
1443                 if (rn_mpath_capable(rnh) &&
1444                         rt_mpath_conflict(rnh, rt, netmask)) {
1445                         ifa_free(rt->rt_ifa);
1446                         R_Free(rt_key(rt));
1447                         uma_zfree(V_rtzone, rt);
1448                         senderr(EEXIST);
1449                 }
1450 #endif
1451
1452 #ifdef FLOWTABLE
1453                 rt0 = NULL;
1454                 /* "flow-table" only supports IPv6 and IPv4 at the moment. */
1455                 switch (dst->sa_family) {
1456 #ifdef INET6
1457                 case AF_INET6:
1458 #endif
1459 #ifdef INET
1460                 case AF_INET:
1461 #endif
1462 #if defined(INET6) || defined(INET)
1463                         rn = rnh->rnh_matchaddr(dst, rnh);
1464                         if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) {
1465                                 struct sockaddr *mask;
1466                                 u_char *m, *n;
1467                                 int len;
1468                                 
1469                                 /*
1470                                  * compare mask to see if the new route is
1471                                  * more specific than the existing one
1472                                  */
1473                                 rt0 = RNTORT(rn);
1474                                 RT_LOCK(rt0);
1475                                 RT_ADDREF(rt0);
1476                                 RT_UNLOCK(rt0);
1477                                 /*
1478                                  * A host route is already present, so 
1479                                  * leave the flow-table entries as is.
1480                                  */
1481                                 if (rt0->rt_flags & RTF_HOST) {
1482                                         RTFREE(rt0);
1483                                         rt0 = NULL;
1484                                 } else if (!(flags & RTF_HOST) && netmask) {
1485                                         mask = rt_mask(rt0);
1486                                         len = mask->sa_len;
1487                                         m = (u_char *)mask;
1488                                         n = (u_char *)netmask;
1489                                         while (len-- > 0) {
1490                                                 if (*n != *m)
1491                                                         break;
1492                                                 n++;
1493                                                 m++;
1494                                         }
1495                                         if (len == 0 || (*n < *m)) {
1496                                                 RTFREE(rt0);
1497                                                 rt0 = NULL;
1498                                         }
1499                                 }
1500                         }
1501 #endif/* INET6 || INET */
1502                 }
1503 #endif /* FLOWTABLE */
1504
1505                 /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
1506                 rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes);
1507                 /*
1508                  * If it still failed to go into the tree,
1509                  * then un-make it (this should be a function)
1510                  */
1511                 if (rn == NULL) {
1512                         ifa_free(rt->rt_ifa);
1513                         R_Free(rt_key(rt));
1514                         uma_zfree(V_rtzone, rt);
1515 #ifdef FLOWTABLE
1516                         if (rt0 != NULL)
1517                                 RTFREE(rt0);
1518 #endif
1519                         senderr(EEXIST);
1520                 } 
1521 #ifdef FLOWTABLE
1522                 else if (rt0 != NULL) {
1523                         flowtable_route_flush(dst->sa_family, rt0);
1524                         RTFREE(rt0);
1525                 }
1526 #endif
1527
1528                 /*
1529                  * If this protocol has something to add to this then
1530                  * allow it to do that as well.
1531                  */
1532                 if (ifa->ifa_rtrequest)
1533                         ifa->ifa_rtrequest(req, rt, info);
1534
1535                 /*
1536                  * actually return a resultant rtentry and
1537                  * give the caller a single reference.
1538                  */
1539                 if (ret_nrt) {
1540                         *ret_nrt = rt;
1541                         RT_ADDREF(rt);
1542                 }
1543                 RT_UNLOCK(rt);
1544                 break;
1545         case RTM_CHANGE:
1546                 error = rtrequest1_fib_change(rnh, info, ret_nrt, fibnum);
1547                 break;
1548         default:
1549                 error = EOPNOTSUPP;
1550         }
1551 bad:
1552         if (needlock)
1553                 RADIX_NODE_HEAD_UNLOCK(rnh);
1554         return (error);
1555 #undef senderr
1556 }
1557
1558 #undef dst
1559 #undef gateway
1560 #undef netmask
1561 #undef ifaaddr
1562 #undef ifpaddr
1563 #undef flags
1564
1565 static int
1566 rtrequest1_fib_change(struct radix_node_head *rnh, struct rt_addrinfo *info,
1567     struct rtentry **ret_nrt, u_int fibnum)
1568 {
1569         struct rtentry *rt = NULL;
1570         int error = 0;
1571         int free_ifa = 0;
1572         int family, mtu;
1573         struct if_mtuinfo ifmtu;
1574
1575         rt = (struct rtentry *)rnh->rnh_lookup(info->rti_info[RTAX_DST],
1576             info->rti_info[RTAX_NETMASK], rnh);
1577
1578         if (rt == NULL)
1579                 return (ESRCH);
1580
1581 #ifdef RADIX_MPATH
1582         /*
1583          * If we got multipath routes,
1584          * we require users to specify a matching RTAX_GATEWAY.
1585          */
1586         if (rn_mpath_capable(rnh)) {
1587                 rt = rt_mpath_matchgate(rt, info->rti_info[RTAX_GATEWAY]);
1588                 if (rt == NULL)
1589                         return (ESRCH);
1590         }
1591 #endif
1592
1593         RT_LOCK(rt);
1594
1595         rt_setmetrics(info, rt);
1596
1597         /*
1598          * New gateway could require new ifaddr, ifp;
1599          * flags may also be different; ifp may be specified
1600          * by ll sockaddr when protocol address is ambiguous
1601          */
1602         if (((rt->rt_flags & RTF_GATEWAY) &&
1603             info->rti_info[RTAX_GATEWAY] != NULL) ||
1604             info->rti_info[RTAX_IFP] != NULL ||
1605             (info->rti_info[RTAX_IFA] != NULL &&
1606              !sa_equal(info->rti_info[RTAX_IFA], rt->rt_ifa->ifa_addr))) {
1607
1608                 error = rt_getifa_fib(info, fibnum);
1609                 if (info->rti_ifa != NULL)
1610                         free_ifa = 1;
1611
1612                 if (error != 0)
1613                         goto bad;
1614         }
1615
1616         /* Check if outgoing interface has changed */
1617         if (info->rti_ifa != NULL && info->rti_ifa != rt->rt_ifa &&
1618             rt->rt_ifa != NULL && rt->rt_ifa->ifa_rtrequest != NULL) {
1619                 rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, info);
1620                 ifa_free(rt->rt_ifa);
1621         }
1622         /* Update gateway address */
1623         if (info->rti_info[RTAX_GATEWAY] != NULL) {
1624                 error = rt_setgate(rt, rt_key(rt), info->rti_info[RTAX_GATEWAY]);
1625                 if (error != 0)
1626                         goto bad;
1627
1628                 rt->rt_flags &= ~RTF_GATEWAY;
1629                 rt->rt_flags |= (RTF_GATEWAY & info->rti_flags);
1630         }
1631
1632         if (info->rti_ifa != NULL && info->rti_ifa != rt->rt_ifa) {
1633                 ifa_ref(info->rti_ifa);
1634                 rt->rt_ifa = info->rti_ifa;
1635                 rt->rt_ifp = info->rti_ifp;
1636         }
1637         /* Allow some flags to be toggled on change. */
1638         rt->rt_flags &= ~RTF_FMASK;
1639         rt->rt_flags |= info->rti_flags & RTF_FMASK;
1640
1641         if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest != NULL)
1642                rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info);
1643
1644         /* Alter route MTU if necessary */
1645         if (rt->rt_ifp != NULL) {
1646                 family = info->rti_info[RTAX_DST]->sa_family;
1647                 mtu = if_getmtu_family(rt->rt_ifp, family);
1648                 /* Set default MTU */
1649                 if (rt->rt_mtu == 0)
1650                         rt->rt_mtu = mtu;
1651                 if (rt->rt_mtu != mtu) {
1652                         /* Check if we really need to update */
1653                         ifmtu.ifp = rt->rt_ifp;
1654                         ifmtu.mtu = mtu;
1655                         if_updatemtu_cb(rt->rt_nodes, &ifmtu);
1656                 }
1657         }
1658
1659         if (ret_nrt) {
1660                 *ret_nrt = rt;
1661                 RT_ADDREF(rt);
1662         }
1663 bad:
1664         RT_UNLOCK(rt);
1665         if (free_ifa != 0)
1666                 ifa_free(info->rti_ifa);
1667         return (error);
1668 }
1669
1670 static void
1671 rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt)
1672 {
1673
1674         if (info->rti_mflags & RTV_MTU) {
1675                 if (info->rti_rmx->rmx_mtu != 0) {
1676
1677                         /*
1678                          * MTU was explicitly provided by user.
1679                          * Keep it.
1680                          */
1681                         rt->rt_flags |= RTF_FIXEDMTU;
1682                 } else {
1683
1684                         /*
1685                          * User explicitly sets MTU to 0.
1686                          * Assume rollback to default.
1687                          */
1688                         rt->rt_flags &= ~RTF_FIXEDMTU;
1689                 }
1690                 rt->rt_mtu = info->rti_rmx->rmx_mtu;
1691         }
1692         if (info->rti_mflags & RTV_WEIGHT)
1693                 rt->rt_weight = info->rti_rmx->rmx_weight;
1694         /* Kernel -> userland timebase conversion. */
1695         if (info->rti_mflags & RTV_EXPIRE)
1696                 rt->rt_expire = info->rti_rmx->rmx_expire ?
1697                     info->rti_rmx->rmx_expire - time_second + time_uptime : 0;
1698 }
1699
1700 int
1701 rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate)
1702 {
1703         /* XXX dst may be overwritten, can we move this to below */
1704         int dlen = SA_SIZE(dst), glen = SA_SIZE(gate);
1705 #ifdef INVARIANTS
1706         struct radix_node_head *rnh;
1707
1708         rnh = rt_tables_get_rnh(rt->rt_fibnum, dst->sa_family);
1709 #endif
1710
1711         RT_LOCK_ASSERT(rt);
1712         RADIX_NODE_HEAD_LOCK_ASSERT(rnh);
1713         
1714         /*
1715          * Prepare to store the gateway in rt->rt_gateway.
1716          * Both dst and gateway are stored one after the other in the same
1717          * malloc'd chunk. If we have room, we can reuse the old buffer,
1718          * rt_gateway already points to the right place.
1719          * Otherwise, malloc a new block and update the 'dst' address.
1720          */
1721         if (rt->rt_gateway == NULL || glen > SA_SIZE(rt->rt_gateway)) {
1722                 caddr_t new;
1723
1724                 R_Malloc(new, caddr_t, dlen + glen);
1725                 if (new == NULL)
1726                         return ENOBUFS;
1727                 /*
1728                  * XXX note, we copy from *dst and not *rt_key(rt) because
1729                  * rt_setgate() can be called to initialize a newly
1730                  * allocated route entry, in which case rt_key(rt) == NULL
1731                  * (and also rt->rt_gateway == NULL).
1732                  * Free()/free() handle a NULL argument just fine.
1733                  */
1734                 bcopy(dst, new, dlen);
1735                 R_Free(rt_key(rt));     /* free old block, if any */
1736                 rt_key(rt) = (struct sockaddr *)new;
1737                 rt->rt_gateway = (struct sockaddr *)(new + dlen);
1738         }
1739
1740         /*
1741          * Copy the new gateway value into the memory chunk.
1742          */
1743         bcopy(gate, rt->rt_gateway, glen);
1744
1745         return (0);
1746 }
1747
1748 void
1749 rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
1750 {
1751         u_char *cp1 = (u_char *)src;
1752         u_char *cp2 = (u_char *)dst;
1753         u_char *cp3 = (u_char *)netmask;
1754         u_char *cplim = cp2 + *cp3;
1755         u_char *cplim2 = cp2 + *cp1;
1756
1757         *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */
1758         cp3 += 2;
1759         if (cplim > cplim2)
1760                 cplim = cplim2;
1761         while (cp2 < cplim)
1762                 *cp2++ = *cp1++ & *cp3++;
1763         if (cp2 < cplim2)
1764                 bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));
1765 }
1766
1767 /*
1768  * Set up a routing table entry, normally
1769  * for an interface.
1770  */
1771 #define _SOCKADDR_TMPSIZE 128 /* Not too big.. kernel stack size is limited */
1772 static inline  int
1773 rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum)
1774 {
1775         struct sockaddr *dst;
1776         struct sockaddr *netmask;
1777         struct rtentry *rt = NULL;
1778         struct rt_addrinfo info;
1779         int error = 0;
1780         int startfib, endfib;
1781         char tempbuf[_SOCKADDR_TMPSIZE];
1782         int didwork = 0;
1783         int a_failure = 0;
1784         static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
1785         struct radix_node_head *rnh;
1786
1787         if (flags & RTF_HOST) {
1788                 dst = ifa->ifa_dstaddr;
1789                 netmask = NULL;
1790         } else {
1791                 dst = ifa->ifa_addr;
1792                 netmask = ifa->ifa_netmask;
1793         }
1794         if (dst->sa_len == 0)
1795                 return(EINVAL);
1796         switch (dst->sa_family) {
1797         case AF_INET6:
1798         case AF_INET:
1799                 /* We support multiple FIBs. */
1800                 break;
1801         default:
1802                 fibnum = RT_DEFAULT_FIB;
1803                 break;
1804         }
1805         if (fibnum == RT_ALL_FIBS) {
1806                 if (V_rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD)
1807                         startfib = endfib = ifa->ifa_ifp->if_fib;
1808                 else {
1809                         startfib = 0;
1810                         endfib = rt_numfibs - 1;
1811                 }
1812         } else {
1813                 KASSERT((fibnum < rt_numfibs), ("rtinit1: bad fibnum"));
1814                 startfib = fibnum;
1815                 endfib = fibnum;
1816         }
1817
1818         /*
1819          * If it's a delete, check that if it exists,
1820          * it's on the correct interface or we might scrub
1821          * a route to another ifa which would
1822          * be confusing at best and possibly worse.
1823          */
1824         if (cmd == RTM_DELETE) {
1825                 /*
1826                  * It's a delete, so it should already exist..
1827                  * If it's a net, mask off the host bits
1828                  * (Assuming we have a mask)
1829                  * XXX this is kinda inet specific..
1830                  */
1831                 if (netmask != NULL) {
1832                         rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask);
1833                         dst = (struct sockaddr *)tempbuf;
1834                 }
1835         }
1836         /*
1837          * Now go through all the requested tables (fibs) and do the
1838          * requested action. Realistically, this will either be fib 0
1839          * for protocols that don't do multiple tables or all the
1840          * tables for those that do.
1841          */
1842         for ( fibnum = startfib; fibnum <= endfib; fibnum++) {
1843                 if (cmd == RTM_DELETE) {
1844                         struct radix_node *rn;
1845                         /*
1846                          * Look up an rtentry that is in the routing tree and
1847                          * contains the correct info.
1848                          */
1849                         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
1850                         if (rnh == NULL)
1851                                 /* this table doesn't exist but others might */
1852                                 continue;
1853                         RADIX_NODE_HEAD_RLOCK(rnh);
1854                         rn = rnh->rnh_lookup(dst, netmask, rnh);
1855 #ifdef RADIX_MPATH
1856                         if (rn_mpath_capable(rnh)) {
1857
1858                                 if (rn == NULL) 
1859                                         error = ESRCH;
1860                                 else {
1861                                         rt = RNTORT(rn);
1862                                         /*
1863                                          * for interface route the
1864                                          * rt->rt_gateway is sockaddr_intf
1865                                          * for cloning ARP entries, so
1866                                          * rt_mpath_matchgate must use the
1867                                          * interface address
1868                                          */
1869                                         rt = rt_mpath_matchgate(rt,
1870                                             ifa->ifa_addr);
1871                                         if (rt == NULL) 
1872                                                 error = ESRCH;
1873                                 }
1874                         }
1875 #endif
1876                         error = (rn == NULL ||
1877                             (rn->rn_flags & RNF_ROOT) ||
1878                             RNTORT(rn)->rt_ifa != ifa);
1879                         RADIX_NODE_HEAD_RUNLOCK(rnh);
1880                         if (error) {
1881                                 /* this is only an error if bad on ALL tables */
1882                                 continue;
1883                         }
1884                 }
1885                 /*
1886                  * Do the actual request
1887                  */
1888                 bzero((caddr_t)&info, sizeof(info));
1889                 info.rti_ifa = ifa;
1890                 info.rti_flags = flags |
1891                     (ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED;
1892                 info.rti_info[RTAX_DST] = dst;
1893                 /* 
1894                  * doing this for compatibility reasons
1895                  */
1896                 if (cmd == RTM_ADD)
1897                         info.rti_info[RTAX_GATEWAY] =
1898                             (struct sockaddr *)&null_sdl;
1899                 else
1900                         info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
1901                 info.rti_info[RTAX_NETMASK] = netmask;
1902                 error = rtrequest1_fib(cmd, &info, &rt, fibnum);
1903
1904                 if ((error == EEXIST) && (cmd == RTM_ADD)) {
1905                         /*
1906                          * Interface route addition failed.
1907                          * Atomically delete current prefix generating
1908                          * RTM_DELETE message, and retry adding
1909                          * interface prefix.
1910                          */
1911                         rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
1912                         RADIX_NODE_HEAD_LOCK(rnh);
1913
1914                         /* Delete old prefix */
1915                         info.rti_ifa = NULL;
1916                         info.rti_flags = RTF_RNH_LOCKED;
1917
1918                         error = rtrequest1_fib(RTM_DELETE, &info, NULL, fibnum);
1919                         if (error == 0) {
1920                                 info.rti_ifa = ifa;
1921                                 info.rti_flags = flags | RTF_RNH_LOCKED |
1922                                     (ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED;
1923                                 error = rtrequest1_fib(cmd, &info, &rt, fibnum);
1924                         }
1925
1926                         RADIX_NODE_HEAD_UNLOCK(rnh);
1927                 }
1928
1929
1930                 if (error == 0 && rt != NULL) {
1931                         /*
1932                          * notify any listening routing agents of the change
1933                          */
1934                         RT_LOCK(rt);
1935 #ifdef RADIX_MPATH
1936                         /*
1937                          * in case address alias finds the first address
1938                          * e.g. ifconfig bge0 192.0.2.246/24
1939                          * e.g. ifconfig bge0 192.0.2.247/24
1940                          * the address set in the route is 192.0.2.246
1941                          * so we need to replace it with 192.0.2.247
1942                          */
1943                         if (memcmp(rt->rt_ifa->ifa_addr,
1944                             ifa->ifa_addr, ifa->ifa_addr->sa_len)) {
1945                                 ifa_free(rt->rt_ifa);
1946                                 ifa_ref(ifa);
1947                                 rt->rt_ifp = ifa->ifa_ifp;
1948                                 rt->rt_ifa = ifa;
1949                         }
1950 #endif
1951                         /* 
1952                          * doing this for compatibility reasons
1953                          */
1954                         if (cmd == RTM_ADD) {
1955                             ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
1956                                 rt->rt_ifp->if_type;
1957                             ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
1958                                 rt->rt_ifp->if_index;
1959                         }
1960                         RT_ADDREF(rt);
1961                         RT_UNLOCK(rt);
1962                         rt_newaddrmsg_fib(cmd, ifa, error, rt, fibnum);
1963                         RT_LOCK(rt);
1964                         RT_REMREF(rt);
1965                         if (cmd == RTM_DELETE) {
1966                                 /*
1967                                  * If we are deleting, and we found an entry,
1968                                  * then it's been removed from the tree..
1969                                  * now throw it away.
1970                                  */
1971                                 RTFREE_LOCKED(rt);
1972                         } else {
1973                                 if (cmd == RTM_ADD) {
1974                                         /*
1975                                          * We just wanted to add it..
1976                                          * we don't actually need a reference.
1977                                          */
1978                                         RT_REMREF(rt);
1979                                 }
1980                                 RT_UNLOCK(rt);
1981                         }
1982                         didwork = 1;
1983                 }
1984                 if (error)
1985                         a_failure = error;
1986         }
1987         if (cmd == RTM_DELETE) {
1988                 if (didwork) {
1989                         error = 0;
1990                 } else {
1991                         /* we only give an error if it wasn't in any table */
1992                         error = ((flags & RTF_HOST) ?
1993                             EHOSTUNREACH : ENETUNREACH);
1994                 }
1995         } else {
1996                 if (a_failure) {
1997                         /* return an error if any of them failed */
1998                         error = a_failure;
1999                 }
2000         }
2001         return (error);
2002 }
2003
2004 /*
2005  * Set up a routing table entry, normally
2006  * for an interface.
2007  */
2008 int
2009 rtinit(struct ifaddr *ifa, int cmd, int flags)
2010 {
2011         struct sockaddr *dst;
2012         int fib = RT_DEFAULT_FIB;
2013
2014         if (flags & RTF_HOST) {
2015                 dst = ifa->ifa_dstaddr;
2016         } else {
2017                 dst = ifa->ifa_addr;
2018         }
2019
2020         switch (dst->sa_family) {
2021         case AF_INET6:
2022         case AF_INET:
2023                 /* We do support multiple FIBs. */
2024                 fib = RT_ALL_FIBS;
2025                 break;
2026         }
2027         return (rtinit1(ifa, cmd, flags, fib));
2028 }
2029
2030 /*
2031  * Announce interface address arrival/withdraw
2032  * Returns 0 on success.
2033  */
2034 int
2035 rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
2036 {
2037
2038         KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
2039             ("unexpected cmd %d", cmd));
2040         
2041         KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
2042             ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
2043
2044 #if defined(INET) || defined(INET6)
2045 #ifdef SCTP
2046         /*
2047          * notify the SCTP stack
2048          * this will only get called when an address is added/deleted
2049          * XXX pass the ifaddr struct instead if ifa->ifa_addr...
2050          */
2051         sctp_addr_change(ifa, cmd);
2052 #endif /* SCTP */
2053 #endif
2054         return (rtsock_addrmsg(cmd, ifa, fibnum));
2055 }
2056
2057 /*
2058  * Announce route addition/removal.
2059  * Users of this function MUST validate input data BEFORE calling.
2060  * However we have to be able to handle invalid data:
2061  * if some userland app sends us "invalid" route message (invalid mask,
2062  * no dst, wrong address families, etc...) we need to pass it back
2063  * to app (and any other rtsock consumers) with rtm_errno field set to
2064  * non-zero value.
2065  * Returns 0 on success.
2066  */
2067 int
2068 rt_routemsg(int cmd, struct ifnet *ifp, int error, struct rtentry *rt,
2069     int fibnum)
2070 {
2071
2072         KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
2073             ("unexpected cmd %d", cmd));
2074         
2075         KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
2076             ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
2077
2078         KASSERT(rt_key(rt) != NULL, (":%s: rt_key must be supplied", __func__));
2079
2080         return (rtsock_routemsg(cmd, ifp, error, rt, fibnum));
2081 }
2082
2083 void
2084 rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
2085 {
2086
2087         rt_newaddrmsg_fib(cmd, ifa, error, rt, RT_ALL_FIBS);
2088 }
2089
2090 /*
2091  * This is called to generate messages from the routing socket
2092  * indicating a network interface has had addresses associated with it.
2093  */
2094 void
2095 rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt,
2096     int fibnum)
2097 {
2098
2099         KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE,
2100                 ("unexpected cmd %u", cmd));
2101         KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs),
2102             ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs));
2103
2104         if (cmd == RTM_ADD) {
2105                 rt_addrmsg(cmd, ifa, fibnum);
2106                 if (rt != NULL)
2107                         rt_routemsg(cmd, ifa->ifa_ifp, error, rt, fibnum);
2108         } else {
2109                 if (rt != NULL)
2110                         rt_routemsg(cmd, ifa->ifa_ifp, error, rt, fibnum);
2111                 rt_addrmsg(cmd, ifa, fibnum);
2112         }
2113 }
2114