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