]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/rtsock.c
Fix dst/netmask handling in routing socket code.
[FreeBSD/FreeBSD.git] / sys / net / rtsock.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1988, 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  *      @(#)rtsock.c    8.7 (Berkeley) 10/12/95
32  * $FreeBSD$
33  */
34 #include "opt_ddb.h"
35 #include "opt_route.h"
36 #include "opt_inet.h"
37 #include "opt_inet6.h"
38
39 #include <sys/param.h>
40 #include <sys/jail.h>
41 #include <sys/kernel.h>
42 #include <sys/domain.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/priv.h>
47 #include <sys/proc.h>
48 #include <sys/protosw.h>
49 #include <sys/rmlock.h>
50 #include <sys/rwlock.h>
51 #include <sys/signalvar.h>
52 #include <sys/socket.h>
53 #include <sys/socketvar.h>
54 #include <sys/sysctl.h>
55 #include <sys/systm.h>
56
57 #include <net/if.h>
58 #include <net/if_var.h>
59 #include <net/if_dl.h>
60 #include <net/if_llatbl.h>
61 #include <net/if_types.h>
62 #include <net/netisr.h>
63 #include <net/raw_cb.h>
64 #include <net/route.h>
65 #include <net/route/route_ctl.h>
66 #include <net/route/route_var.h>
67 #include <net/vnet.h>
68
69 #include <netinet/in.h>
70 #include <netinet/if_ether.h>
71 #include <netinet/ip_carp.h>
72 #ifdef INET6
73 #include <netinet6/in6_var.h>
74 #include <netinet6/ip6_var.h>
75 #include <netinet6/scope6_var.h>
76 #endif
77 #include <net/route/nhop.h>
78
79 #ifdef COMPAT_FREEBSD32
80 #include <sys/mount.h>
81 #include <compat/freebsd32/freebsd32.h>
82
83 struct if_msghdr32 {
84         uint16_t ifm_msglen;
85         uint8_t ifm_version;
86         uint8_t ifm_type;
87         int32_t ifm_addrs;
88         int32_t ifm_flags;
89         uint16_t ifm_index;
90         uint16_t _ifm_spare1;
91         struct  if_data ifm_data;
92 };
93
94 struct if_msghdrl32 {
95         uint16_t ifm_msglen;
96         uint8_t ifm_version;
97         uint8_t ifm_type;
98         int32_t ifm_addrs;
99         int32_t ifm_flags;
100         uint16_t ifm_index;
101         uint16_t _ifm_spare1;
102         uint16_t ifm_len;
103         uint16_t ifm_data_off;
104         uint32_t _ifm_spare2;
105         struct  if_data ifm_data;
106 };
107
108 struct ifa_msghdrl32 {
109         uint16_t ifam_msglen;
110         uint8_t ifam_version;
111         uint8_t ifam_type;
112         int32_t ifam_addrs;
113         int32_t ifam_flags;
114         uint16_t ifam_index;
115         uint16_t _ifam_spare1;
116         uint16_t ifam_len;
117         uint16_t ifam_data_off;
118         int32_t ifam_metric;
119         struct  if_data ifam_data;
120 };
121
122 #define SA_SIZE32(sa)                                           \
123     (  (((struct sockaddr *)(sa))->sa_len == 0) ?               \
124         sizeof(int)             :                               \
125         1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(int) - 1) ) )
126
127 #endif /* COMPAT_FREEBSD32 */
128
129 MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
130
131 /* NB: these are not modified */
132 static struct   sockaddr route_src = { 2, PF_ROUTE, };
133 static struct   sockaddr sa_zero   = { sizeof(sa_zero), AF_INET, };
134
135 /* These are external hooks for CARP. */
136 int     (*carp_get_vhid_p)(struct ifaddr *);
137
138 /*
139  * Used by rtsock/raw_input callback code to decide whether to filter the update
140  * notification to a socket bound to a particular FIB.
141  */
142 #define RTS_FILTER_FIB  M_PROTO8
143
144 typedef struct {
145         int     ip_count;       /* attached w/ AF_INET */
146         int     ip6_count;      /* attached w/ AF_INET6 */
147         int     any_count;      /* total attached */
148 } route_cb_t;
149 VNET_DEFINE_STATIC(route_cb_t, route_cb);
150 #define V_route_cb VNET(route_cb)
151
152 struct mtx rtsock_mtx;
153 MTX_SYSINIT(rtsock, &rtsock_mtx, "rtsock route_cb lock", MTX_DEF);
154
155 #define RTSOCK_LOCK()   mtx_lock(&rtsock_mtx)
156 #define RTSOCK_UNLOCK() mtx_unlock(&rtsock_mtx)
157 #define RTSOCK_LOCK_ASSERT()    mtx_assert(&rtsock_mtx, MA_OWNED)
158
159 SYSCTL_NODE(_net, OID_AUTO, route, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
160
161 struct walkarg {
162         int     family;
163         int     w_tmemsize;
164         int     w_op, w_arg;
165         caddr_t w_tmem;
166         struct sysctl_req *w_req;
167         struct sockaddr *dst;
168         struct sockaddr *mask;
169 };
170
171 static void     rts_input(struct mbuf *m);
172 static struct mbuf *rtsock_msg_mbuf(int type, struct rt_addrinfo *rtinfo);
173 static int      rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo,
174                         struct walkarg *w, int *plen);
175 static int      rt_xaddrs(caddr_t cp, caddr_t cplim,
176                         struct rt_addrinfo *rtinfo);
177 static int      cleanup_xaddrs(struct rt_addrinfo *info);
178 static int      sysctl_dumpentry(struct rtentry *rt, void *vw);
179 static int      sysctl_dumpnhop(struct rtentry *rt, struct nhop_object *nh,
180                         uint32_t weight, struct walkarg *w);
181 static int      sysctl_iflist(int af, struct walkarg *w);
182 static int      sysctl_ifmalist(int af, struct walkarg *w);
183 static int      route_output(struct mbuf *m, struct socket *so, ...);
184 static void     rt_getmetrics(const struct rtentry *rt,
185                         const struct nhop_object *nh, struct rt_metrics *out);
186 static void     rt_dispatch(struct mbuf *, sa_family_t);
187 static int      handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
188                         struct rt_msghdr *rtm, struct rib_cmd_info *rc);
189 static int      update_rtm_from_rc(struct rt_addrinfo *info,
190                         struct rt_msghdr **prtm, int alloc_len,
191                         struct rib_cmd_info *rc, struct nhop_object *nh);
192 static void     send_rtm_reply(struct socket *so, struct rt_msghdr *rtm,
193                         struct mbuf *m, sa_family_t saf, u_int fibnum,
194                         int rtm_errno);
195 static bool     can_export_rte(struct ucred *td_ucred, bool rt_is_host,
196                         const struct sockaddr *rt_dst);
197
198 static struct netisr_handler rtsock_nh = {
199         .nh_name = "rtsock",
200         .nh_handler = rts_input,
201         .nh_proto = NETISR_ROUTE,
202         .nh_policy = NETISR_POLICY_SOURCE,
203 };
204
205 static int
206 sysctl_route_netisr_maxqlen(SYSCTL_HANDLER_ARGS)
207 {
208         int error, qlimit;
209
210         netisr_getqlimit(&rtsock_nh, &qlimit);
211         error = sysctl_handle_int(oidp, &qlimit, 0, req);
212         if (error || !req->newptr)
213                 return (error);
214         if (qlimit < 1)
215                 return (EINVAL);
216         return (netisr_setqlimit(&rtsock_nh, qlimit));
217 }
218 SYSCTL_PROC(_net_route, OID_AUTO, netisr_maxqlen,
219     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
220     0, 0, sysctl_route_netisr_maxqlen, "I",
221     "maximum routing socket dispatch queue length");
222
223 static void
224 vnet_rts_init(void)
225 {
226         int tmp;
227
228         if (IS_DEFAULT_VNET(curvnet)) {
229                 if (TUNABLE_INT_FETCH("net.route.netisr_maxqlen", &tmp))
230                         rtsock_nh.nh_qlimit = tmp;
231                 netisr_register(&rtsock_nh);
232         }
233 #ifdef VIMAGE
234          else
235                 netisr_register_vnet(&rtsock_nh);
236 #endif
237 }
238 VNET_SYSINIT(vnet_rtsock, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
239     vnet_rts_init, 0);
240
241 #ifdef VIMAGE
242 static void
243 vnet_rts_uninit(void)
244 {
245
246         netisr_unregister_vnet(&rtsock_nh);
247 }
248 VNET_SYSUNINIT(vnet_rts_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
249     vnet_rts_uninit, 0);
250 #endif
251
252 static int
253 raw_input_rts_cb(struct mbuf *m, struct sockproto *proto, struct sockaddr *src,
254     struct rawcb *rp)
255 {
256         int fibnum;
257
258         KASSERT(m != NULL, ("%s: m is NULL", __func__));
259         KASSERT(proto != NULL, ("%s: proto is NULL", __func__));
260         KASSERT(rp != NULL, ("%s: rp is NULL", __func__));
261
262         /* No filtering requested. */
263         if ((m->m_flags & RTS_FILTER_FIB) == 0)
264                 return (0);
265
266         /* Check if it is a rts and the fib matches the one of the socket. */
267         fibnum = M_GETFIB(m);
268         if (proto->sp_family != PF_ROUTE ||
269             rp->rcb_socket == NULL ||
270             rp->rcb_socket->so_fibnum == fibnum)
271                 return (0);
272
273         /* Filtering requested and no match, the socket shall be skipped. */
274         return (1);
275 }
276
277 static void
278 rts_input(struct mbuf *m)
279 {
280         struct sockproto route_proto;
281         unsigned short *family;
282         struct m_tag *tag;
283
284         route_proto.sp_family = PF_ROUTE;
285         tag = m_tag_find(m, PACKET_TAG_RTSOCKFAM, NULL);
286         if (tag != NULL) {
287                 family = (unsigned short *)(tag + 1);
288                 route_proto.sp_protocol = *family;
289                 m_tag_delete(m, tag);
290         } else
291                 route_proto.sp_protocol = 0;
292
293         raw_input_ext(m, &route_proto, &route_src, raw_input_rts_cb);
294 }
295
296 /*
297  * It really doesn't make any sense at all for this code to share much
298  * with raw_usrreq.c, since its functionality is so restricted.  XXX
299  */
300 static void
301 rts_abort(struct socket *so)
302 {
303
304         raw_usrreqs.pru_abort(so);
305 }
306
307 static void
308 rts_close(struct socket *so)
309 {
310
311         raw_usrreqs.pru_close(so);
312 }
313
314 /* pru_accept is EOPNOTSUPP */
315
316 static int
317 rts_attach(struct socket *so, int proto, struct thread *td)
318 {
319         struct rawcb *rp;
320         int error;
321
322         KASSERT(so->so_pcb == NULL, ("rts_attach: so_pcb != NULL"));
323
324         /* XXX */
325         rp = malloc(sizeof *rp, M_PCB, M_WAITOK | M_ZERO);
326
327         so->so_pcb = (caddr_t)rp;
328         so->so_fibnum = td->td_proc->p_fibnum;
329         error = raw_attach(so, proto);
330         rp = sotorawcb(so);
331         if (error) {
332                 so->so_pcb = NULL;
333                 free(rp, M_PCB);
334                 return error;
335         }
336         RTSOCK_LOCK();
337         switch(rp->rcb_proto.sp_protocol) {
338         case AF_INET:
339                 V_route_cb.ip_count++;
340                 break;
341         case AF_INET6:
342                 V_route_cb.ip6_count++;
343                 break;
344         }
345         V_route_cb.any_count++;
346         RTSOCK_UNLOCK();
347         soisconnected(so);
348         so->so_options |= SO_USELOOPBACK;
349         return 0;
350 }
351
352 static int
353 rts_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
354 {
355
356         return (raw_usrreqs.pru_bind(so, nam, td)); /* xxx just EINVAL */
357 }
358
359 static int
360 rts_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
361 {
362
363         return (raw_usrreqs.pru_connect(so, nam, td)); /* XXX just EINVAL */
364 }
365
366 /* pru_connect2 is EOPNOTSUPP */
367 /* pru_control is EOPNOTSUPP */
368
369 static void
370 rts_detach(struct socket *so)
371 {
372         struct rawcb *rp = sotorawcb(so);
373
374         KASSERT(rp != NULL, ("rts_detach: rp == NULL"));
375
376         RTSOCK_LOCK();
377         switch(rp->rcb_proto.sp_protocol) {
378         case AF_INET:
379                 V_route_cb.ip_count--;
380                 break;
381         case AF_INET6:
382                 V_route_cb.ip6_count--;
383                 break;
384         }
385         V_route_cb.any_count--;
386         RTSOCK_UNLOCK();
387         raw_usrreqs.pru_detach(so);
388 }
389
390 static int
391 rts_disconnect(struct socket *so)
392 {
393
394         return (raw_usrreqs.pru_disconnect(so));
395 }
396
397 /* pru_listen is EOPNOTSUPP */
398
399 static int
400 rts_peeraddr(struct socket *so, struct sockaddr **nam)
401 {
402
403         return (raw_usrreqs.pru_peeraddr(so, nam));
404 }
405
406 /* pru_rcvd is EOPNOTSUPP */
407 /* pru_rcvoob is EOPNOTSUPP */
408
409 static int
410 rts_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
411          struct mbuf *control, struct thread *td)
412 {
413
414         return (raw_usrreqs.pru_send(so, flags, m, nam, control, td));
415 }
416
417 /* pru_sense is null */
418
419 static int
420 rts_shutdown(struct socket *so)
421 {
422
423         return (raw_usrreqs.pru_shutdown(so));
424 }
425
426 static int
427 rts_sockaddr(struct socket *so, struct sockaddr **nam)
428 {
429
430         return (raw_usrreqs.pru_sockaddr(so, nam));
431 }
432
433 static struct pr_usrreqs route_usrreqs = {
434         .pru_abort =            rts_abort,
435         .pru_attach =           rts_attach,
436         .pru_bind =             rts_bind,
437         .pru_connect =          rts_connect,
438         .pru_detach =           rts_detach,
439         .pru_disconnect =       rts_disconnect,
440         .pru_peeraddr =         rts_peeraddr,
441         .pru_send =             rts_send,
442         .pru_shutdown =         rts_shutdown,
443         .pru_sockaddr =         rts_sockaddr,
444         .pru_close =            rts_close,
445 };
446
447 #ifndef _SOCKADDR_UNION_DEFINED
448 #define _SOCKADDR_UNION_DEFINED
449 /*
450  * The union of all possible address formats we handle.
451  */
452 union sockaddr_union {
453         struct sockaddr         sa;
454         struct sockaddr_in      sin;
455         struct sockaddr_in6     sin6;
456 };
457 #endif /* _SOCKADDR_UNION_DEFINED */
458
459 static int
460 rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
461     struct nhop_object *nh, union sockaddr_union *saun, struct ucred *cred)
462 {
463 #if defined(INET) || defined(INET6)
464         struct epoch_tracker et;
465 #endif
466
467         /* First, see if the returned address is part of the jail. */
468         if (prison_if(cred, nh->nh_ifa->ifa_addr) == 0) {
469                 info->rti_info[RTAX_IFA] = nh->nh_ifa->ifa_addr;
470                 return (0);
471         }
472
473         switch (info->rti_info[RTAX_DST]->sa_family) {
474 #ifdef INET
475         case AF_INET:
476         {
477                 struct in_addr ia;
478                 struct ifaddr *ifa;
479                 int found;
480
481                 found = 0;
482                 /*
483                  * Try to find an address on the given outgoing interface
484                  * that belongs to the jail.
485                  */
486                 NET_EPOCH_ENTER(et);
487                 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
488                         struct sockaddr *sa;
489                         sa = ifa->ifa_addr;
490                         if (sa->sa_family != AF_INET)
491                                 continue;
492                         ia = ((struct sockaddr_in *)sa)->sin_addr;
493                         if (prison_check_ip4(cred, &ia) == 0) {
494                                 found = 1;
495                                 break;
496                         }
497                 }
498                 NET_EPOCH_EXIT(et);
499                 if (!found) {
500                         /*
501                          * As a last resort return the 'default' jail address.
502                          */
503                         ia = ((struct sockaddr_in *)nh->nh_ifa->ifa_addr)->
504                             sin_addr;
505                         if (prison_get_ip4(cred, &ia) != 0)
506                                 return (ESRCH);
507                 }
508                 bzero(&saun->sin, sizeof(struct sockaddr_in));
509                 saun->sin.sin_len = sizeof(struct sockaddr_in);
510                 saun->sin.sin_family = AF_INET;
511                 saun->sin.sin_addr.s_addr = ia.s_addr;
512                 info->rti_info[RTAX_IFA] = (struct sockaddr *)&saun->sin;
513                 break;
514         }
515 #endif
516 #ifdef INET6
517         case AF_INET6:
518         {
519                 struct in6_addr ia6;
520                 struct ifaddr *ifa;
521                 int found;
522
523                 found = 0;
524                 /*
525                  * Try to find an address on the given outgoing interface
526                  * that belongs to the jail.
527                  */
528                 NET_EPOCH_ENTER(et);
529                 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
530                         struct sockaddr *sa;
531                         sa = ifa->ifa_addr;
532                         if (sa->sa_family != AF_INET6)
533                                 continue;
534                         bcopy(&((struct sockaddr_in6 *)sa)->sin6_addr,
535                             &ia6, sizeof(struct in6_addr));
536                         if (prison_check_ip6(cred, &ia6) == 0) {
537                                 found = 1;
538                                 break;
539                         }
540                 }
541                 NET_EPOCH_EXIT(et);
542                 if (!found) {
543                         /*
544                          * As a last resort return the 'default' jail address.
545                          */
546                         ia6 = ((struct sockaddr_in6 *)nh->nh_ifa->ifa_addr)->
547                             sin6_addr;
548                         if (prison_get_ip6(cred, &ia6) != 0)
549                                 return (ESRCH);
550                 }
551                 bzero(&saun->sin6, sizeof(struct sockaddr_in6));
552                 saun->sin6.sin6_len = sizeof(struct sockaddr_in6);
553                 saun->sin6.sin6_family = AF_INET6;
554                 bcopy(&ia6, &saun->sin6.sin6_addr, sizeof(struct in6_addr));
555                 if (sa6_recoverscope(&saun->sin6) != 0)
556                         return (ESRCH);
557                 info->rti_info[RTAX_IFA] = (struct sockaddr *)&saun->sin6;
558                 break;
559         }
560 #endif
561         default:
562                 return (ESRCH);
563         }
564         return (0);
565 }
566
567 /*
568  * Fills in @info based on userland-provided @rtm message.
569  *
570  * Returns 0 on success.
571  */
572 static int
573 fill_addrinfo(struct rt_msghdr *rtm, int len, u_int fibnum, struct rt_addrinfo *info)
574 {
575         int error;
576         sa_family_t saf;
577
578         rtm->rtm_pid = curproc->p_pid;
579         info->rti_addrs = rtm->rtm_addrs;
580
581         info->rti_mflags = rtm->rtm_inits;
582         info->rti_rmx = &rtm->rtm_rmx;
583
584         /*
585          * rt_xaddrs() performs s6_addr[2] := sin6_scope_id for AF_INET6
586          * link-local address because rtrequest requires addresses with
587          * embedded scope id.
588          */
589         if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, info))
590                 return (EINVAL);
591
592         if (rtm->rtm_flags & RTF_RNH_LOCKED)
593                 return (EINVAL);
594         info->rti_flags = rtm->rtm_flags;
595         error = cleanup_xaddrs(info);
596         if (error != 0)
597                 return (error);
598         saf = info->rti_info[RTAX_DST]->sa_family;
599         /*
600          * Verify that the caller has the appropriate privilege; RTM_GET
601          * is the only operation the non-superuser is allowed.
602          */
603         if (rtm->rtm_type != RTM_GET) {
604                 error = priv_check(curthread, PRIV_NET_ROUTE);
605                 if (error != 0)
606                         return (error);
607         }
608
609         /*
610          * The given gateway address may be an interface address.
611          * For example, issuing a "route change" command on a route
612          * entry that was created from a tunnel, and the gateway
613          * address given is the local end point. In this case the 
614          * RTF_GATEWAY flag must be cleared or the destination will
615          * not be reachable even though there is no error message.
616          */
617         if (info->rti_info[RTAX_GATEWAY] != NULL &&
618             info->rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) {
619                 struct rt_addrinfo ginfo;
620                 struct sockaddr *gdst;
621                 struct sockaddr_storage ss;
622
623                 bzero(&ginfo, sizeof(ginfo));
624                 bzero(&ss, sizeof(ss));
625                 ss.ss_len = sizeof(ss);
626
627                 ginfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&ss;
628                 gdst = info->rti_info[RTAX_GATEWAY];
629
630                 /* 
631                  * A host route through the loopback interface is 
632                  * installed for each interface adddress. In pre 8.0
633                  * releases the interface address of a PPP link type
634                  * is not reachable locally. This behavior is fixed as 
635                  * part of the new L2/L3 redesign and rewrite work. The
636                  * signature of this interface address route is the
637                  * AF_LINK sa_family type of the gateway, and the
638                  * rt_ifp has the IFF_LOOPBACK flag set.
639                  */
640                 if (rib_lookup_info(fibnum, gdst, NHR_REF, 0, &ginfo) == 0) {
641                         if (ss.ss_family == AF_LINK &&
642                             ginfo.rti_ifp->if_flags & IFF_LOOPBACK) {
643                                 info->rti_flags &= ~RTF_GATEWAY;
644                                 info->rti_flags |= RTF_GWFLAG_COMPAT;
645                         }
646                         rib_free_info(&ginfo);
647                 }
648         }
649
650         return (0);
651 }
652
653 static struct nhop_object *
654 select_nhop(struct nhop_object *nh, const struct sockaddr *gw)
655 {
656         if (!NH_IS_NHGRP(nh))
657                 return (nh);
658 #ifdef ROUTE_MPATH
659         struct weightened_nhop *wn;
660         uint32_t num_nhops;
661         wn = nhgrp_get_nhops((struct nhgrp_object *)nh, &num_nhops);
662         if (gw == NULL)
663                 return (wn[0].nh);
664         for (int i = 0; i < num_nhops; i++) {
665                 if (match_nhop_gw(wn[i].nh, gw))
666                         return (wn[i].nh);
667         }
668 #endif
669         return (NULL);
670 }
671
672 /*
673  * Handles RTM_GET message from routing socket, returning matching rt.
674  *
675  * Returns:
676  * 0 on success, with locked and referenced matching rt in @rt_nrt
677  * errno of failure
678  */
679 static int
680 handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
681     struct rt_msghdr *rtm, struct rib_cmd_info *rc)
682 {
683         RIB_RLOCK_TRACKER;
684         struct rib_head *rnh;
685         struct nhop_object *nh;
686         sa_family_t saf;
687
688         saf = info->rti_info[RTAX_DST]->sa_family;
689
690         rnh = rt_tables_get_rnh(fibnum, saf);
691         if (rnh == NULL)
692                 return (EAFNOSUPPORT);
693
694         RIB_RLOCK(rnh);
695
696         /*
697          * By (implicit) convention host route (one without netmask)
698          * means longest-prefix-match request and the route with netmask
699          * means exact-match lookup.
700          * As cleanup_xaddrs() cleans up info flags&addrs for the /32,/128
701          * prefixes, use original data to check for the netmask presence.
702          */
703         if ((rtm->rtm_addrs & RTA_NETMASK) == 0) {
704                 /*
705                  * Provide longest prefix match for
706                  * address lookup (no mask).
707                  * 'route -n get addr'
708                  */
709                 rc->rc_rt = (struct rtentry *) rnh->rnh_matchaddr(
710                     info->rti_info[RTAX_DST], &rnh->head);
711         } else
712                 rc->rc_rt = (struct rtentry *) rnh->rnh_lookup(
713                     info->rti_info[RTAX_DST],
714                     info->rti_info[RTAX_NETMASK], &rnh->head);
715
716         if (rc->rc_rt == NULL) {
717                 RIB_RUNLOCK(rnh);
718                 return (ESRCH);
719         }
720
721         nh = select_nhop(rt_get_raw_nhop(rc->rc_rt), info->rti_info[RTAX_GATEWAY]);
722         if (nh == NULL) {
723                 RIB_RUNLOCK(rnh);
724                 return (ESRCH);
725         }
726         /*
727          * If performing proxied L2 entry insertion, and
728          * the actual PPP host entry is found, perform
729          * another search to retrieve the prefix route of
730          * the local end point of the PPP link.
731          * TODO: move this logic to userland.
732          */
733         if (rtm->rtm_flags & RTF_ANNOUNCE) {
734                 struct sockaddr laddr;
735
736                 if (nh->nh_ifp != NULL &&
737                     nh->nh_ifp->if_type == IFT_PROPVIRTUAL) {
738                         struct ifaddr *ifa;
739
740                         ifa = ifa_ifwithnet(info->rti_info[RTAX_DST], 1,
741                                         RT_ALL_FIBS);
742                         if (ifa != NULL)
743                                 rt_maskedcopy(ifa->ifa_addr,
744                                               &laddr,
745                                               ifa->ifa_netmask);
746                 } else
747                         rt_maskedcopy(nh->nh_ifa->ifa_addr,
748                                       &laddr,
749                                       nh->nh_ifa->ifa_netmask);
750                 /* 
751                  * refactor rt and no lock operation necessary
752                  */
753                 rc->rc_rt = (struct rtentry *)rnh->rnh_matchaddr(&laddr,
754                     &rnh->head);
755                 if (rc->rc_rt == NULL) {
756                         RIB_RUNLOCK(rnh);
757                         return (ESRCH);
758                 }
759                 nh = select_nhop(rt_get_raw_nhop(rc->rc_rt), info->rti_info[RTAX_GATEWAY]);
760                 if (nh == NULL) {
761                         RIB_RUNLOCK(rnh);
762                         return (ESRCH);
763                 }
764         }
765         rc->rc_nh_new = nh;
766         rc->rc_nh_weight = rc->rc_rt->rt_weight;
767         RIB_RUNLOCK(rnh);
768
769         return (0);
770 }
771
772 static void
773 init_sockaddrs_family(int family, struct sockaddr *dst, struct sockaddr *mask)
774 {
775 #ifdef INET
776         if (family == AF_INET) {
777                 struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
778                 struct sockaddr_in *mask4 = (struct sockaddr_in *)mask;
779
780                 bzero(dst4, sizeof(struct sockaddr_in));
781                 bzero(mask4, sizeof(struct sockaddr_in));
782
783                 dst4->sin_family = AF_INET;
784                 dst4->sin_len = sizeof(struct sockaddr_in);
785                 mask4->sin_family = AF_INET;
786                 mask4->sin_len = sizeof(struct sockaddr_in);
787         }
788 #endif
789 #ifdef INET6
790         if (family == AF_INET6) {
791                 struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
792                 struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *)mask;
793
794                 bzero(dst6, sizeof(struct sockaddr_in6));
795                 bzero(mask6, sizeof(struct sockaddr_in6));
796
797                 dst6->sin6_family = AF_INET6;
798                 dst6->sin6_len = sizeof(struct sockaddr_in6);
799                 mask6->sin6_family = AF_INET6;
800                 mask6->sin6_len = sizeof(struct sockaddr_in6);
801         }
802 #endif
803 }
804
805 static void
806 export_rtaddrs(const struct rtentry *rt, struct sockaddr *dst,
807     struct sockaddr *mask)
808 {
809 #ifdef INET
810         if (dst->sa_family == AF_INET) {
811                 struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
812                 struct sockaddr_in *mask4 = (struct sockaddr_in *)mask;
813                 uint32_t scopeid = 0;
814                 rt_get_inet_prefix_pmask(rt, &dst4->sin_addr, &mask4->sin_addr,
815                     &scopeid);
816                 return;
817         }
818 #endif
819 #ifdef INET6
820         if (dst->sa_family == AF_INET6) {
821                 struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
822                 struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *)mask;
823                 uint32_t scopeid = 0;
824                 rt_get_inet6_prefix_pmask(rt, &dst6->sin6_addr,
825                     &mask6->sin6_addr, &scopeid);
826                 dst6->sin6_scope_id = scopeid;
827                 return;
828         }
829 #endif
830 }
831
832
833 /*
834  * Update sockaddrs, flags, etc in @prtm based on @rc data.
835  * rtm can be reallocated.
836  *
837  * Returns 0 on success, along with pointer to (potentially reallocated)
838  *  rtm.
839  *
840  */
841 static int
842 update_rtm_from_rc(struct rt_addrinfo *info, struct rt_msghdr **prtm,
843     int alloc_len, struct rib_cmd_info *rc, struct nhop_object *nh)
844 {
845         struct walkarg w;
846         union sockaddr_union saun;
847         struct rt_msghdr *rtm, *orig_rtm = NULL;
848         struct ifnet *ifp;
849         int error, len;
850
851         rtm = *prtm;
852         union sockaddr_union sa_dst, sa_mask;
853         int family = info->rti_info[RTAX_DST]->sa_family;
854         init_sockaddrs_family(family, &sa_dst.sa, &sa_mask.sa);
855         export_rtaddrs(rc->rc_rt, &sa_dst.sa, &sa_mask.sa);
856
857         info->rti_info[RTAX_DST] = &sa_dst.sa;
858         info->rti_info[RTAX_NETMASK] = rt_is_host(rc->rc_rt) ? NULL : &sa_mask.sa;
859         info->rti_info[RTAX_GATEWAY] = &nh->gw_sa;
860         info->rti_info[RTAX_GENMASK] = 0;
861         ifp = nh->nh_ifp;
862         if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
863                 if (ifp) {
864                         info->rti_info[RTAX_IFP] =
865                             ifp->if_addr->ifa_addr;
866                         error = rtm_get_jailed(info, ifp, nh,
867                             &saun, curthread->td_ucred);
868                         if (error != 0)
869                                 return (error);
870                         if (ifp->if_flags & IFF_POINTOPOINT)
871                                 info->rti_info[RTAX_BRD] =
872                                     nh->nh_ifa->ifa_dstaddr;
873                         rtm->rtm_index = ifp->if_index;
874                 } else {
875                         info->rti_info[RTAX_IFP] = NULL;
876                         info->rti_info[RTAX_IFA] = NULL;
877                 }
878         } else if (ifp != NULL)
879                 rtm->rtm_index = ifp->if_index;
880
881         /* Check if we need to realloc storage */
882         rtsock_msg_buffer(rtm->rtm_type, info, NULL, &len);
883         if (len > alloc_len) {
884                 struct rt_msghdr *tmp_rtm;
885
886                 tmp_rtm = malloc(len, M_TEMP, M_NOWAIT);
887                 if (tmp_rtm == NULL)
888                         return (ENOBUFS);
889                 bcopy(rtm, tmp_rtm, rtm->rtm_msglen);
890                 orig_rtm = rtm;
891                 rtm = tmp_rtm;
892                 alloc_len = len;
893
894                 /*
895                  * Delay freeing original rtm as info contains
896                  * data referencing it.
897                  */
898         }
899
900         w.w_tmem = (caddr_t)rtm;
901         w.w_tmemsize = alloc_len;
902         rtsock_msg_buffer(rtm->rtm_type, info, &w, &len);
903
904         rtm->rtm_flags = rc->rc_rt->rte_flags | nhop_get_rtflags(nh);
905         if (rtm->rtm_flags & RTF_GWFLAG_COMPAT)
906                 rtm->rtm_flags = RTF_GATEWAY | 
907                         (rtm->rtm_flags & ~RTF_GWFLAG_COMPAT);
908         rt_getmetrics(rc->rc_rt, nh, &rtm->rtm_rmx);
909         rtm->rtm_rmx.rmx_weight = rc->rc_nh_weight;
910         rtm->rtm_addrs = info->rti_addrs;
911
912         if (orig_rtm != NULL)
913                 free(orig_rtm, M_TEMP);
914         *prtm = rtm;
915
916         return (0);
917 }
918
919 #ifdef ROUTE_MPATH
920 static void
921 save_del_notification(struct rib_cmd_info *rc, void *_cbdata)
922 {
923         struct rib_cmd_info *rc_new = (struct rib_cmd_info *)_cbdata;
924
925         if (rc->rc_cmd == RTM_DELETE)
926                 *rc_new = *rc;
927 }
928
929 static void
930 save_add_notification(struct rib_cmd_info *rc, void *_cbdata)
931 {
932         struct rib_cmd_info *rc_new = (struct rib_cmd_info *)_cbdata;
933
934         if (rc->rc_cmd == RTM_ADD)
935                 *rc_new = *rc;
936 }
937 #endif
938
939 /*ARGSUSED*/
940 static int
941 route_output(struct mbuf *m, struct socket *so, ...)
942 {
943         struct rt_msghdr *rtm = NULL;
944         struct rtentry *rt = NULL;
945         struct rt_addrinfo info;
946         struct epoch_tracker et;
947 #ifdef INET6
948         struct sockaddr_storage ss;
949         struct sockaddr_in6 *sin6;
950         int i, rti_need_deembed = 0;
951 #endif
952         int alloc_len = 0, len, error = 0, fibnum;
953         sa_family_t saf = AF_UNSPEC;
954         struct walkarg w;
955         struct rib_cmd_info rc;
956         struct nhop_object *nh;
957
958         fibnum = so->so_fibnum;
959 #define senderr(e) { error = e; goto flush;}
960         if (m == NULL || ((m->m_len < sizeof(long)) &&
961                        (m = m_pullup(m, sizeof(long))) == NULL))
962                 return (ENOBUFS);
963         if ((m->m_flags & M_PKTHDR) == 0)
964                 panic("route_output");
965         NET_EPOCH_ENTER(et);
966         len = m->m_pkthdr.len;
967         if (len < sizeof(*rtm) ||
968             len != mtod(m, struct rt_msghdr *)->rtm_msglen)
969                 senderr(EINVAL);
970
971         /*
972          * Most of current messages are in range 200-240 bytes,
973          * minimize possible re-allocation on reply using larger size
974          * buffer aligned on 1k boundaty.
975          */
976         alloc_len = roundup2(len, 1024);
977         if ((rtm = malloc(alloc_len, M_TEMP, M_NOWAIT)) == NULL)
978                 senderr(ENOBUFS);
979
980         m_copydata(m, 0, len, (caddr_t)rtm);
981         bzero(&info, sizeof(info));
982         bzero(&w, sizeof(w));
983         nh = NULL;
984
985         if (rtm->rtm_version != RTM_VERSION) {
986                 /* Do not touch message since format is unknown */
987                 free(rtm, M_TEMP);
988                 rtm = NULL;
989                 senderr(EPROTONOSUPPORT);
990         }
991
992         /*
993          * Starting from here, it is possible
994          * to alter original message and insert
995          * caller PID and error value.
996          */
997
998         if ((error = fill_addrinfo(rtm, len, fibnum, &info)) != 0) {
999                 senderr(error);
1000         }
1001
1002         saf = info.rti_info[RTAX_DST]->sa_family;
1003
1004         /* support for new ARP code */
1005         if (rtm->rtm_flags & RTF_LLDATA) {
1006                 error = lla_rt_output(rtm, &info);
1007 #ifdef INET6
1008                 if (error == 0)
1009                         rti_need_deembed = 1;
1010 #endif
1011                 goto flush;
1012         }
1013
1014         switch (rtm->rtm_type) {
1015         case RTM_ADD:
1016         case RTM_CHANGE:
1017                 if (rtm->rtm_type == RTM_ADD) {
1018                         if (info.rti_info[RTAX_GATEWAY] == NULL)
1019                                 senderr(EINVAL);
1020                 }
1021                 error = rib_action(fibnum, rtm->rtm_type, &info, &rc);
1022                 if (error == 0) {
1023 #ifdef INET6
1024                         rti_need_deembed = 1;
1025 #endif
1026 #ifdef ROUTE_MPATH
1027                         if (NH_IS_NHGRP(rc.rc_nh_new) ||
1028                             (rc.rc_nh_old && NH_IS_NHGRP(rc.rc_nh_old))) {
1029                                 struct rib_cmd_info rc_simple = {};
1030                                 rib_decompose_notification(&rc,
1031                                     save_add_notification, (void *)&rc_simple);
1032                                 rc = rc_simple;
1033                         }
1034 #endif
1035                         nh = rc.rc_nh_new;
1036                         rtm->rtm_index = nh->nh_ifp->if_index;
1037                         rtm->rtm_flags = rc.rc_rt->rte_flags | nhop_get_rtflags(nh);
1038                 }
1039                 break;
1040
1041         case RTM_DELETE:
1042                 error = rib_action(fibnum, RTM_DELETE, &info, &rc);
1043                 if (error == 0) {
1044 #ifdef ROUTE_MPATH
1045                         if (NH_IS_NHGRP(rc.rc_nh_old) ||
1046                             (rc.rc_nh_new && NH_IS_NHGRP(rc.rc_nh_new))) {
1047                                 struct rib_cmd_info rc_simple = {};
1048                                 rib_decompose_notification(&rc,
1049                                     save_del_notification, (void *)&rc_simple);
1050                                 rc = rc_simple;
1051                         }
1052 #endif
1053                         nh = rc.rc_nh_old;
1054                         goto report;
1055                 }
1056 #ifdef INET6
1057                 /* rt_msg2() will not be used when RTM_DELETE fails. */
1058                 rti_need_deembed = 1;
1059 #endif
1060                 break;
1061
1062         case RTM_GET:
1063                 error = handle_rtm_get(&info, fibnum, rtm, &rc);
1064                 if (error != 0)
1065                         senderr(error);
1066                 nh = rc.rc_nh_new;
1067
1068 report:
1069                 if (!can_export_rte(curthread->td_ucred,
1070                     info.rti_info[RTAX_NETMASK] == NULL,
1071                     info.rti_info[RTAX_DST])) {
1072                         senderr(ESRCH);
1073                 }
1074
1075                 error = update_rtm_from_rc(&info, &rtm, alloc_len, &rc, nh);
1076                 /*
1077                  * Note that some sockaddr pointers may have changed to
1078                  * point to memory outsize @rtm. Some may be pointing
1079                  * to the on-stack variables.
1080                  * Given that, any pointer in @info CANNOT BE USED.
1081                  */
1082
1083                 /*
1084                  * scopeid deembedding has been performed while
1085                  * writing updated rtm in rtsock_msg_buffer().
1086                  * With that in mind, skip deembedding procedure below.
1087                  */
1088 #ifdef INET6
1089                 rti_need_deembed = 0;
1090 #endif
1091                 if (error != 0)
1092                         senderr(error);
1093                 break;
1094
1095         default:
1096                 senderr(EOPNOTSUPP);
1097         }
1098
1099 flush:
1100         NET_EPOCH_EXIT(et);
1101         rt = NULL;
1102
1103 #ifdef INET6
1104         if (rtm != NULL) {
1105                 if (rti_need_deembed) {
1106                         /* sin6_scope_id is recovered before sending rtm. */
1107                         sin6 = (struct sockaddr_in6 *)&ss;
1108                         for (i = 0; i < RTAX_MAX; i++) {
1109                                 if (info.rti_info[i] == NULL)
1110                                         continue;
1111                                 if (info.rti_info[i]->sa_family != AF_INET6)
1112                                         continue;
1113                                 bcopy(info.rti_info[i], sin6, sizeof(*sin6));
1114                                 if (sa6_recoverscope(sin6) == 0)
1115                                         bcopy(sin6, info.rti_info[i],
1116                                                     sizeof(*sin6));
1117                         }
1118                 }
1119         }
1120 #endif
1121         send_rtm_reply(so, rtm, m, saf, fibnum, error);
1122
1123         return (error);
1124 }
1125
1126 /*
1127  * Sends the prepared reply message in @rtm to all rtsock clients.
1128  * Frees @m and @rtm.
1129  *
1130  */
1131 static void
1132 send_rtm_reply(struct socket *so, struct rt_msghdr *rtm, struct mbuf *m,
1133     sa_family_t saf, u_int fibnum, int rtm_errno)
1134 {
1135         struct rawcb *rp = NULL;
1136
1137         /*
1138          * Check to see if we don't want our own messages.
1139          */
1140         if ((so->so_options & SO_USELOOPBACK) == 0) {
1141                 if (V_route_cb.any_count <= 1) {
1142                         if (rtm != NULL)
1143                                 free(rtm, M_TEMP);
1144                         m_freem(m);
1145                         return;
1146                 }
1147                 /* There is another listener, so construct message */
1148                 rp = sotorawcb(so);
1149         }
1150
1151         if (rtm != NULL) {
1152                 if (rtm_errno!= 0)
1153                         rtm->rtm_errno = rtm_errno;
1154                 else
1155                         rtm->rtm_flags |= RTF_DONE;
1156
1157                 m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);
1158                 if (m->m_pkthdr.len < rtm->rtm_msglen) {
1159                         m_freem(m);
1160                         m = NULL;
1161                 } else if (m->m_pkthdr.len > rtm->rtm_msglen)
1162                         m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
1163
1164                 free(rtm, M_TEMP);
1165         }
1166         if (m != NULL) {
1167                 M_SETFIB(m, fibnum);
1168                 m->m_flags |= RTS_FILTER_FIB;
1169                 if (rp) {
1170                         /*
1171                          * XXX insure we don't get a copy by
1172                          * invalidating our protocol
1173                          */
1174                         unsigned short family = rp->rcb_proto.sp_family;
1175                         rp->rcb_proto.sp_family = 0;
1176                         rt_dispatch(m, saf);
1177                         rp->rcb_proto.sp_family = family;
1178                 } else
1179                         rt_dispatch(m, saf);
1180         }
1181 }
1182
1183 static void
1184 rt_getmetrics(const struct rtentry *rt, const struct nhop_object *nh,
1185     struct rt_metrics *out)
1186 {
1187
1188         bzero(out, sizeof(*out));
1189         out->rmx_mtu = nh->nh_mtu;
1190         out->rmx_weight = rt->rt_weight;
1191         out->rmx_nhidx = nhop_get_idx(nh);
1192         /* Kernel -> userland timebase conversion. */
1193         out->rmx_expire = rt->rt_expire ?
1194             rt->rt_expire - time_uptime + time_second : 0;
1195 }
1196
1197 /*
1198  * Extract the addresses of the passed sockaddrs.
1199  * Do a little sanity checking so as to avoid bad memory references.
1200  * This data is derived straight from userland.
1201  */
1202 static int
1203 rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
1204 {
1205         struct sockaddr *sa;
1206         int i;
1207
1208         for (i = 0; i < RTAX_MAX && cp < cplim; i++) {
1209                 if ((rtinfo->rti_addrs & (1 << i)) == 0)
1210                         continue;
1211                 sa = (struct sockaddr *)cp;
1212                 /*
1213                  * It won't fit.
1214                  */
1215                 if (cp + sa->sa_len > cplim)
1216                         return (EINVAL);
1217                 /*
1218                  * there are no more.. quit now
1219                  * If there are more bits, they are in error.
1220                  * I've seen this. route(1) can evidently generate these. 
1221                  * This causes kernel to core dump.
1222                  * for compatibility, If we see this, point to a safe address.
1223                  */
1224                 if (sa->sa_len == 0) {
1225                         rtinfo->rti_info[i] = &sa_zero;
1226                         return (0); /* should be EINVAL but for compat */
1227                 }
1228                 /* accept it */
1229 #ifdef INET6
1230                 if (sa->sa_family == AF_INET6)
1231                         sa6_embedscope((struct sockaddr_in6 *)sa,
1232                             V_ip6_use_defzone);
1233 #endif
1234                 rtinfo->rti_info[i] = sa;
1235                 cp += SA_SIZE(sa);
1236         }
1237         return (0);
1238 }
1239
1240 #ifdef INET
1241 static inline void
1242 fill_sockaddr_inet(struct sockaddr_in *sin, struct in_addr addr)
1243 {
1244
1245         const struct sockaddr_in nsin = {
1246                 .sin_family = AF_INET,
1247                 .sin_len = sizeof(struct sockaddr_in),
1248                 .sin_addr = addr,
1249         };
1250         *sin = nsin;
1251 }
1252 #endif
1253
1254 #ifdef INET6
1255 static inline void
1256 fill_sockaddr_inet6(struct sockaddr_in6 *sin6, const struct in6_addr *addr6,
1257     uint32_t scopeid)
1258 {
1259
1260         const struct sockaddr_in6 nsin6 = {
1261                 .sin6_family = AF_INET6,
1262                 .sin6_len = sizeof(struct sockaddr_in6),
1263                 .sin6_addr = *addr6,
1264                 .sin6_scope_id = scopeid,
1265         };
1266         *sin6 = nsin6;
1267 }
1268 #endif
1269
1270 /*
1271  * Checks if gateway is suitable for lltable operations.
1272  * Lltable code requires AF_LINK gateway with ifindex
1273  *  and mac address specified.
1274  * Returns 0 on success.
1275  */
1276 static int
1277 cleanup_xaddrs_lladdr(struct rt_addrinfo *info)
1278 {
1279         struct sockaddr_dl *sdl = (struct sockaddr_dl *)info->rti_info[RTAX_GATEWAY];
1280
1281         if (sdl->sdl_family != AF_LINK)
1282                 return (EINVAL);
1283
1284         if (sdl->sdl_index == 0)
1285                 return (EINVAL);
1286
1287         if (offsetof(struct sockaddr_dl, sdl_data) + sdl->sdl_nlen + sdl->sdl_alen > sdl->sdl_len)
1288                 return (EINVAL);
1289
1290         return (0);
1291 }
1292
1293 static int
1294 cleanup_xaddrs_gateway(struct rt_addrinfo *info)
1295 {
1296         struct sockaddr *gw = info->rti_info[RTAX_GATEWAY];
1297
1298         if (info->rti_flags & RTF_LLDATA)
1299                 return (cleanup_xaddrs_lladdr(info));
1300
1301         switch (gw->sa_family) {
1302 #ifdef INET
1303         case AF_INET:
1304                 {
1305                         struct sockaddr_in *gw_sin = (struct sockaddr_in *)gw;
1306                         if (gw_sin->sin_len < sizeof(struct sockaddr_in)) {
1307                                 printf("gw sin_len too small\n");
1308                                 return (EINVAL);
1309                         }
1310                         fill_sockaddr_inet(gw_sin, gw_sin->sin_addr);
1311                 }
1312                 break;
1313 #endif
1314 #ifdef INET6
1315         case AF_INET6:
1316                 {
1317                         struct sockaddr_in6 *gw_sin6 = (struct sockaddr_in6 *)gw;
1318                         if (gw_sin6->sin6_len < sizeof(struct sockaddr_in6)) {
1319                                 printf("gw sin6_len too small\n");
1320                                 return (EINVAL);
1321                         }
1322                         fill_sockaddr_inet6(gw_sin6, &gw_sin6->sin6_addr, 0);
1323                         break;
1324                 }
1325 #endif
1326         case AF_LINK:
1327                 {
1328                         struct sockaddr_dl_short *gw_sdl;
1329
1330                         gw_sdl = (struct sockaddr_dl_short *)gw;
1331                         if (gw_sdl->sdl_len < sizeof(struct sockaddr_dl_short)) {
1332                                 printf("gw sdl_len too small\n");
1333                                 return (EINVAL);
1334                         }
1335
1336                         const struct sockaddr_dl_short sdl = {
1337                                 .sdl_family = AF_LINK,
1338                                 .sdl_len = sizeof(struct sockaddr_dl_short),
1339                                 .sdl_index = gw_sdl->sdl_index,
1340                         };
1341                         *gw_sdl = sdl;
1342                         break;
1343                 }
1344         }
1345
1346         return (0);
1347 }
1348
1349 static void
1350 remove_netmask(struct rt_addrinfo *info)
1351 {
1352         info->rti_info[RTAX_NETMASK] = NULL;
1353         info->rti_flags |= RTF_HOST;
1354         info->rti_addrs &= ~RTA_NETMASK;
1355 }
1356
1357 #ifdef INET
1358 static int
1359 cleanup_xaddrs_inet(struct rt_addrinfo *info)
1360 {
1361         struct sockaddr_in *dst_sa, *mask_sa;
1362
1363         /* Check & fixup dst/netmask combination first */
1364         dst_sa = (struct sockaddr_in *)info->rti_info[RTAX_DST];
1365         mask_sa = (struct sockaddr_in *)info->rti_info[RTAX_NETMASK];
1366
1367         struct in_addr mask = {
1368                 .s_addr = mask_sa ? mask_sa->sin_addr.s_addr : INADDR_BROADCAST,
1369         };
1370         struct in_addr dst = {
1371                 .s_addr = htonl(ntohl(dst_sa->sin_addr.s_addr) & ntohl(mask.s_addr))
1372         };
1373
1374         if (dst_sa->sin_len < sizeof(struct sockaddr_in)) {
1375                 printf("dst sin_len too small\n");
1376                 return (EINVAL);
1377         }
1378         if (mask_sa && mask_sa->sin_len < sizeof(struct sockaddr_in)) {
1379                 printf("mask sin_len too small\n");
1380                 return (EINVAL);
1381         }
1382         fill_sockaddr_inet(dst_sa, dst);
1383
1384         if (mask.s_addr != INADDR_BROADCAST)
1385                 fill_sockaddr_inet(mask_sa, mask);
1386         else
1387                 remove_netmask(info);
1388
1389         /* Check gateway */
1390         if (info->rti_info[RTAX_GATEWAY] != NULL)
1391                 return (cleanup_xaddrs_gateway(info));
1392
1393         return (0);
1394 }
1395 #endif
1396
1397 #ifdef INET6
1398 static int
1399 cleanup_xaddrs_inet6(struct rt_addrinfo *info)
1400 {
1401         struct sockaddr_in6 *dst_sa, *mask_sa;
1402         struct in6_addr mask;
1403
1404         /* Check & fixup dst/netmask combination first */
1405         dst_sa = (struct sockaddr_in6 *)info->rti_info[RTAX_DST];
1406         mask_sa = (struct sockaddr_in6 *)info->rti_info[RTAX_NETMASK];
1407
1408         mask = mask_sa ? mask_sa->sin6_addr : in6mask128;
1409         IN6_MASK_ADDR(&dst_sa->sin6_addr, &mask);
1410
1411         if (dst_sa->sin6_len < sizeof(struct sockaddr_in6)) {
1412                 printf("dst sin6_len too small\n");
1413                 return (EINVAL);
1414         }
1415         if (mask_sa && mask_sa->sin6_len < sizeof(struct sockaddr_in6)) {
1416                 printf("mask sin6_len too small\n");
1417                 return (EINVAL);
1418         }
1419         fill_sockaddr_inet6(dst_sa, &dst_sa->sin6_addr, 0);
1420
1421         if (!IN6_ARE_ADDR_EQUAL(&mask, &in6mask128))
1422                 fill_sockaddr_inet6(mask_sa, &mask, 0);
1423         else
1424                 remove_netmask(info);
1425
1426         /* Check gateway */
1427         if (info->rti_info[RTAX_GATEWAY] != NULL)
1428                 return (cleanup_xaddrs_gateway(info));
1429
1430         return (0);
1431 }
1432 #endif
1433
1434 static int
1435 cleanup_xaddrs(struct rt_addrinfo *info)
1436 {
1437         int error = EAFNOSUPPORT;
1438
1439         if (info->rti_info[RTAX_DST] == NULL)
1440                 return (EINVAL);
1441
1442         if (info->rti_flags & RTF_LLDATA) {
1443                 /*
1444                  * arp(8)/ndp(8) sends RTA_NETMASK for the associated
1445                  * prefix along with the actual address in RTA_DST.
1446                  * Remove netmask to avoid unnecessary address masking.
1447                  */
1448                 remove_netmask(info);
1449         }
1450
1451         switch (info->rti_info[RTAX_DST]->sa_family) {
1452 #ifdef INET
1453         case AF_INET:
1454                 error = cleanup_xaddrs_inet(info);
1455                 break;
1456 #endif
1457 #ifdef INET6
1458         case AF_INET6:
1459                 error = cleanup_xaddrs_inet6(info);
1460                 break;
1461 #endif
1462         }
1463
1464         return (error);
1465 }
1466
1467 /*
1468  * Fill in @dmask with valid netmask leaving original @smask
1469  * intact. Mostly used with radix netmasks.
1470  */
1471 struct sockaddr *
1472 rtsock_fix_netmask(const struct sockaddr *dst, const struct sockaddr *smask,
1473     struct sockaddr_storage *dmask)
1474 {
1475         if (dst == NULL || smask == NULL)
1476                 return (NULL);
1477
1478         memset(dmask, 0, dst->sa_len);
1479         memcpy(dmask, smask, smask->sa_len);
1480         dmask->ss_len = dst->sa_len;
1481         dmask->ss_family = dst->sa_family;
1482
1483         return ((struct sockaddr *)dmask);
1484 }
1485
1486 /*
1487  * Writes information related to @rtinfo object to newly-allocated mbuf.
1488  * Assumes MCLBYTES is enough to construct any message.
1489  * Used for OS notifications of vaious events (if/ifa announces,etc)
1490  *
1491  * Returns allocated mbuf or NULL on failure.
1492  */
1493 static struct mbuf *
1494 rtsock_msg_mbuf(int type, struct rt_addrinfo *rtinfo)
1495 {
1496         struct sockaddr_storage ss;
1497         struct rt_msghdr *rtm;
1498         struct mbuf *m;
1499         int i;
1500         struct sockaddr *sa;
1501 #ifdef INET6
1502         struct sockaddr_in6 *sin6;
1503 #endif
1504         int len, dlen;
1505
1506         switch (type) {
1507         case RTM_DELADDR:
1508         case RTM_NEWADDR:
1509                 len = sizeof(struct ifa_msghdr);
1510                 break;
1511
1512         case RTM_DELMADDR:
1513         case RTM_NEWMADDR:
1514                 len = sizeof(struct ifma_msghdr);
1515                 break;
1516
1517         case RTM_IFINFO:
1518                 len = sizeof(struct if_msghdr);
1519                 break;
1520
1521         case RTM_IFANNOUNCE:
1522         case RTM_IEEE80211:
1523                 len = sizeof(struct if_announcemsghdr);
1524                 break;
1525
1526         default:
1527                 len = sizeof(struct rt_msghdr);
1528         }
1529
1530         /* XXXGL: can we use MJUMPAGESIZE cluster here? */
1531         KASSERT(len <= MCLBYTES, ("%s: message too big", __func__));
1532         if (len > MHLEN)
1533                 m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1534         else
1535                 m = m_gethdr(M_NOWAIT, MT_DATA);
1536         if (m == NULL)
1537                 return (m);
1538
1539         m->m_pkthdr.len = m->m_len = len;
1540         rtm = mtod(m, struct rt_msghdr *);
1541         bzero((caddr_t)rtm, len);
1542         for (i = 0; i < RTAX_MAX; i++) {
1543                 if ((sa = rtinfo->rti_info[i]) == NULL)
1544                         continue;
1545                 rtinfo->rti_addrs |= (1 << i);
1546
1547                 dlen = SA_SIZE(sa);
1548                 KASSERT(dlen <= sizeof(ss),
1549                     ("%s: sockaddr size overflow", __func__));
1550                 bzero(&ss, sizeof(ss));
1551                 bcopy(sa, &ss, sa->sa_len);
1552                 sa = (struct sockaddr *)&ss;
1553 #ifdef INET6
1554                 if (sa->sa_family == AF_INET6) {
1555                         sin6 = (struct sockaddr_in6 *)sa;
1556                         (void)sa6_recoverscope(sin6);
1557                 }
1558 #endif
1559                 m_copyback(m, len, dlen, (caddr_t)sa);
1560                 len += dlen;
1561         }
1562         if (m->m_pkthdr.len != len) {
1563                 m_freem(m);
1564                 return (NULL);
1565         }
1566         rtm->rtm_msglen = len;
1567         rtm->rtm_version = RTM_VERSION;
1568         rtm->rtm_type = type;
1569         return (m);
1570 }
1571
1572 /*
1573  * Writes information related to @rtinfo object to preallocated buffer.
1574  * Stores needed size in @plen. If @w is NULL, calculates size without
1575  * writing.
1576  * Used for sysctl dumps and rtsock answers (RTM_DEL/RTM_GET) generation.
1577  *
1578  * Returns 0 on success.
1579  *
1580  */
1581 static int
1582 rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *plen)
1583 {
1584         struct sockaddr_storage ss;
1585         int len, buflen = 0, dlen, i;
1586         caddr_t cp = NULL;
1587         struct rt_msghdr *rtm = NULL;
1588 #ifdef INET6
1589         struct sockaddr_in6 *sin6;
1590 #endif
1591 #ifdef COMPAT_FREEBSD32
1592         bool compat32 = false;
1593 #endif
1594
1595         switch (type) {
1596         case RTM_DELADDR:
1597         case RTM_NEWADDR:
1598                 if (w != NULL && w->w_op == NET_RT_IFLISTL) {
1599 #ifdef COMPAT_FREEBSD32
1600                         if (w->w_req->flags & SCTL_MASK32) {
1601                                 len = sizeof(struct ifa_msghdrl32);
1602                                 compat32 = true;
1603                         } else
1604 #endif
1605                                 len = sizeof(struct ifa_msghdrl);
1606                 } else
1607                         len = sizeof(struct ifa_msghdr);
1608                 break;
1609
1610         case RTM_IFINFO:
1611 #ifdef COMPAT_FREEBSD32
1612                 if (w != NULL && w->w_req->flags & SCTL_MASK32) {
1613                         if (w->w_op == NET_RT_IFLISTL)
1614                                 len = sizeof(struct if_msghdrl32);
1615                         else
1616                                 len = sizeof(struct if_msghdr32);
1617                         compat32 = true;
1618                         break;
1619                 }
1620 #endif
1621                 if (w != NULL && w->w_op == NET_RT_IFLISTL)
1622                         len = sizeof(struct if_msghdrl);
1623                 else
1624                         len = sizeof(struct if_msghdr);
1625                 break;
1626
1627         case RTM_NEWMADDR:
1628                 len = sizeof(struct ifma_msghdr);
1629                 break;
1630
1631         default:
1632                 len = sizeof(struct rt_msghdr);
1633         }
1634
1635         if (w != NULL) {
1636                 rtm = (struct rt_msghdr *)w->w_tmem;
1637                 buflen = w->w_tmemsize - len;
1638                 cp = (caddr_t)w->w_tmem + len;
1639         }
1640
1641         rtinfo->rti_addrs = 0;
1642         for (i = 0; i < RTAX_MAX; i++) {
1643                 struct sockaddr *sa;
1644
1645                 if ((sa = rtinfo->rti_info[i]) == NULL)
1646                         continue;
1647                 rtinfo->rti_addrs |= (1 << i);
1648 #ifdef COMPAT_FREEBSD32
1649                 if (compat32)
1650                         dlen = SA_SIZE32(sa);
1651                 else
1652 #endif
1653                         dlen = SA_SIZE(sa);
1654                 if (cp != NULL && buflen >= dlen) {
1655                         KASSERT(dlen <= sizeof(ss),
1656                             ("%s: sockaddr size overflow", __func__));
1657                         bzero(&ss, sizeof(ss));
1658                         bcopy(sa, &ss, sa->sa_len);
1659                         sa = (struct sockaddr *)&ss;
1660 #ifdef INET6
1661                         if (sa->sa_family == AF_INET6) {
1662                                 sin6 = (struct sockaddr_in6 *)sa;
1663                                 (void)sa6_recoverscope(sin6);
1664                         }
1665 #endif
1666                         bcopy((caddr_t)sa, cp, (unsigned)dlen);
1667                         cp += dlen;
1668                         buflen -= dlen;
1669                 } else if (cp != NULL) {
1670                         /*
1671                          * Buffer too small. Count needed size
1672                          * and return with error.
1673                          */
1674                         cp = NULL;
1675                 }
1676
1677                 len += dlen;
1678         }
1679
1680         if (cp != NULL) {
1681                 dlen = ALIGN(len) - len;
1682                 if (buflen < dlen)
1683                         cp = NULL;
1684                 else {
1685                         bzero(cp, dlen);
1686                         cp += dlen;
1687                         buflen -= dlen;
1688                 }
1689         }
1690         len = ALIGN(len);
1691
1692         if (cp != NULL) {
1693                 /* fill header iff buffer is large enough */
1694                 rtm->rtm_version = RTM_VERSION;
1695                 rtm->rtm_type = type;
1696                 rtm->rtm_msglen = len;
1697         }
1698
1699         *plen = len;
1700
1701         if (w != NULL && cp == NULL)
1702                 return (ENOBUFS);
1703
1704         return (0);
1705 }
1706
1707 /*
1708  * This routine is called to generate a message from the routing
1709  * socket indicating that a redirect has occurred, a routing lookup
1710  * has failed, or that a protocol has detected timeouts to a particular
1711  * destination.
1712  */
1713 void
1714 rt_missmsg_fib(int type, struct rt_addrinfo *rtinfo, int flags, int error,
1715     int fibnum)
1716 {
1717         struct rt_msghdr *rtm;
1718         struct mbuf *m;
1719         struct sockaddr *sa = rtinfo->rti_info[RTAX_DST];
1720
1721         if (V_route_cb.any_count == 0)
1722                 return;
1723         m = rtsock_msg_mbuf(type, rtinfo);
1724         if (m == NULL)
1725                 return;
1726
1727         if (fibnum != RT_ALL_FIBS) {
1728                 KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: fibnum out "
1729                     "of range 0 <= %d < %d", __func__, fibnum, rt_numfibs));
1730                 M_SETFIB(m, fibnum);
1731                 m->m_flags |= RTS_FILTER_FIB;
1732         }
1733
1734         rtm = mtod(m, struct rt_msghdr *);
1735         rtm->rtm_flags = RTF_DONE | flags;
1736         rtm->rtm_errno = error;
1737         rtm->rtm_addrs = rtinfo->rti_addrs;
1738         rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
1739 }
1740
1741 void
1742 rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
1743 {
1744
1745         rt_missmsg_fib(type, rtinfo, flags, error, RT_ALL_FIBS);
1746 }
1747
1748 /*
1749  * This routine is called to generate a message from the routing
1750  * socket indicating that the status of a network interface has changed.
1751  */
1752 void
1753 rt_ifmsg(struct ifnet *ifp)
1754 {
1755         struct if_msghdr *ifm;
1756         struct mbuf *m;
1757         struct rt_addrinfo info;
1758
1759         if (V_route_cb.any_count == 0)
1760                 return;
1761         bzero((caddr_t)&info, sizeof(info));
1762         m = rtsock_msg_mbuf(RTM_IFINFO, &info);
1763         if (m == NULL)
1764                 return;
1765         ifm = mtod(m, struct if_msghdr *);
1766         ifm->ifm_index = ifp->if_index;
1767         ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
1768         if_data_copy(ifp, &ifm->ifm_data);
1769         ifm->ifm_addrs = 0;
1770         rt_dispatch(m, AF_UNSPEC);
1771 }
1772
1773 /*
1774  * Announce interface address arrival/withdraw.
1775  * Please do not call directly, use rt_addrmsg().
1776  * Assume input data to be valid.
1777  * Returns 0 on success.
1778  */
1779 int
1780 rtsock_addrmsg(int cmd, struct ifaddr *ifa, int fibnum)
1781 {
1782         struct rt_addrinfo info;
1783         struct sockaddr *sa;
1784         int ncmd;
1785         struct mbuf *m;
1786         struct ifa_msghdr *ifam;
1787         struct ifnet *ifp = ifa->ifa_ifp;
1788         struct sockaddr_storage ss;
1789
1790         if (V_route_cb.any_count == 0)
1791                 return (0);
1792
1793         ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
1794
1795         bzero((caddr_t)&info, sizeof(info));
1796         info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
1797         info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr;
1798         info.rti_info[RTAX_NETMASK] = rtsock_fix_netmask(
1799             info.rti_info[RTAX_IFA], ifa->ifa_netmask, &ss);
1800         info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
1801         if ((m = rtsock_msg_mbuf(ncmd, &info)) == NULL)
1802                 return (ENOBUFS);
1803         ifam = mtod(m, struct ifa_msghdr *);
1804         ifam->ifam_index = ifp->if_index;
1805         ifam->ifam_metric = ifa->ifa_ifp->if_metric;
1806         ifam->ifam_flags = ifa->ifa_flags;
1807         ifam->ifam_addrs = info.rti_addrs;
1808
1809         if (fibnum != RT_ALL_FIBS) {
1810                 M_SETFIB(m, fibnum);
1811                 m->m_flags |= RTS_FILTER_FIB;
1812         }
1813
1814         rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
1815
1816         return (0);
1817 }
1818
1819 /*
1820  * Announce route addition/removal to rtsock based on @rt data.
1821  * Callers are advives to use rt_routemsg() instead of using this
1822  *  function directly.
1823  * Assume @rt data is consistent.
1824  *
1825  * Returns 0 on success.
1826  */
1827 int
1828 rtsock_routemsg(int cmd, struct rtentry *rt, struct nhop_object *nh,
1829     int fibnum)
1830 {
1831         union sockaddr_union dst, mask;
1832         struct rt_addrinfo info;
1833
1834         if (V_route_cb.any_count == 0)
1835                 return (0);
1836
1837         int family = rt_get_family(rt);
1838         init_sockaddrs_family(family, &dst.sa, &mask.sa);
1839         export_rtaddrs(rt, &dst.sa, &mask.sa);
1840
1841         bzero((caddr_t)&info, sizeof(info));
1842         info.rti_info[RTAX_DST] = &dst.sa;
1843         info.rti_info[RTAX_NETMASK] = &mask.sa;
1844         info.rti_info[RTAX_GATEWAY] = &nh->gw_sa;
1845         info.rti_flags = rt->rte_flags | nhop_get_rtflags(nh);
1846         info.rti_ifp = nh->nh_ifp;
1847
1848         return (rtsock_routemsg_info(cmd, &info, fibnum));
1849 }
1850
1851 int
1852 rtsock_routemsg_info(int cmd, struct rt_addrinfo *info, int fibnum)
1853 {
1854         struct rt_msghdr *rtm;
1855         struct sockaddr *sa;
1856         struct mbuf *m;
1857
1858         if (V_route_cb.any_count == 0)
1859                 return (0);
1860
1861         if (info->rti_flags & RTF_HOST)
1862                 info->rti_info[RTAX_NETMASK] = NULL;
1863
1864         m = rtsock_msg_mbuf(cmd, info);
1865         if (m == NULL)
1866                 return (ENOBUFS);
1867
1868         if (fibnum != RT_ALL_FIBS) {
1869                 KASSERT(fibnum >= 0 && fibnum < rt_numfibs, ("%s: fibnum out "
1870                     "of range 0 <= %d < %d", __func__, fibnum, rt_numfibs));
1871                 M_SETFIB(m, fibnum);
1872                 m->m_flags |= RTS_FILTER_FIB;
1873         }
1874
1875         rtm = mtod(m, struct rt_msghdr *);
1876         rtm->rtm_addrs = info->rti_addrs;
1877         if (info->rti_ifp != NULL)
1878                 rtm->rtm_index = info->rti_ifp->if_index;
1879         /* Add RTF_DONE to indicate command 'completion' required by API */
1880         info->rti_flags |= RTF_DONE;
1881         /* Reported routes has to be up */
1882         if (cmd == RTM_ADD || cmd == RTM_CHANGE)
1883                 info->rti_flags |= RTF_UP;
1884         rtm->rtm_flags = info->rti_flags;
1885
1886         sa = info->rti_info[RTAX_DST];
1887         rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC);
1888
1889         return (0);
1890 }
1891
1892 /*
1893  * This is the analogue to the rt_newaddrmsg which performs the same
1894  * function but for multicast group memberhips.  This is easier since
1895  * there is no route state to worry about.
1896  */
1897 void
1898 rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma)
1899 {
1900         struct rt_addrinfo info;
1901         struct mbuf *m = NULL;
1902         struct ifnet *ifp = ifma->ifma_ifp;
1903         struct ifma_msghdr *ifmam;
1904
1905         if (V_route_cb.any_count == 0)
1906                 return;
1907
1908         bzero((caddr_t)&info, sizeof(info));
1909         info.rti_info[RTAX_IFA] = ifma->ifma_addr;
1910         if (ifp && ifp->if_addr)
1911                 info.rti_info[RTAX_IFP] = ifp->if_addr->ifa_addr;
1912         else
1913                 info.rti_info[RTAX_IFP] = NULL;
1914         /*
1915          * If a link-layer address is present, present it as a ``gateway''
1916          * (similarly to how ARP entries, e.g., are presented).
1917          */
1918         info.rti_info[RTAX_GATEWAY] = ifma->ifma_lladdr;
1919         m = rtsock_msg_mbuf(cmd, &info);
1920         if (m == NULL)
1921                 return;
1922         ifmam = mtod(m, struct ifma_msghdr *);
1923         KASSERT(ifp != NULL, ("%s: link-layer multicast address w/o ifp\n",
1924             __func__));
1925         ifmam->ifmam_index = ifp->if_index;
1926         ifmam->ifmam_addrs = info.rti_addrs;
1927         rt_dispatch(m, ifma->ifma_addr ? ifma->ifma_addr->sa_family : AF_UNSPEC);
1928 }
1929
1930 static struct mbuf *
1931 rt_makeifannouncemsg(struct ifnet *ifp, int type, int what,
1932         struct rt_addrinfo *info)
1933 {
1934         struct if_announcemsghdr *ifan;
1935         struct mbuf *m;
1936
1937         if (V_route_cb.any_count == 0)
1938                 return NULL;
1939         bzero((caddr_t)info, sizeof(*info));
1940         m = rtsock_msg_mbuf(type, info);
1941         if (m != NULL) {
1942                 ifan = mtod(m, struct if_announcemsghdr *);
1943                 ifan->ifan_index = ifp->if_index;
1944                 strlcpy(ifan->ifan_name, ifp->if_xname,
1945                         sizeof(ifan->ifan_name));
1946                 ifan->ifan_what = what;
1947         }
1948         return m;
1949 }
1950
1951 /*
1952  * This is called to generate routing socket messages indicating
1953  * IEEE80211 wireless events.
1954  * XXX we piggyback on the RTM_IFANNOUNCE msg format in a clumsy way.
1955  */
1956 void
1957 rt_ieee80211msg(struct ifnet *ifp, int what, void *data, size_t data_len)
1958 {
1959         struct mbuf *m;
1960         struct rt_addrinfo info;
1961
1962         m = rt_makeifannouncemsg(ifp, RTM_IEEE80211, what, &info);
1963         if (m != NULL) {
1964                 /*
1965                  * Append the ieee80211 data.  Try to stick it in the
1966                  * mbuf containing the ifannounce msg; otherwise allocate
1967                  * a new mbuf and append.
1968                  *
1969                  * NB: we assume m is a single mbuf.
1970                  */
1971                 if (data_len > M_TRAILINGSPACE(m)) {
1972                         struct mbuf *n = m_get(M_NOWAIT, MT_DATA);
1973                         if (n == NULL) {
1974                                 m_freem(m);
1975                                 return;
1976                         }
1977                         bcopy(data, mtod(n, void *), data_len);
1978                         n->m_len = data_len;
1979                         m->m_next = n;
1980                 } else if (data_len > 0) {
1981                         bcopy(data, mtod(m, u_int8_t *) + m->m_len, data_len);
1982                         m->m_len += data_len;
1983                 }
1984                 if (m->m_flags & M_PKTHDR)
1985                         m->m_pkthdr.len += data_len;
1986                 mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len;
1987                 rt_dispatch(m, AF_UNSPEC);
1988         }
1989 }
1990
1991 /*
1992  * This is called to generate routing socket messages indicating
1993  * network interface arrival and departure.
1994  */
1995 void
1996 rt_ifannouncemsg(struct ifnet *ifp, int what)
1997 {
1998         struct mbuf *m;
1999         struct rt_addrinfo info;
2000
2001         m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info);
2002         if (m != NULL)
2003                 rt_dispatch(m, AF_UNSPEC);
2004 }
2005
2006 static void
2007 rt_dispatch(struct mbuf *m, sa_family_t saf)
2008 {
2009         struct m_tag *tag;
2010
2011         /*
2012          * Preserve the family from the sockaddr, if any, in an m_tag for
2013          * use when injecting the mbuf into the routing socket buffer from
2014          * the netisr.
2015          */
2016         if (saf != AF_UNSPEC) {
2017                 tag = m_tag_get(PACKET_TAG_RTSOCKFAM, sizeof(unsigned short),
2018                     M_NOWAIT);
2019                 if (tag == NULL) {
2020                         m_freem(m);
2021                         return;
2022                 }
2023                 *(unsigned short *)(tag + 1) = saf;
2024                 m_tag_prepend(m, tag);
2025         }
2026 #ifdef VIMAGE
2027         if (V_loif)
2028                 m->m_pkthdr.rcvif = V_loif;
2029         else {
2030                 m_freem(m);
2031                 return;
2032         }
2033 #endif
2034         netisr_queue(NETISR_ROUTE, m);  /* mbuf is free'd on failure. */
2035 }
2036
2037 /*
2038  * Checks if rte can be exported v.r.t jails/vnets.
2039  *
2040  * Returns 1 if it can, 0 otherwise.
2041  */
2042 static bool
2043 can_export_rte(struct ucred *td_ucred, bool rt_is_host,
2044     const struct sockaddr *rt_dst)
2045 {
2046
2047         if ((!rt_is_host) ? jailed_without_vnet(td_ucred)
2048             : prison_if(td_ucred, rt_dst) != 0)
2049                 return (false);
2050         return (true);
2051 }
2052
2053
2054 /*
2055  * This is used in dumping the kernel table via sysctl().
2056  */
2057 static int
2058 sysctl_dumpentry(struct rtentry *rt, void *vw)
2059 {
2060         struct walkarg *w = vw;
2061         struct nhop_object *nh;
2062         int error = 0;
2063
2064         NET_EPOCH_ASSERT();
2065
2066         export_rtaddrs(rt, w->dst, w->mask);
2067         if (!can_export_rte(w->w_req->td->td_ucred, rt_is_host(rt), w->dst))
2068                 return (0);
2069         nh = rt_get_raw_nhop(rt);
2070 #ifdef ROUTE_MPATH
2071         if (NH_IS_NHGRP(nh)) {
2072                 struct weightened_nhop *wn;
2073                 uint32_t num_nhops;
2074                 wn = nhgrp_get_nhops((struct nhgrp_object *)nh, &num_nhops);
2075                 for (int i = 0; i < num_nhops; i++) {
2076                         error = sysctl_dumpnhop(rt, wn[i].nh, wn[i].weight, w);
2077                         if (error != 0)
2078                                 return (error);
2079                 }
2080         } else
2081 #endif
2082                 error = sysctl_dumpnhop(rt, nh, rt->rt_weight, w);
2083
2084         return (0);
2085 }
2086
2087
2088 static int
2089 sysctl_dumpnhop(struct rtentry *rt, struct nhop_object *nh, uint32_t weight,
2090     struct walkarg *w)
2091 {
2092         struct rt_addrinfo info;
2093         int error = 0, size;
2094         uint32_t rtflags;
2095
2096         rtflags = nhop_get_rtflags(nh);
2097
2098         if (w->w_op == NET_RT_FLAGS && !(rtflags & w->w_arg))
2099                 return (0);
2100
2101         bzero((caddr_t)&info, sizeof(info));
2102         info.rti_info[RTAX_DST] = w->dst;
2103         info.rti_info[RTAX_GATEWAY] = &nh->gw_sa;
2104         info.rti_info[RTAX_NETMASK] = (rtflags & RTF_HOST) ? NULL : w->mask;
2105         info.rti_info[RTAX_GENMASK] = 0;
2106         if (nh->nh_ifp && !(nh->nh_ifp->if_flags & IFF_DYING)) {
2107                 info.rti_info[RTAX_IFP] = nh->nh_ifp->if_addr->ifa_addr;
2108                 info.rti_info[RTAX_IFA] = nh->nh_ifa->ifa_addr;
2109                 if (nh->nh_ifp->if_flags & IFF_POINTOPOINT)
2110                         info.rti_info[RTAX_BRD] = nh->nh_ifa->ifa_dstaddr;
2111         }
2112         if ((error = rtsock_msg_buffer(RTM_GET, &info, w, &size)) != 0)
2113                 return (error);
2114         if (w->w_req && w->w_tmem) {
2115                 struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
2116
2117                 bzero(&rtm->rtm_index,
2118                     sizeof(*rtm) - offsetof(struct rt_msghdr, rtm_index));
2119
2120                 /*
2121                  * rte flags may consist of RTF_HOST (duplicated in nhop rtflags)
2122                  * and RTF_UP (if entry is linked, which is always true here).
2123                  * Given that, use nhop rtflags & add RTF_UP.
2124                  */
2125                 rtm->rtm_flags = rtflags | RTF_UP;
2126                 if (rtm->rtm_flags & RTF_GWFLAG_COMPAT)
2127                         rtm->rtm_flags = RTF_GATEWAY | 
2128                                 (rtm->rtm_flags & ~RTF_GWFLAG_COMPAT);
2129                 rt_getmetrics(rt, nh, &rtm->rtm_rmx);
2130                 rtm->rtm_rmx.rmx_weight = weight;
2131                 rtm->rtm_index = nh->nh_ifp->if_index;
2132                 rtm->rtm_addrs = info.rti_addrs;
2133                 error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size);
2134                 return (error);
2135         }
2136         return (error);
2137 }
2138
2139 static int
2140 sysctl_iflist_ifml(struct ifnet *ifp, const struct if_data *src_ifd,
2141     struct rt_addrinfo *info, struct walkarg *w, int len)
2142 {
2143         struct if_msghdrl *ifm;
2144         struct if_data *ifd;
2145
2146         ifm = (struct if_msghdrl *)w->w_tmem;
2147
2148 #ifdef COMPAT_FREEBSD32
2149         if (w->w_req->flags & SCTL_MASK32) {
2150                 struct if_msghdrl32 *ifm32;
2151
2152                 ifm32 = (struct if_msghdrl32 *)ifm;
2153                 ifm32->ifm_addrs = info->rti_addrs;
2154                 ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
2155                 ifm32->ifm_index = ifp->if_index;
2156                 ifm32->_ifm_spare1 = 0;
2157                 ifm32->ifm_len = sizeof(*ifm32);
2158                 ifm32->ifm_data_off = offsetof(struct if_msghdrl32, ifm_data);
2159                 ifm32->_ifm_spare2 = 0;
2160                 ifd = &ifm32->ifm_data;
2161         } else
2162 #endif
2163         {
2164                 ifm->ifm_addrs = info->rti_addrs;
2165                 ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
2166                 ifm->ifm_index = ifp->if_index;
2167                 ifm->_ifm_spare1 = 0;
2168                 ifm->ifm_len = sizeof(*ifm);
2169                 ifm->ifm_data_off = offsetof(struct if_msghdrl, ifm_data);
2170                 ifm->_ifm_spare2 = 0;
2171                 ifd = &ifm->ifm_data;
2172         }
2173
2174         memcpy(ifd, src_ifd, sizeof(*ifd));
2175
2176         return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
2177 }
2178
2179 static int
2180 sysctl_iflist_ifm(struct ifnet *ifp, const struct if_data *src_ifd,
2181     struct rt_addrinfo *info, struct walkarg *w, int len)
2182 {
2183         struct if_msghdr *ifm;
2184         struct if_data *ifd;
2185
2186         ifm = (struct if_msghdr *)w->w_tmem;
2187
2188 #ifdef COMPAT_FREEBSD32
2189         if (w->w_req->flags & SCTL_MASK32) {
2190                 struct if_msghdr32 *ifm32;
2191
2192                 ifm32 = (struct if_msghdr32 *)ifm;
2193                 ifm32->ifm_addrs = info->rti_addrs;
2194                 ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
2195                 ifm32->ifm_index = ifp->if_index;
2196                 ifm32->_ifm_spare1 = 0;
2197                 ifd = &ifm32->ifm_data;
2198         } else
2199 #endif
2200         {
2201                 ifm->ifm_addrs = info->rti_addrs;
2202                 ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
2203                 ifm->ifm_index = ifp->if_index;
2204                 ifm->_ifm_spare1 = 0;
2205                 ifd = &ifm->ifm_data;
2206         }
2207
2208         memcpy(ifd, src_ifd, sizeof(*ifd));
2209
2210         return (SYSCTL_OUT(w->w_req, (caddr_t)ifm, len));
2211 }
2212
2213 static int
2214 sysctl_iflist_ifaml(struct ifaddr *ifa, struct rt_addrinfo *info,
2215     struct walkarg *w, int len)
2216 {
2217         struct ifa_msghdrl *ifam;
2218         struct if_data *ifd;
2219
2220         ifam = (struct ifa_msghdrl *)w->w_tmem;
2221
2222 #ifdef COMPAT_FREEBSD32
2223         if (w->w_req->flags & SCTL_MASK32) {
2224                 struct ifa_msghdrl32 *ifam32;
2225
2226                 ifam32 = (struct ifa_msghdrl32 *)ifam;
2227                 ifam32->ifam_addrs = info->rti_addrs;
2228                 ifam32->ifam_flags = ifa->ifa_flags;
2229                 ifam32->ifam_index = ifa->ifa_ifp->if_index;
2230                 ifam32->_ifam_spare1 = 0;
2231                 ifam32->ifam_len = sizeof(*ifam32);
2232                 ifam32->ifam_data_off =
2233                     offsetof(struct ifa_msghdrl32, ifam_data);
2234                 ifam32->ifam_metric = ifa->ifa_ifp->if_metric;
2235                 ifd = &ifam32->ifam_data;
2236         } else
2237 #endif
2238         {
2239                 ifam->ifam_addrs = info->rti_addrs;
2240                 ifam->ifam_flags = ifa->ifa_flags;
2241                 ifam->ifam_index = ifa->ifa_ifp->if_index;
2242                 ifam->_ifam_spare1 = 0;
2243                 ifam->ifam_len = sizeof(*ifam);
2244                 ifam->ifam_data_off = offsetof(struct ifa_msghdrl, ifam_data);
2245                 ifam->ifam_metric = ifa->ifa_ifp->if_metric;
2246                 ifd = &ifam->ifam_data;
2247         }
2248
2249         bzero(ifd, sizeof(*ifd));
2250         ifd->ifi_datalen = sizeof(struct if_data);
2251         ifd->ifi_ipackets = counter_u64_fetch(ifa->ifa_ipackets);
2252         ifd->ifi_opackets = counter_u64_fetch(ifa->ifa_opackets);
2253         ifd->ifi_ibytes = counter_u64_fetch(ifa->ifa_ibytes);
2254         ifd->ifi_obytes = counter_u64_fetch(ifa->ifa_obytes);
2255
2256         /* Fixup if_data carp(4) vhid. */
2257         if (carp_get_vhid_p != NULL)
2258                 ifd->ifi_vhid = (*carp_get_vhid_p)(ifa);
2259
2260         return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
2261 }
2262
2263 static int
2264 sysctl_iflist_ifam(struct ifaddr *ifa, struct rt_addrinfo *info,
2265     struct walkarg *w, int len)
2266 {
2267         struct ifa_msghdr *ifam;
2268
2269         ifam = (struct ifa_msghdr *)w->w_tmem;
2270         ifam->ifam_addrs = info->rti_addrs;
2271         ifam->ifam_flags = ifa->ifa_flags;
2272         ifam->ifam_index = ifa->ifa_ifp->if_index;
2273         ifam->_ifam_spare1 = 0;
2274         ifam->ifam_metric = ifa->ifa_ifp->if_metric;
2275
2276         return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
2277 }
2278
2279 static int
2280 sysctl_iflist(int af, struct walkarg *w)
2281 {
2282         struct ifnet *ifp;
2283         struct ifaddr *ifa;
2284         struct if_data ifd;
2285         struct rt_addrinfo info;
2286         int len, error = 0;
2287         struct sockaddr_storage ss;
2288
2289         bzero((caddr_t)&info, sizeof(info));
2290         bzero(&ifd, sizeof(ifd));
2291         CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
2292                 if (w->w_arg && w->w_arg != ifp->if_index)
2293                         continue;
2294                 if_data_copy(ifp, &ifd);
2295                 ifa = ifp->if_addr;
2296                 info.rti_info[RTAX_IFP] = ifa->ifa_addr;
2297                 error = rtsock_msg_buffer(RTM_IFINFO, &info, w, &len);
2298                 if (error != 0)
2299                         goto done;
2300                 info.rti_info[RTAX_IFP] = NULL;
2301                 if (w->w_req && w->w_tmem) {
2302                         if (w->w_op == NET_RT_IFLISTL)
2303                                 error = sysctl_iflist_ifml(ifp, &ifd, &info, w,
2304                                     len);
2305                         else
2306                                 error = sysctl_iflist_ifm(ifp, &ifd, &info, w,
2307                                     len);
2308                         if (error)
2309                                 goto done;
2310                 }
2311                 while ((ifa = CK_STAILQ_NEXT(ifa, ifa_link)) != NULL) {
2312                         if (af && af != ifa->ifa_addr->sa_family)
2313                                 continue;
2314                         if (prison_if(w->w_req->td->td_ucred,
2315                             ifa->ifa_addr) != 0)
2316                                 continue;
2317                         info.rti_info[RTAX_IFA] = ifa->ifa_addr;
2318                         info.rti_info[RTAX_NETMASK] = rtsock_fix_netmask(
2319                             ifa->ifa_addr, ifa->ifa_netmask, &ss);
2320                         info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
2321                         error = rtsock_msg_buffer(RTM_NEWADDR, &info, w, &len);
2322                         if (error != 0)
2323                                 goto done;
2324                         if (w->w_req && w->w_tmem) {
2325                                 if (w->w_op == NET_RT_IFLISTL)
2326                                         error = sysctl_iflist_ifaml(ifa, &info,
2327                                             w, len);
2328                                 else
2329                                         error = sysctl_iflist_ifam(ifa, &info,
2330                                             w, len);
2331                                 if (error)
2332                                         goto done;
2333                         }
2334                 }
2335                 info.rti_info[RTAX_IFA] = NULL;
2336                 info.rti_info[RTAX_NETMASK] = NULL;
2337                 info.rti_info[RTAX_BRD] = NULL;
2338         }
2339 done:
2340         return (error);
2341 }
2342
2343 static int
2344 sysctl_ifmalist(int af, struct walkarg *w)
2345 {
2346         struct rt_addrinfo info;
2347         struct ifaddr *ifa;
2348         struct ifmultiaddr *ifma;
2349         struct ifnet *ifp;
2350         int error, len;
2351
2352         NET_EPOCH_ASSERT();
2353
2354         error = 0;
2355         bzero((caddr_t)&info, sizeof(info));
2356
2357         CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
2358                 if (w->w_arg && w->w_arg != ifp->if_index)
2359                         continue;
2360                 ifa = ifp->if_addr;
2361                 info.rti_info[RTAX_IFP] = ifa ? ifa->ifa_addr : NULL;
2362                 CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
2363                         if (af && af != ifma->ifma_addr->sa_family)
2364                                 continue;
2365                         if (prison_if(w->w_req->td->td_ucred,
2366                             ifma->ifma_addr) != 0)
2367                                 continue;
2368                         info.rti_info[RTAX_IFA] = ifma->ifma_addr;
2369                         info.rti_info[RTAX_GATEWAY] =
2370                             (ifma->ifma_addr->sa_family != AF_LINK) ?
2371                             ifma->ifma_lladdr : NULL;
2372                         error = rtsock_msg_buffer(RTM_NEWMADDR, &info, w, &len);
2373                         if (error != 0)
2374                                 break;
2375                         if (w->w_req && w->w_tmem) {
2376                                 struct ifma_msghdr *ifmam;
2377
2378                                 ifmam = (struct ifma_msghdr *)w->w_tmem;
2379                                 ifmam->ifmam_index = ifma->ifma_ifp->if_index;
2380                                 ifmam->ifmam_flags = 0;
2381                                 ifmam->ifmam_addrs = info.rti_addrs;
2382                                 ifmam->_ifmam_spare1 = 0;
2383                                 error = SYSCTL_OUT(w->w_req, w->w_tmem, len);
2384                                 if (error != 0)
2385                                         break;
2386                         }
2387                 }
2388                 if (error != 0)
2389                         break;
2390         }
2391         return (error);
2392 }
2393
2394 static void
2395 rtable_sysctl_dump(uint32_t fibnum, int family, struct walkarg *w)
2396 {
2397         union sockaddr_union sa_dst, sa_mask;
2398
2399         w->family = family;
2400         w->dst = (struct sockaddr *)&sa_dst;
2401         w->mask = (struct sockaddr *)&sa_mask;
2402
2403         init_sockaddrs_family(family, w->dst, w->mask);
2404
2405         rib_walk(fibnum, family, false, sysctl_dumpentry, w);
2406 }
2407
2408 static int
2409 sysctl_rtsock(SYSCTL_HANDLER_ARGS)
2410 {
2411         struct epoch_tracker et;
2412         int     *name = (int *)arg1;
2413         u_int   namelen = arg2;
2414         struct rib_head *rnh = NULL; /* silence compiler. */
2415         int     i, lim, error = EINVAL;
2416         int     fib = 0;
2417         u_char  af;
2418         struct  walkarg w;
2419
2420         name ++;
2421         namelen--;
2422         if (req->newptr)
2423                 return (EPERM);
2424         if (name[1] == NET_RT_DUMP || name[1] == NET_RT_NHOP || name[1] == NET_RT_NHGRP) {
2425                 if (namelen == 3)
2426                         fib = req->td->td_proc->p_fibnum;
2427                 else if (namelen == 4)
2428                         fib = (name[3] == RT_ALL_FIBS) ?
2429                             req->td->td_proc->p_fibnum : name[3];
2430                 else
2431                         return ((namelen < 3) ? EISDIR : ENOTDIR);
2432                 if (fib < 0 || fib >= rt_numfibs)
2433                         return (EINVAL);
2434         } else if (namelen != 3)
2435                 return ((namelen < 3) ? EISDIR : ENOTDIR);
2436         af = name[0];
2437         if (af > AF_MAX)
2438                 return (EINVAL);
2439         bzero(&w, sizeof(w));
2440         w.w_op = name[1];
2441         w.w_arg = name[2];
2442         w.w_req = req;
2443
2444         error = sysctl_wire_old_buffer(req, 0);
2445         if (error)
2446                 return (error);
2447
2448         /*
2449          * Allocate reply buffer in advance.
2450          * All rtsock messages has maximum length of u_short.
2451          */
2452         w.w_tmemsize = 65536;
2453         w.w_tmem = malloc(w.w_tmemsize, M_TEMP, M_WAITOK);
2454
2455         NET_EPOCH_ENTER(et);
2456         switch (w.w_op) {
2457         case NET_RT_DUMP:
2458         case NET_RT_FLAGS:
2459                 if (af == 0) {                  /* dump all tables */
2460                         i = 1;
2461                         lim = AF_MAX;
2462                 } else                          /* dump only one table */
2463                         i = lim = af;
2464
2465                 /*
2466                  * take care of llinfo entries, the caller must
2467                  * specify an AF
2468                  */
2469                 if (w.w_op == NET_RT_FLAGS &&
2470                     (w.w_arg == 0 || w.w_arg & RTF_LLINFO)) {
2471                         if (af != 0)
2472                                 error = lltable_sysctl_dumparp(af, w.w_req);
2473                         else
2474                                 error = EINVAL;
2475                         break;
2476                 }
2477                 /*
2478                  * take care of routing entries
2479                  */
2480                 for (error = 0; error == 0 && i <= lim; i++) {
2481                         rnh = rt_tables_get_rnh(fib, i);
2482                         if (rnh != NULL) {
2483                                 rtable_sysctl_dump(fib, i, &w);
2484                         } else if (af != 0)
2485                                 error = EAFNOSUPPORT;
2486                 }
2487                 break;
2488         case NET_RT_NHOP:
2489         case NET_RT_NHGRP:
2490                 /* Allow dumping one specific af/fib at a time */
2491                 if (namelen < 4) {
2492                         error = EINVAL;
2493                         break;
2494                 }
2495                 fib = name[3];
2496                 if (fib < 0 || fib > rt_numfibs) {
2497                         error = EINVAL;
2498                         break;
2499                 }
2500                 rnh = rt_tables_get_rnh(fib, af);
2501                 if (rnh == NULL) {
2502                         error = EAFNOSUPPORT;
2503                         break;
2504                 }
2505                 if (w.w_op == NET_RT_NHOP)
2506                         error = nhops_dump_sysctl(rnh, w.w_req);
2507                 else
2508 #ifdef ROUTE_MPATH
2509                         error = nhgrp_dump_sysctl(rnh, w.w_req);
2510 #else
2511                         error = ENOTSUP;
2512 #endif
2513                 break;
2514         case NET_RT_IFLIST:
2515         case NET_RT_IFLISTL:
2516                 error = sysctl_iflist(af, &w);
2517                 break;
2518
2519         case NET_RT_IFMALIST:
2520                 error = sysctl_ifmalist(af, &w);
2521                 break;
2522         }
2523         NET_EPOCH_EXIT(et);
2524
2525         free(w.w_tmem, M_TEMP);
2526         return (error);
2527 }
2528
2529 static SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD | CTLFLAG_MPSAFE,
2530     sysctl_rtsock, "Return route tables and interface/address lists");
2531
2532 /*
2533  * Definitions of protocols supported in the ROUTE domain.
2534  */
2535
2536 static struct domain routedomain;               /* or at least forward */
2537
2538 static struct protosw routesw[] = {
2539 {
2540         .pr_type =              SOCK_RAW,
2541         .pr_domain =            &routedomain,
2542         .pr_flags =             PR_ATOMIC|PR_ADDR,
2543         .pr_output =            route_output,
2544         .pr_ctlinput =          raw_ctlinput,
2545         .pr_init =              raw_init,
2546         .pr_usrreqs =           &route_usrreqs
2547 }
2548 };
2549
2550 static struct domain routedomain = {
2551         .dom_family =           PF_ROUTE,
2552         .dom_name =             "route",
2553         .dom_protosw =          routesw,
2554         .dom_protoswNPROTOSW =  &routesw[nitems(routesw)]
2555 };
2556
2557 VNET_DOMAIN_SET(route);