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