]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/rtsock.c
xnu-4903.270.47.tar.gz
[apple/xnu.git] / bsd / net / rtsock.c
1 /*
2 * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * Copyright (c) 1988, 1991, 1993
30 * The Regents of the University of California. All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)rtsock.c 8.5 (Berkeley) 11/2/94
61 */
62
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kauth.h>
66 #include <sys/kernel.h>
67 #include <sys/sysctl.h>
68 #include <sys/proc.h>
69 #include <sys/malloc.h>
70 #include <sys/mbuf.h>
71 #include <sys/socket.h>
72 #include <sys/socketvar.h>
73 #include <sys/domain.h>
74 #include <sys/protosw.h>
75 #include <sys/syslog.h>
76 #include <sys/mcache.h>
77 #include <kern/locks.h>
78 #include <sys/codesign.h>
79
80 #include <net/if.h>
81 #include <net/route.h>
82 #include <net/dlil.h>
83 #include <net/raw_cb.h>
84 #include <netinet/in.h>
85 #include <netinet/in_var.h>
86 #include <netinet/in_arp.h>
87 #include <netinet/ip.h>
88 #include <netinet/ip6.h>
89 #include <netinet6/nd6.h>
90
91 extern struct rtstat rtstat;
92 extern struct domain routedomain_s;
93 static struct domain *routedomain = NULL;
94
95 MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
96
97 static struct sockaddr route_dst = { 2, PF_ROUTE, { 0, } };
98 static struct sockaddr route_src = { 2, PF_ROUTE, { 0, } };
99 static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, { 0, } };
100
101 struct route_cb {
102 u_int32_t ip_count; /* attached w/ AF_INET */
103 u_int32_t ip6_count; /* attached w/ AF_INET6 */
104 u_int32_t any_count; /* total attached */
105 };
106
107 static struct route_cb route_cb;
108
109 struct walkarg {
110 int w_tmemsize;
111 int w_op, w_arg;
112 caddr_t w_tmem;
113 struct sysctl_req *w_req;
114 };
115
116 static void route_dinit(struct domain *);
117 static int rts_abort(struct socket *);
118 static int rts_attach(struct socket *, int, struct proc *);
119 static int rts_bind(struct socket *, struct sockaddr *, struct proc *);
120 static int rts_connect(struct socket *, struct sockaddr *, struct proc *);
121 static int rts_detach(struct socket *);
122 static int rts_disconnect(struct socket *);
123 static int rts_peeraddr(struct socket *, struct sockaddr **);
124 static int rts_send(struct socket *, int, struct mbuf *, struct sockaddr *,
125 struct mbuf *, struct proc *);
126 static int rts_shutdown(struct socket *);
127 static int rts_sockaddr(struct socket *, struct sockaddr **);
128
129 static int route_output(struct mbuf *, struct socket *);
130 static int rt_setmetrics(u_int32_t, struct rt_metrics *, struct rtentry *);
131 static void rt_getmetrics(struct rtentry *, struct rt_metrics *);
132 static void rt_setif(struct rtentry *, struct sockaddr *, struct sockaddr *,
133 struct sockaddr *, unsigned int);
134 static int rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
135 static struct mbuf *rt_msg1(int, struct rt_addrinfo *);
136 static int rt_msg2(int, struct rt_addrinfo *, caddr_t, struct walkarg *,
137 kauth_cred_t *);
138 static int sysctl_dumpentry(struct radix_node *rn, void *vw);
139 static int sysctl_dumpentry_ext(struct radix_node *rn, void *vw);
140 static int sysctl_iflist(int af, struct walkarg *w);
141 static int sysctl_iflist2(int af, struct walkarg *w);
142 static int sysctl_rtstat(struct sysctl_req *);
143 static int sysctl_rttrash(struct sysctl_req *);
144 static int sysctl_rtsock SYSCTL_HANDLER_ARGS;
145
146 SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD | CTLFLAG_LOCKED,
147 sysctl_rtsock, "");
148
149 SYSCTL_NODE(_net, OID_AUTO, route, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "routing");
150
151 /* Align x to 1024 (only power of 2) assuming x is positive */
152 #define ALIGN_BYTES(x) do { \
153 x = P2ALIGN(x, 1024); \
154 } while(0)
155
156 #define ROUNDUP32(a) \
157 ((a) > 0 ? (1 + (((a) - 1) | (sizeof (uint32_t) - 1))) : \
158 sizeof (uint32_t))
159
160 #define ADVANCE32(x, n) \
161 (x += ROUNDUP32((n)->sa_len))
162
163 /*
164 * It really doesn't make any sense at all for this code to share much
165 * with raw_usrreq.c, since its functionality is so restricted. XXX
166 */
167 static int
168 rts_abort(struct socket *so)
169 {
170 return raw_usrreqs.pru_abort(so);
171 }
172
173 /* pru_accept is EOPNOTSUPP */
174
175 static int
176 rts_attach(struct socket *so, int proto, struct proc *p)
177 {
178 #pragma unused(p)
179 struct rawcb *rp;
180 int error;
181
182 VERIFY(so->so_pcb == NULL);
183
184 MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK | M_ZERO);
185 if (rp == NULL) {
186 return ENOBUFS;
187 }
188
189 so->so_pcb = (caddr_t)rp;
190 /* don't use raw_usrreqs.pru_attach, it checks for SS_PRIV */
191 error = raw_attach(so, proto);
192 rp = sotorawcb(so);
193 if (error) {
194 FREE(rp, M_PCB);
195 so->so_pcb = NULL;
196 so->so_flags |= SOF_PCBCLEARING;
197 return error;
198 }
199
200 switch (rp->rcb_proto.sp_protocol) {
201 case AF_INET:
202 atomic_add_32(&route_cb.ip_count, 1);
203 break;
204 case AF_INET6:
205 atomic_add_32(&route_cb.ip6_count, 1);
206 break;
207 }
208 rp->rcb_faddr = &route_src;
209 atomic_add_32(&route_cb.any_count, 1);
210 /* the socket is already locked when we enter rts_attach */
211 soisconnected(so);
212 so->so_options |= SO_USELOOPBACK;
213 return 0;
214 }
215
216 static int
217 rts_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
218 {
219 return raw_usrreqs.pru_bind(so, nam, p); /* xxx just EINVAL */
220 }
221
222 static int
223 rts_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
224 {
225 return raw_usrreqs.pru_connect(so, nam, p); /* XXX just EINVAL */
226 }
227
228 /* pru_connect2 is EOPNOTSUPP */
229 /* pru_control is EOPNOTSUPP */
230
231 static int
232 rts_detach(struct socket *so)
233 {
234 struct rawcb *rp = sotorawcb(so);
235
236 VERIFY(rp != NULL);
237
238 switch (rp->rcb_proto.sp_protocol) {
239 case AF_INET:
240 atomic_add_32(&route_cb.ip_count, -1);
241 break;
242 case AF_INET6:
243 atomic_add_32(&route_cb.ip6_count, -1);
244 break;
245 }
246 atomic_add_32(&route_cb.any_count, -1);
247 return raw_usrreqs.pru_detach(so);
248 }
249
250 static int
251 rts_disconnect(struct socket *so)
252 {
253 return raw_usrreqs.pru_disconnect(so);
254 }
255
256 /* pru_listen is EOPNOTSUPP */
257
258 static int
259 rts_peeraddr(struct socket *so, struct sockaddr **nam)
260 {
261 return raw_usrreqs.pru_peeraddr(so, nam);
262 }
263
264 /* pru_rcvd is EOPNOTSUPP */
265 /* pru_rcvoob is EOPNOTSUPP */
266
267 static int
268 rts_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
269 struct mbuf *control, struct proc *p)
270 {
271 return raw_usrreqs.pru_send(so, flags, m, nam, control, p);
272 }
273
274 /* pru_sense is null */
275
276 static int
277 rts_shutdown(struct socket *so)
278 {
279 return raw_usrreqs.pru_shutdown(so);
280 }
281
282 static int
283 rts_sockaddr(struct socket *so, struct sockaddr **nam)
284 {
285 return raw_usrreqs.pru_sockaddr(so, nam);
286 }
287
288 static struct pr_usrreqs route_usrreqs = {
289 .pru_abort = rts_abort,
290 .pru_attach = rts_attach,
291 .pru_bind = rts_bind,
292 .pru_connect = rts_connect,
293 .pru_detach = rts_detach,
294 .pru_disconnect = rts_disconnect,
295 .pru_peeraddr = rts_peeraddr,
296 .pru_send = rts_send,
297 .pru_shutdown = rts_shutdown,
298 .pru_sockaddr = rts_sockaddr,
299 .pru_sosend = sosend,
300 .pru_soreceive = soreceive,
301 };
302
303 /*ARGSUSED*/
304 static int
305 route_output(struct mbuf *m, struct socket *so)
306 {
307 struct rt_msghdr *rtm = NULL;
308 struct rtentry *rt = NULL;
309 struct rtentry *saved_nrt = NULL;
310 struct radix_node_head *rnh;
311 struct rt_addrinfo info;
312 int len, error = 0;
313 sa_family_t dst_sa_family = 0;
314 struct ifnet *ifp = NULL;
315 struct sockaddr_in dst_in, gate_in;
316 int sendonlytoself = 0;
317 unsigned int ifscope = IFSCOPE_NONE;
318 struct rawcb *rp = NULL;
319 boolean_t is_router = FALSE;
320 #define senderr(e) { error = (e); goto flush; }
321 if (m == NULL || ((m->m_len < sizeof(intptr_t)) &&
322 (m = m_pullup(m, sizeof(intptr_t))) == NULL)) {
323 return ENOBUFS;
324 }
325 VERIFY(m->m_flags & M_PKTHDR);
326
327 /*
328 * Unlock the socket (but keep a reference) it won't be
329 * accessed until raw_input appends to it.
330 */
331 socket_unlock(so, 0);
332 lck_mtx_lock(rnh_lock);
333
334 len = m->m_pkthdr.len;
335 if (len < sizeof(*rtm) ||
336 len != mtod(m, struct rt_msghdr *)->rtm_msglen) {
337 info.rti_info[RTAX_DST] = NULL;
338 senderr(EINVAL);
339 }
340 R_Malloc(rtm, struct rt_msghdr *, len);
341 if (rtm == NULL) {
342 info.rti_info[RTAX_DST] = NULL;
343 senderr(ENOBUFS);
344 }
345 m_copydata(m, 0, len, (caddr_t)rtm);
346 if (rtm->rtm_version != RTM_VERSION) {
347 info.rti_info[RTAX_DST] = NULL;
348 senderr(EPROTONOSUPPORT);
349 }
350
351 /*
352 * Silent version of RTM_GET for Reachabiltiy APIs. We may change
353 * all RTM_GETs to be silent in the future, so this is private for now.
354 */
355 if (rtm->rtm_type == RTM_GET_SILENT) {
356 if (!(so->so_options & SO_USELOOPBACK)) {
357 senderr(EINVAL);
358 }
359 sendonlytoself = 1;
360 rtm->rtm_type = RTM_GET;
361 }
362
363 /*
364 * Perform permission checking, only privileged sockets
365 * may perform operations other than RTM_GET
366 */
367 if (rtm->rtm_type != RTM_GET && !(so->so_state & SS_PRIV)) {
368 info.rti_info[RTAX_DST] = NULL;
369 senderr(EPERM);
370 }
371
372 rtm->rtm_pid = proc_selfpid();
373 info.rti_addrs = rtm->rtm_addrs;
374 if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) {
375 info.rti_info[RTAX_DST] = NULL;
376 senderr(EINVAL);
377 }
378 if (info.rti_info[RTAX_DST] == NULL ||
379 info.rti_info[RTAX_DST]->sa_family >= AF_MAX ||
380 (info.rti_info[RTAX_GATEWAY] != NULL &&
381 info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX)) {
382 senderr(EINVAL);
383 }
384
385 if (info.rti_info[RTAX_DST]->sa_family == AF_INET &&
386 info.rti_info[RTAX_DST]->sa_len != sizeof(dst_in)) {
387 /* At minimum, we need up to sin_addr */
388 if (info.rti_info[RTAX_DST]->sa_len <
389 offsetof(struct sockaddr_in, sin_zero)) {
390 senderr(EINVAL);
391 }
392 bzero(&dst_in, sizeof(dst_in));
393 dst_in.sin_len = sizeof(dst_in);
394 dst_in.sin_family = AF_INET;
395 dst_in.sin_port = SIN(info.rti_info[RTAX_DST])->sin_port;
396 dst_in.sin_addr = SIN(info.rti_info[RTAX_DST])->sin_addr;
397 info.rti_info[RTAX_DST] = (struct sockaddr *)&dst_in;
398 dst_sa_family = info.rti_info[RTAX_DST]->sa_family;
399 }
400
401 if (info.rti_info[RTAX_GATEWAY] != NULL &&
402 info.rti_info[RTAX_GATEWAY]->sa_family == AF_INET &&
403 info.rti_info[RTAX_GATEWAY]->sa_len != sizeof(gate_in)) {
404 /* At minimum, we need up to sin_addr */
405 if (info.rti_info[RTAX_GATEWAY]->sa_len <
406 offsetof(struct sockaddr_in, sin_zero)) {
407 senderr(EINVAL);
408 }
409 bzero(&gate_in, sizeof(gate_in));
410 gate_in.sin_len = sizeof(gate_in);
411 gate_in.sin_family = AF_INET;
412 gate_in.sin_port = SIN(info.rti_info[RTAX_GATEWAY])->sin_port;
413 gate_in.sin_addr = SIN(info.rti_info[RTAX_GATEWAY])->sin_addr;
414 info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gate_in;
415 }
416
417 if (info.rti_info[RTAX_GENMASK]) {
418 struct radix_node *t;
419 t = rn_addmask((caddr_t)info.rti_info[RTAX_GENMASK], 0, 1);
420 if (t != NULL && Bcmp(info.rti_info[RTAX_GENMASK],
421 t->rn_key, *(u_char *)info.rti_info[RTAX_GENMASK]) == 0) {
422 info.rti_info[RTAX_GENMASK] =
423 (struct sockaddr *)(t->rn_key);
424 } else {
425 senderr(ENOBUFS);
426 }
427 }
428
429 /*
430 * If RTF_IFSCOPE flag is set, then rtm_index specifies the scope.
431 */
432 if (rtm->rtm_flags & RTF_IFSCOPE) {
433 if (info.rti_info[RTAX_DST]->sa_family != AF_INET &&
434 info.rti_info[RTAX_DST]->sa_family != AF_INET6) {
435 senderr(EINVAL);
436 }
437 ifscope = rtm->rtm_index;
438 }
439 /*
440 * Block changes on INTCOPROC interfaces.
441 */
442 if (ifscope) {
443 unsigned int intcoproc_scope = 0;
444 ifnet_head_lock_shared();
445 TAILQ_FOREACH(ifp, &ifnet_head, if_link) {
446 if (IFNET_IS_INTCOPROC(ifp)) {
447 intcoproc_scope = ifp->if_index;
448 break;
449 }
450 }
451 ifnet_head_done();
452 if (intcoproc_scope == ifscope && current_proc()->p_pid != 0) {
453 senderr(EINVAL);
454 }
455 }
456
457 /*
458 * RTF_PROXY can only be set internally from within the kernel.
459 */
460 if (rtm->rtm_flags & RTF_PROXY) {
461 senderr(EINVAL);
462 }
463
464 /*
465 * For AF_INET, always zero out the embedded scope ID. If this is
466 * a scoped request, it must be done explicitly by setting RTF_IFSCOPE
467 * flag and the corresponding rtm_index value. This is to prevent
468 * false interpretation of the scope ID because it's using the sin_zero
469 * field, which might not be properly cleared by the requestor.
470 */
471 if (info.rti_info[RTAX_DST]->sa_family == AF_INET) {
472 sin_set_ifscope(info.rti_info[RTAX_DST], IFSCOPE_NONE);
473 }
474 if (info.rti_info[RTAX_GATEWAY] != NULL &&
475 info.rti_info[RTAX_GATEWAY]->sa_family == AF_INET) {
476 sin_set_ifscope(info.rti_info[RTAX_GATEWAY], IFSCOPE_NONE);
477 }
478 switch (rtm->rtm_type) {
479 case RTM_ADD:
480 if (info.rti_info[RTAX_GATEWAY] == NULL) {
481 senderr(EINVAL);
482 }
483
484 error = rtrequest_scoped_locked(RTM_ADD,
485 info.rti_info[RTAX_DST], info.rti_info[RTAX_GATEWAY],
486 info.rti_info[RTAX_NETMASK], rtm->rtm_flags, &saved_nrt,
487 ifscope);
488 if (error == 0 && saved_nrt != NULL) {
489 RT_LOCK(saved_nrt);
490 /*
491 * If the route request specified an interface with
492 * IFA and/or IFP, we set the requested interface on
493 * the route with rt_setif. It would be much better
494 * to do this inside rtrequest, but that would
495 * require passing the desired interface, in some
496 * form, to rtrequest. Since rtrequest is called in
497 * so many places (roughly 40 in our source), adding
498 * a parameter is to much for us to swallow; this is
499 * something for the FreeBSD developers to tackle.
500 * Instead, we let rtrequest compute whatever
501 * interface it wants, then come in behind it and
502 * stick in the interface that we really want. This
503 * works reasonably well except when rtrequest can't
504 * figure out what interface to use (with
505 * ifa_withroute) and returns ENETUNREACH. Ideally
506 * it shouldn't matter if rtrequest can't figure out
507 * the interface if we're going to explicitly set it
508 * ourselves anyway. But practically we can't
509 * recover here because rtrequest will not do any of
510 * the work necessary to add the route if it can't
511 * find an interface. As long as there is a default
512 * route that leads to some interface, rtrequest will
513 * find an interface, so this problem should be
514 * rarely encountered.
515 * dwiggins@bbn.com
516 */
517 rt_setif(saved_nrt,
518 info.rti_info[RTAX_IFP], info.rti_info[RTAX_IFA],
519 info.rti_info[RTAX_GATEWAY], ifscope);
520 (void)rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, saved_nrt);
521 saved_nrt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
522 saved_nrt->rt_rmx.rmx_locks |=
523 (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);
524 saved_nrt->rt_genmask = info.rti_info[RTAX_GENMASK];
525 RT_REMREF_LOCKED(saved_nrt);
526 RT_UNLOCK(saved_nrt);
527 }
528 break;
529
530 case RTM_DELETE:
531 error = rtrequest_scoped_locked(RTM_DELETE,
532 info.rti_info[RTAX_DST], info.rti_info[RTAX_GATEWAY],
533 info.rti_info[RTAX_NETMASK], rtm->rtm_flags, &saved_nrt,
534 ifscope);
535 if (error == 0) {
536 rt = saved_nrt;
537 RT_LOCK(rt);
538 goto report;
539 }
540 break;
541
542 case RTM_GET:
543 case RTM_CHANGE:
544 case RTM_LOCK:
545 rnh = rt_tables[info.rti_info[RTAX_DST]->sa_family];
546 if (rnh == NULL) {
547 senderr(EAFNOSUPPORT);
548 }
549 /*
550 * Lookup the best match based on the key-mask pair;
551 * callee adds a reference and checks for root node.
552 */
553 rt = rt_lookup(TRUE, info.rti_info[RTAX_DST],
554 info.rti_info[RTAX_NETMASK], rnh, ifscope);
555 if (rt == NULL) {
556 senderr(ESRCH);
557 }
558 RT_LOCK(rt);
559
560 /*
561 * Holding rnh_lock here prevents the possibility of
562 * ifa from changing (e.g. in_ifinit), so it is safe
563 * to access its ifa_addr (down below) without locking.
564 */
565 switch (rtm->rtm_type) {
566 case RTM_GET: {
567 kauth_cred_t cred;
568 kauth_cred_t* credp;
569 struct ifaddr *ifa2;
570 report:
571 cred = kauth_cred_proc_ref(current_proc());
572 credp = &cred;
573
574 ifa2 = NULL;
575 RT_LOCK_ASSERT_HELD(rt);
576 info.rti_info[RTAX_DST] = rt_key(rt);
577 dst_sa_family = info.rti_info[RTAX_DST]->sa_family;
578 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
579 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
580 info.rti_info[RTAX_GENMASK] = rt->rt_genmask;
581 if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
582 ifp = rt->rt_ifp;
583 if (ifp != NULL) {
584 ifnet_lock_shared(ifp);
585 ifa2 = ifp->if_lladdr;
586 info.rti_info[RTAX_IFP] =
587 ifa2->ifa_addr;
588 IFA_ADDREF(ifa2);
589 ifnet_lock_done(ifp);
590 info.rti_info[RTAX_IFA] =
591 rt->rt_ifa->ifa_addr;
592 rtm->rtm_index = ifp->if_index;
593 } else {
594 info.rti_info[RTAX_IFP] = NULL;
595 info.rti_info[RTAX_IFA] = NULL;
596 }
597 } else if ((ifp = rt->rt_ifp) != NULL) {
598 rtm->rtm_index = ifp->if_index;
599 }
600 if (ifa2 != NULL) {
601 IFA_LOCK(ifa2);
602 }
603 len = rt_msg2(rtm->rtm_type, &info, NULL, NULL, credp);
604 if (ifa2 != NULL) {
605 IFA_UNLOCK(ifa2);
606 }
607 struct rt_msghdr *out_rtm;
608 R_Malloc(out_rtm, struct rt_msghdr *, len);
609 if (out_rtm == NULL) {
610 RT_UNLOCK(rt);
611 if (ifa2 != NULL) {
612 IFA_REMREF(ifa2);
613 }
614 senderr(ENOBUFS);
615 }
616 Bcopy(rtm, out_rtm, sizeof(struct rt_msghdr));
617 if (ifa2 != NULL) {
618 IFA_LOCK(ifa2);
619 }
620 (void) rt_msg2(out_rtm->rtm_type, &info, (caddr_t)out_rtm,
621 NULL, &cred);
622 if (ifa2 != NULL) {
623 IFA_UNLOCK(ifa2);
624 }
625 R_Free(rtm);
626 rtm = out_rtm;
627 rtm->rtm_flags = rt->rt_flags;
628 rt_getmetrics(rt, &rtm->rtm_rmx);
629 rtm->rtm_addrs = info.rti_addrs;
630 if (ifa2 != NULL) {
631 IFA_REMREF(ifa2);
632 }
633
634 kauth_cred_unref(&cred);
635 break;
636 }
637
638 case RTM_CHANGE:
639 is_router = (rt->rt_flags & RTF_ROUTER) ? TRUE : FALSE;
640
641 if (info.rti_info[RTAX_GATEWAY] != NULL &&
642 (error = rt_setgate(rt, rt_key(rt),
643 info.rti_info[RTAX_GATEWAY]))) {
644 int tmp = error;
645 RT_UNLOCK(rt);
646 senderr(tmp);
647 }
648 /*
649 * If they tried to change things but didn't specify
650 * the required gateway, then just use the old one.
651 * This can happen if the user tries to change the
652 * flags on the default route without changing the
653 * default gateway. Changing flags still doesn't work.
654 */
655 if ((rt->rt_flags & RTF_GATEWAY) &&
656 info.rti_info[RTAX_GATEWAY] == NULL) {
657 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
658 }
659
660 /*
661 * On Darwin, we call rt_setif which contains the
662 * equivalent to the code found at this very spot
663 * in BSD.
664 */
665 rt_setif(rt,
666 info.rti_info[RTAX_IFP], info.rti_info[RTAX_IFA],
667 info.rti_info[RTAX_GATEWAY], ifscope);
668
669 if ((error = rt_setmetrics(rtm->rtm_inits,
670 &rtm->rtm_rmx, rt))) {
671 int tmp = error;
672 RT_UNLOCK(rt);
673 senderr(tmp);
674 }
675 if (info.rti_info[RTAX_GENMASK]) {
676 rt->rt_genmask = info.rti_info[RTAX_GENMASK];
677 }
678
679 /*
680 * Enqueue work item to invoke callback for this route entry
681 * This may not be needed always, but for now issue it anytime
682 * RTM_CHANGE gets called.
683 */
684 route_event_enqueue_nwk_wq_entry(rt, NULL, ROUTE_ENTRY_REFRESH, NULL, TRUE);
685 /*
686 * If the route is for a router, walk the tree to send refresh
687 * event to protocol cloned entries
688 */
689 if (is_router) {
690 struct route_event rt_ev;
691 route_event_init(&rt_ev, rt, NULL, ROUTE_ENTRY_REFRESH);
692 RT_UNLOCK(rt);
693 (void) rnh->rnh_walktree(rnh, route_event_walktree, (void *)&rt_ev);
694 RT_LOCK(rt);
695 }
696 /* FALLTHRU */
697 case RTM_LOCK:
698 rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);
699 rt->rt_rmx.rmx_locks |=
700 (rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);
701 break;
702 }
703 RT_UNLOCK(rt);
704 break;
705 default:
706 senderr(EOPNOTSUPP);
707 }
708 flush:
709 if (rtm != NULL) {
710 if (error) {
711 rtm->rtm_errno = error;
712 } else {
713 rtm->rtm_flags |= RTF_DONE;
714 }
715 }
716 if (rt != NULL) {
717 RT_LOCK_ASSERT_NOTHELD(rt);
718 rtfree_locked(rt);
719 }
720 lck_mtx_unlock(rnh_lock);
721
722 /* relock the socket now */
723 socket_lock(so, 0);
724 /*
725 * Check to see if we don't want our own messages.
726 */
727 if (!(so->so_options & SO_USELOOPBACK)) {
728 if (route_cb.any_count <= 1) {
729 if (rtm != NULL) {
730 R_Free(rtm);
731 }
732 m_freem(m);
733 return error;
734 }
735 /* There is another listener, so construct message */
736 rp = sotorawcb(so);
737 }
738 if (rtm != NULL) {
739 m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);
740 if (m->m_pkthdr.len < rtm->rtm_msglen) {
741 m_freem(m);
742 m = NULL;
743 } else if (m->m_pkthdr.len > rtm->rtm_msglen) {
744 m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len);
745 }
746 R_Free(rtm);
747 }
748 if (sendonlytoself && m != NULL) {
749 error = 0;
750 if (sbappendaddr(&so->so_rcv, &route_src, m,
751 NULL, &error) != 0) {
752 sorwakeup(so);
753 }
754 if (error) {
755 return error;
756 }
757 } else {
758 struct sockproto route_proto = { PF_ROUTE, 0 };
759 if (rp != NULL) {
760 rp->rcb_proto.sp_family = 0; /* Avoid us */
761 }
762 if (dst_sa_family != 0) {
763 route_proto.sp_protocol = dst_sa_family;
764 }
765 if (m != NULL) {
766 socket_unlock(so, 0);
767 raw_input(m, &route_proto, &route_src, &route_dst);
768 socket_lock(so, 0);
769 }
770 if (rp != NULL) {
771 rp->rcb_proto.sp_family = PF_ROUTE;
772 }
773 }
774 return error;
775 }
776
777 void
778 rt_setexpire(struct rtentry *rt, uint64_t expiry)
779 {
780 /* set both rt_expire and rmx_expire */
781 rt->rt_expire = expiry;
782 if (expiry) {
783 rt->rt_rmx.rmx_expire = expiry + rt->base_calendartime -
784 rt->base_uptime;
785 } else {
786 rt->rt_rmx.rmx_expire = 0;
787 }
788 }
789
790 static int
791 rt_setmetrics(u_int32_t which, struct rt_metrics *in, struct rtentry *out)
792 {
793 if (!(which & RTV_REFRESH_HOST)) {
794 struct timeval caltime;
795 getmicrotime(&caltime);
796 #define metric(f, e) if (which & (f)) out->rt_rmx.e = in->e;
797 metric(RTV_RPIPE, rmx_recvpipe);
798 metric(RTV_SPIPE, rmx_sendpipe);
799 metric(RTV_SSTHRESH, rmx_ssthresh);
800 metric(RTV_RTT, rmx_rtt);
801 metric(RTV_RTTVAR, rmx_rttvar);
802 metric(RTV_HOPCOUNT, rmx_hopcount);
803 metric(RTV_MTU, rmx_mtu);
804 metric(RTV_EXPIRE, rmx_expire);
805 #undef metric
806 if (out->rt_rmx.rmx_expire > 0) {
807 /* account for system time change */
808 getmicrotime(&caltime);
809 out->base_calendartime +=
810 NET_CALCULATE_CLOCKSKEW(caltime,
811 out->base_calendartime,
812 net_uptime(), out->base_uptime);
813 rt_setexpire(out,
814 out->rt_rmx.rmx_expire -
815 out->base_calendartime +
816 out->base_uptime);
817 } else {
818 rt_setexpire(out, 0);
819 }
820
821 VERIFY(out->rt_expire == 0 || out->rt_rmx.rmx_expire != 0);
822 VERIFY(out->rt_expire != 0 || out->rt_rmx.rmx_expire == 0);
823 } else {
824 /* Only RTV_REFRESH_HOST must be set */
825 if ((which & ~RTV_REFRESH_HOST) ||
826 (out->rt_flags & RTF_STATIC) ||
827 !(out->rt_flags & RTF_LLINFO)) {
828 return EINVAL;
829 }
830
831 if (out->rt_llinfo_refresh == NULL) {
832 return ENOTSUP;
833 }
834
835 out->rt_llinfo_refresh(out);
836 }
837 return 0;
838 }
839
840 static void
841 rt_getmetrics(struct rtentry *in, struct rt_metrics *out)
842 {
843 struct timeval caltime;
844
845 VERIFY(in->rt_expire == 0 || in->rt_rmx.rmx_expire != 0);
846 VERIFY(in->rt_expire != 0 || in->rt_rmx.rmx_expire == 0);
847
848 *out = in->rt_rmx;
849
850 if (in->rt_expire != 0) {
851 /* account for system time change */
852 getmicrotime(&caltime);
853
854 in->base_calendartime +=
855 NET_CALCULATE_CLOCKSKEW(caltime,
856 in->base_calendartime, net_uptime(), in->base_uptime);
857
858 out->rmx_expire = in->base_calendartime +
859 in->rt_expire - in->base_uptime;
860 } else {
861 out->rmx_expire = 0;
862 }
863 }
864
865 /*
866 * Set route's interface given info.rti_info[RTAX_IFP],
867 * info.rti_info[RTAX_IFA], and gateway.
868 */
869 static void
870 rt_setif(struct rtentry *rt, struct sockaddr *Ifpaddr, struct sockaddr *Ifaaddr,
871 struct sockaddr *Gate, unsigned int ifscope)
872 {
873 struct ifaddr *ifa = NULL;
874 struct ifnet *ifp = NULL;
875 void (*ifa_rtrequest)(int, struct rtentry *, struct sockaddr *);
876
877 LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
878
879 RT_LOCK_ASSERT_HELD(rt);
880
881 /* Don't update a defunct route */
882 if (rt->rt_flags & RTF_CONDEMNED) {
883 return;
884 }
885
886 /* Add an extra ref for ourselves */
887 RT_ADDREF_LOCKED(rt);
888
889 /* Become a regular mutex, just in case */
890 RT_CONVERT_LOCK(rt);
891
892 /*
893 * New gateway could require new ifaddr, ifp; flags may also
894 * be different; ifp may be specified by ll sockaddr when
895 * protocol address is ambiguous.
896 */
897 if (Ifpaddr && (ifa = ifa_ifwithnet_scoped(Ifpaddr, ifscope)) &&
898 (ifp = ifa->ifa_ifp) && (Ifaaddr || Gate)) {
899 IFA_REMREF(ifa);
900 ifa = ifaof_ifpforaddr(Ifaaddr ? Ifaaddr : Gate, ifp);
901 } else {
902 if (ifa != NULL) {
903 IFA_REMREF(ifa);
904 ifa = NULL;
905 }
906 if (Ifpaddr && (ifp = if_withname(Ifpaddr))) {
907 if (Gate) {
908 ifa = ifaof_ifpforaddr(Gate, ifp);
909 } else {
910 ifnet_lock_shared(ifp);
911 ifa = TAILQ_FIRST(&ifp->if_addrhead);
912 if (ifa != NULL) {
913 IFA_ADDREF(ifa);
914 }
915 ifnet_lock_done(ifp);
916 }
917 } else if (Ifaaddr &&
918 (ifa = ifa_ifwithaddr_scoped(Ifaaddr, ifscope))) {
919 ifp = ifa->ifa_ifp;
920 } else if (Gate != NULL) {
921 /*
922 * Safe to drop rt_lock and use rt_key, since holding
923 * rnh_lock here prevents another thread from calling
924 * rt_setgate() on this route. We cannot hold the
925 * lock across ifa_ifwithroute since the lookup done
926 * by that routine may point to the same route.
927 */
928 RT_UNLOCK(rt);
929 if ((ifa = ifa_ifwithroute_scoped_locked(rt->rt_flags,
930 rt_key(rt), Gate, ifscope)) != NULL) {
931 ifp = ifa->ifa_ifp;
932 }
933 RT_LOCK(rt);
934 /* Don't update a defunct route */
935 if (rt->rt_flags & RTF_CONDEMNED) {
936 if (ifa != NULL) {
937 IFA_REMREF(ifa);
938 }
939 /* Release extra ref */
940 RT_REMREF_LOCKED(rt);
941 return;
942 }
943 }
944 }
945
946 /* trigger route cache reevaluation */
947 if (rt_key(rt)->sa_family == AF_INET) {
948 routegenid_inet_update();
949 }
950 #if INET6
951 else if (rt_key(rt)->sa_family == AF_INET6) {
952 routegenid_inet6_update();
953 }
954 #endif /* INET6 */
955
956 if (ifa != NULL) {
957 struct ifaddr *oifa = rt->rt_ifa;
958 if (oifa != ifa) {
959 if (oifa != NULL) {
960 IFA_LOCK_SPIN(oifa);
961 ifa_rtrequest = oifa->ifa_rtrequest;
962 IFA_UNLOCK(oifa);
963 if (ifa_rtrequest != NULL) {
964 ifa_rtrequest(RTM_DELETE, rt, Gate);
965 }
966 }
967 rtsetifa(rt, ifa);
968
969 if (rt->rt_ifp != ifp) {
970 /*
971 * Purge any link-layer info caching.
972 */
973 if (rt->rt_llinfo_purge != NULL) {
974 rt->rt_llinfo_purge(rt);
975 }
976
977 /*
978 * Adjust route ref count for the interfaces.
979 */
980 if (rt->rt_if_ref_fn != NULL) {
981 rt->rt_if_ref_fn(ifp, 1);
982 rt->rt_if_ref_fn(rt->rt_ifp, -1);
983 }
984 }
985 rt->rt_ifp = ifp;
986 /*
987 * If this is the (non-scoped) default route, record
988 * the interface index used for the primary ifscope.
989 */
990 if (rt_primary_default(rt, rt_key(rt))) {
991 set_primary_ifscope(rt_key(rt)->sa_family,
992 rt->rt_ifp->if_index);
993 }
994 /*
995 * If rmx_mtu is not locked, update it
996 * to the MTU used by the new interface.
997 */
998 if (!(rt->rt_rmx.rmx_locks & RTV_MTU)) {
999 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
1000 if (rt_key(rt)->sa_family == AF_INET &&
1001 INTF_ADJUST_MTU_FOR_CLAT46(ifp)) {
1002 rt->rt_rmx.rmx_mtu = IN6_LINKMTU(rt->rt_ifp);
1003 /* Further adjust the size for CLAT46 expansion */
1004 rt->rt_rmx.rmx_mtu -= CLAT46_HDR_EXPANSION_OVERHD;
1005 }
1006 }
1007
1008 if (rt->rt_ifa != NULL) {
1009 IFA_LOCK_SPIN(rt->rt_ifa);
1010 ifa_rtrequest = rt->rt_ifa->ifa_rtrequest;
1011 IFA_UNLOCK(rt->rt_ifa);
1012 if (ifa_rtrequest != NULL) {
1013 ifa_rtrequest(RTM_ADD, rt, Gate);
1014 }
1015 }
1016 IFA_REMREF(ifa);
1017 /* Release extra ref */
1018 RT_REMREF_LOCKED(rt);
1019 return;
1020 }
1021 IFA_REMREF(ifa);
1022 ifa = NULL;
1023 }
1024
1025 /* XXX: to reset gateway to correct value, at RTM_CHANGE */
1026 if (rt->rt_ifa != NULL) {
1027 IFA_LOCK_SPIN(rt->rt_ifa);
1028 ifa_rtrequest = rt->rt_ifa->ifa_rtrequest;
1029 IFA_UNLOCK(rt->rt_ifa);
1030 if (ifa_rtrequest != NULL) {
1031 ifa_rtrequest(RTM_ADD, rt, Gate);
1032 }
1033 }
1034
1035 /*
1036 * Workaround for local address routes pointing to the loopback
1037 * interface added by configd, until <rdar://problem/12970142>.
1038 */
1039 if ((rt->rt_ifp->if_flags & IFF_LOOPBACK) &&
1040 (rt->rt_flags & RTF_HOST) && rt->rt_ifa->ifa_ifp == rt->rt_ifp) {
1041 ifa = ifa_ifwithaddr(rt_key(rt));
1042 if (ifa != NULL) {
1043 if (ifa != rt->rt_ifa) {
1044 rtsetifa(rt, ifa);
1045 }
1046 IFA_REMREF(ifa);
1047 }
1048 }
1049
1050 /* Release extra ref */
1051 RT_REMREF_LOCKED(rt);
1052 }
1053
1054 /*
1055 * Extract the addresses of the passed sockaddrs.
1056 * Do a little sanity checking so as to avoid bad memory references.
1057 * This data is derived straight from userland.
1058 */
1059 static int
1060 rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo)
1061 {
1062 struct sockaddr *sa;
1063 int i;
1064
1065 bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info));
1066 for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
1067 if ((rtinfo->rti_addrs & (1 << i)) == 0) {
1068 continue;
1069 }
1070 sa = (struct sockaddr *)cp;
1071 /*
1072 * It won't fit.
1073 */
1074 if ((cp + sa->sa_len) > cplim) {
1075 return EINVAL;
1076 }
1077 /*
1078 * there are no more.. quit now
1079 * If there are more bits, they are in error.
1080 * I've seen this. route(1) can evidently generate these.
1081 * This causes kernel to core dump.
1082 * for compatibility, If we see this, point to a safe address.
1083 */
1084 if (sa->sa_len == 0) {
1085 rtinfo->rti_info[i] = &sa_zero;
1086 return 0; /* should be EINVAL but for compat */
1087 }
1088 /* accept it */
1089 rtinfo->rti_info[i] = sa;
1090 ADVANCE32(cp, sa);
1091 }
1092 return 0;
1093 }
1094
1095 static struct mbuf *
1096 rt_msg1(int type, struct rt_addrinfo *rtinfo)
1097 {
1098 struct rt_msghdr *rtm;
1099 struct mbuf *m;
1100 int i;
1101 int len, dlen, off;
1102
1103 switch (type) {
1104 case RTM_DELADDR:
1105 case RTM_NEWADDR:
1106 len = sizeof(struct ifa_msghdr);
1107 break;
1108
1109 case RTM_DELMADDR:
1110 case RTM_NEWMADDR:
1111 len = sizeof(struct ifma_msghdr);
1112 break;
1113
1114 case RTM_IFINFO:
1115 len = sizeof(struct if_msghdr);
1116 break;
1117
1118 default:
1119 len = sizeof(struct rt_msghdr);
1120 }
1121 m = m_gethdr(M_DONTWAIT, MT_DATA);
1122 if (m && len > MHLEN) {
1123 MCLGET(m, M_DONTWAIT);
1124 if (!(m->m_flags & M_EXT)) {
1125 m_free(m);
1126 m = NULL;
1127 }
1128 }
1129 if (m == NULL) {
1130 return NULL;
1131 }
1132 m->m_pkthdr.len = m->m_len = len;
1133 m->m_pkthdr.rcvif = NULL;
1134 rtm = mtod(m, struct rt_msghdr *);
1135 bzero((caddr_t)rtm, len);
1136 off = len;
1137 for (i = 0; i < RTAX_MAX; i++) {
1138 struct sockaddr *sa, *hint;
1139 uint8_t ssbuf[SOCK_MAXADDRLEN + 1];
1140
1141 /*
1142 * Make sure to accomodate the largest possible size of sa_len.
1143 */
1144 _CASSERT(sizeof(ssbuf) == (SOCK_MAXADDRLEN + 1));
1145
1146 if ((sa = rtinfo->rti_info[i]) == NULL) {
1147 continue;
1148 }
1149
1150 switch (i) {
1151 case RTAX_DST:
1152 case RTAX_NETMASK:
1153 if ((hint = rtinfo->rti_info[RTAX_DST]) == NULL) {
1154 hint = rtinfo->rti_info[RTAX_IFA];
1155 }
1156
1157 /* Scrub away any trace of embedded interface scope */
1158 sa = rtm_scrub(type, i, hint, sa, &ssbuf,
1159 sizeof(ssbuf), NULL);
1160 break;
1161
1162 default:
1163 break;
1164 }
1165
1166 rtinfo->rti_addrs |= (1 << i);
1167 dlen = sa->sa_len;
1168 m_copyback(m, off, dlen, (caddr_t)sa);
1169 len = off + dlen;
1170 off += ROUNDUP32(dlen);
1171 }
1172 if (m->m_pkthdr.len != len) {
1173 m_freem(m);
1174 return NULL;
1175 }
1176 rtm->rtm_msglen = len;
1177 rtm->rtm_version = RTM_VERSION;
1178 rtm->rtm_type = type;
1179 return m;
1180 }
1181
1182 static int
1183 rt_msg2(int type, struct rt_addrinfo *rtinfo, caddr_t cp, struct walkarg *w,
1184 kauth_cred_t* credp)
1185 {
1186 int i;
1187 int len, dlen, rlen, second_time = 0;
1188 caddr_t cp0;
1189
1190 rtinfo->rti_addrs = 0;
1191 again:
1192 switch (type) {
1193 case RTM_DELADDR:
1194 case RTM_NEWADDR:
1195 len = sizeof(struct ifa_msghdr);
1196 break;
1197
1198 case RTM_DELMADDR:
1199 case RTM_NEWMADDR:
1200 len = sizeof(struct ifma_msghdr);
1201 break;
1202
1203 case RTM_IFINFO:
1204 len = sizeof(struct if_msghdr);
1205 break;
1206
1207 case RTM_IFINFO2:
1208 len = sizeof(struct if_msghdr2);
1209 break;
1210
1211 case RTM_NEWMADDR2:
1212 len = sizeof(struct ifma_msghdr2);
1213 break;
1214
1215 case RTM_GET_EXT:
1216 len = sizeof(struct rt_msghdr_ext);
1217 break;
1218
1219 case RTM_GET2:
1220 len = sizeof(struct rt_msghdr2);
1221 break;
1222
1223 default:
1224 len = sizeof(struct rt_msghdr);
1225 }
1226 cp0 = cp;
1227 if (cp0) {
1228 cp += len;
1229 }
1230 for (i = 0; i < RTAX_MAX; i++) {
1231 struct sockaddr *sa, *hint;
1232 uint8_t ssbuf[SOCK_MAXADDRLEN + 1];
1233
1234 /*
1235 * Make sure to accomodate the largest possible size of sa_len.
1236 */
1237 _CASSERT(sizeof(ssbuf) == (SOCK_MAXADDRLEN + 1));
1238
1239 if ((sa = rtinfo->rti_info[i]) == NULL) {
1240 continue;
1241 }
1242
1243 switch (i) {
1244 case RTAX_DST:
1245 case RTAX_NETMASK:
1246 if ((hint = rtinfo->rti_info[RTAX_DST]) == NULL) {
1247 hint = rtinfo->rti_info[RTAX_IFA];
1248 }
1249
1250 /* Scrub away any trace of embedded interface scope */
1251 sa = rtm_scrub(type, i, hint, sa, &ssbuf,
1252 sizeof(ssbuf), NULL);
1253 break;
1254 case RTAX_GATEWAY:
1255 case RTAX_IFP:
1256 sa = rtm_scrub(type, i, NULL, sa, &ssbuf,
1257 sizeof(ssbuf), credp);
1258 break;
1259
1260 default:
1261 break;
1262 }
1263
1264 rtinfo->rti_addrs |= (1 << i);
1265 dlen = sa->sa_len;
1266 rlen = ROUNDUP32(dlen);
1267 if (cp) {
1268 bcopy((caddr_t)sa, cp, (size_t)dlen);
1269 if (dlen != rlen) {
1270 bzero(cp + dlen, rlen - dlen);
1271 }
1272 cp += rlen;
1273 }
1274 len += rlen;
1275 }
1276 if (cp == NULL && w != NULL && !second_time) {
1277 struct walkarg *rw = w;
1278
1279 if (rw->w_req != NULL) {
1280 if (rw->w_tmemsize < len) {
1281 if (rw->w_tmem != NULL) {
1282 FREE(rw->w_tmem, M_RTABLE);
1283 }
1284 rw->w_tmem = _MALLOC(len, M_RTABLE, M_ZERO | M_WAITOK);
1285 if (rw->w_tmem != NULL) {
1286 rw->w_tmemsize = len;
1287 }
1288 }
1289 if (rw->w_tmem != NULL) {
1290 cp = rw->w_tmem;
1291 second_time = 1;
1292 goto again;
1293 }
1294 }
1295 }
1296 if (cp) {
1297 struct rt_msghdr *rtm = (struct rt_msghdr *)(void *)cp0;
1298
1299 rtm->rtm_version = RTM_VERSION;
1300 rtm->rtm_type = type;
1301 rtm->rtm_msglen = len;
1302 }
1303 return len;
1304 }
1305
1306 /*
1307 * This routine is called to generate a message from the routing
1308 * socket indicating that a redirect has occurred, a routing lookup
1309 * has failed, or that a protocol has detected timeouts to a particular
1310 * destination.
1311 */
1312 void
1313 rt_missmsg(int type, struct rt_addrinfo *rtinfo, int flags, int error)
1314 {
1315 struct rt_msghdr *rtm;
1316 struct mbuf *m;
1317 struct sockaddr *sa = rtinfo->rti_info[RTAX_DST];
1318 struct sockproto route_proto = { PF_ROUTE, 0 };
1319
1320 if (route_cb.any_count == 0) {
1321 return;
1322 }
1323 m = rt_msg1(type, rtinfo);
1324 if (m == NULL) {
1325 return;
1326 }
1327 rtm = mtod(m, struct rt_msghdr *);
1328 rtm->rtm_flags = RTF_DONE | flags;
1329 rtm->rtm_errno = error;
1330 rtm->rtm_addrs = rtinfo->rti_addrs;
1331 route_proto.sp_family = sa ? sa->sa_family : 0;
1332 raw_input(m, &route_proto, &route_src, &route_dst);
1333 }
1334
1335 /*
1336 * This routine is called to generate a message from the routing
1337 * socket indicating that the status of a network interface has changed.
1338 */
1339 void
1340 rt_ifmsg(struct ifnet *ifp)
1341 {
1342 struct if_msghdr *ifm;
1343 struct mbuf *m;
1344 struct rt_addrinfo info;
1345 struct sockproto route_proto = { PF_ROUTE, 0 };
1346
1347 if (route_cb.any_count == 0) {
1348 return;
1349 }
1350 bzero((caddr_t)&info, sizeof(info));
1351 m = rt_msg1(RTM_IFINFO, &info);
1352 if (m == NULL) {
1353 return;
1354 }
1355 ifm = mtod(m, struct if_msghdr *);
1356 ifm->ifm_index = ifp->if_index;
1357 ifm->ifm_flags = (u_short)ifp->if_flags;
1358 if_data_internal_to_if_data(ifp, &ifp->if_data, &ifm->ifm_data);
1359 ifm->ifm_addrs = 0;
1360 raw_input(m, &route_proto, &route_src, &route_dst);
1361 }
1362
1363 /*
1364 * This is called to generate messages from the routing socket
1365 * indicating a network interface has had addresses associated with it.
1366 * if we ever reverse the logic and replace messages TO the routing
1367 * socket indicate a request to configure interfaces, then it will
1368 * be unnecessary as the routing socket will automatically generate
1369 * copies of it.
1370 *
1371 * Since this is coming from the interface, it is expected that the
1372 * interface will be locked. Caller must hold rnh_lock and rt_lock.
1373 */
1374 void
1375 rt_newaddrmsg(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt)
1376 {
1377 struct rt_addrinfo info;
1378 struct sockaddr *sa = 0;
1379 int pass;
1380 struct mbuf *m = 0;
1381 struct ifnet *ifp = ifa->ifa_ifp;
1382 struct sockproto route_proto = { PF_ROUTE, 0 };
1383
1384 LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
1385 RT_LOCK_ASSERT_HELD(rt);
1386
1387 if (route_cb.any_count == 0) {
1388 return;
1389 }
1390
1391 /* Become a regular mutex, just in case */
1392 RT_CONVERT_LOCK(rt);
1393 for (pass = 1; pass < 3; pass++) {
1394 bzero((caddr_t)&info, sizeof(info));
1395 if ((cmd == RTM_ADD && pass == 1) ||
1396 (cmd == RTM_DELETE && pass == 2)) {
1397 struct ifa_msghdr *ifam;
1398 int ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;
1399
1400 /* Lock ifp for if_lladdr */
1401 ifnet_lock_shared(ifp);
1402 IFA_LOCK(ifa);
1403 info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
1404 /*
1405 * Holding ifnet lock here prevents the link address
1406 * from changing contents, so no need to hold its
1407 * lock. The link address is always present; it's
1408 * never freed.
1409 */
1410 info.rti_info[RTAX_IFP] = ifp->if_lladdr->ifa_addr;
1411 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
1412 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
1413 if ((m = rt_msg1(ncmd, &info)) == NULL) {
1414 IFA_UNLOCK(ifa);
1415 ifnet_lock_done(ifp);
1416 continue;
1417 }
1418 IFA_UNLOCK(ifa);
1419 ifnet_lock_done(ifp);
1420 ifam = mtod(m, struct ifa_msghdr *);
1421 ifam->ifam_index = ifp->if_index;
1422 IFA_LOCK_SPIN(ifa);
1423 ifam->ifam_metric = ifa->ifa_metric;
1424 ifam->ifam_flags = ifa->ifa_flags;
1425 IFA_UNLOCK(ifa);
1426 ifam->ifam_addrs = info.rti_addrs;
1427 }
1428 if ((cmd == RTM_ADD && pass == 2) ||
1429 (cmd == RTM_DELETE && pass == 1)) {
1430 struct rt_msghdr *rtm;
1431
1432 if (rt == NULL) {
1433 continue;
1434 }
1435 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1436 info.rti_info[RTAX_DST] = sa = rt_key(rt);
1437 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
1438 if ((m = rt_msg1(cmd, &info)) == NULL) {
1439 continue;
1440 }
1441 rtm = mtod(m, struct rt_msghdr *);
1442 rtm->rtm_index = ifp->if_index;
1443 rtm->rtm_flags |= rt->rt_flags;
1444 rtm->rtm_errno = error;
1445 rtm->rtm_addrs = info.rti_addrs;
1446 }
1447 route_proto.sp_protocol = sa ? sa->sa_family : 0;
1448 raw_input(m, &route_proto, &route_src, &route_dst);
1449 }
1450 }
1451
1452 /*
1453 * This is the analogue to the rt_newaddrmsg which performs the same
1454 * function but for multicast group memberhips. This is easier since
1455 * there is no route state to worry about.
1456 */
1457 void
1458 rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma)
1459 {
1460 struct rt_addrinfo info;
1461 struct mbuf *m = 0;
1462 struct ifnet *ifp = ifma->ifma_ifp;
1463 struct ifma_msghdr *ifmam;
1464 struct sockproto route_proto = { PF_ROUTE, 0 };
1465
1466 if (route_cb.any_count == 0) {
1467 return;
1468 }
1469
1470 /* Lock ifp for if_lladdr */
1471 ifnet_lock_shared(ifp);
1472 bzero((caddr_t)&info, sizeof(info));
1473 IFMA_LOCK(ifma);
1474 info.rti_info[RTAX_IFA] = ifma->ifma_addr;
1475 /* lladdr doesn't need lock */
1476 info.rti_info[RTAX_IFP] = ifp->if_lladdr->ifa_addr;
1477
1478 /*
1479 * If a link-layer address is present, present it as a ``gateway''
1480 * (similarly to how ARP entries, e.g., are presented).
1481 */
1482 info.rti_info[RTAX_GATEWAY] = (ifma->ifma_ll != NULL) ?
1483 ifma->ifma_ll->ifma_addr : NULL;
1484 if ((m = rt_msg1(cmd, &info)) == NULL) {
1485 IFMA_UNLOCK(ifma);
1486 ifnet_lock_done(ifp);
1487 return;
1488 }
1489 ifmam = mtod(m, struct ifma_msghdr *);
1490 ifmam->ifmam_index = ifp->if_index;
1491 ifmam->ifmam_addrs = info.rti_addrs;
1492 route_proto.sp_protocol = ifma->ifma_addr->sa_family;
1493 IFMA_UNLOCK(ifma);
1494 ifnet_lock_done(ifp);
1495 raw_input(m, &route_proto, &route_src, &route_dst);
1496 }
1497
1498 const char *
1499 rtm2str(int cmd)
1500 {
1501 const char *c = "RTM_?";
1502
1503 switch (cmd) {
1504 case RTM_ADD:
1505 c = "RTM_ADD";
1506 break;
1507 case RTM_DELETE:
1508 c = "RTM_DELETE";
1509 break;
1510 case RTM_CHANGE:
1511 c = "RTM_CHANGE";
1512 break;
1513 case RTM_GET:
1514 c = "RTM_GET";
1515 break;
1516 case RTM_LOSING:
1517 c = "RTM_LOSING";
1518 break;
1519 case RTM_REDIRECT:
1520 c = "RTM_REDIRECT";
1521 break;
1522 case RTM_MISS:
1523 c = "RTM_MISS";
1524 break;
1525 case RTM_LOCK:
1526 c = "RTM_LOCK";
1527 break;
1528 case RTM_OLDADD:
1529 c = "RTM_OLDADD";
1530 break;
1531 case RTM_OLDDEL:
1532 c = "RTM_OLDDEL";
1533 break;
1534 case RTM_RESOLVE:
1535 c = "RTM_RESOLVE";
1536 break;
1537 case RTM_NEWADDR:
1538 c = "RTM_NEWADDR";
1539 break;
1540 case RTM_DELADDR:
1541 c = "RTM_DELADDR";
1542 break;
1543 case RTM_IFINFO:
1544 c = "RTM_IFINFO";
1545 break;
1546 case RTM_NEWMADDR:
1547 c = "RTM_NEWMADDR";
1548 break;
1549 case RTM_DELMADDR:
1550 c = "RTM_DELMADDR";
1551 break;
1552 case RTM_GET_SILENT:
1553 c = "RTM_GET_SILENT";
1554 break;
1555 case RTM_IFINFO2:
1556 c = "RTM_IFINFO2";
1557 break;
1558 case RTM_NEWMADDR2:
1559 c = "RTM_NEWMADDR2";
1560 break;
1561 case RTM_GET2:
1562 c = "RTM_GET2";
1563 break;
1564 case RTM_GET_EXT:
1565 c = "RTM_GET_EXT";
1566 break;
1567 }
1568
1569 return c;
1570 }
1571
1572 /*
1573 * This is used in dumping the kernel table via sysctl().
1574 */
1575 static int
1576 sysctl_dumpentry(struct radix_node *rn, void *vw)
1577 {
1578 struct walkarg *w = vw;
1579 struct rtentry *rt = (struct rtentry *)rn;
1580 int error = 0, size;
1581 struct rt_addrinfo info;
1582 kauth_cred_t cred;
1583 kauth_cred_t *credp;
1584
1585 cred = kauth_cred_proc_ref(current_proc());
1586 credp = &cred;
1587
1588 RT_LOCK(rt);
1589 if ((w->w_op == NET_RT_FLAGS || w->w_op == NET_RT_FLAGS_PRIV) &&
1590 !(rt->rt_flags & w->w_arg)) {
1591 goto done;
1592 }
1593
1594 /*
1595 * If the matching route has RTF_LLINFO set, then we can skip scrubbing the MAC
1596 * only if the outgoing interface is not loopback and the process has entitlement
1597 * for neighbor cache read.
1598 */
1599 if (w->w_op == NET_RT_FLAGS_PRIV && (rt->rt_flags & RTF_LLINFO)) {
1600 if (rt->rt_ifp != lo_ifp &&
1601 (route_op_entitlement_check(NULL, cred, ROUTE_OP_READ, TRUE) == 0)) {
1602 credp = NULL;
1603 }
1604 }
1605
1606 bzero((caddr_t)&info, sizeof(info));
1607 info.rti_info[RTAX_DST] = rt_key(rt);
1608 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
1609 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1610 info.rti_info[RTAX_GENMASK] = rt->rt_genmask;
1611
1612 if (w->w_op != NET_RT_DUMP2) {
1613 size = rt_msg2(RTM_GET, &info, NULL, w, credp);
1614 if (w->w_req != NULL && w->w_tmem != NULL) {
1615 struct rt_msghdr *rtm =
1616 (struct rt_msghdr *)(void *)w->w_tmem;
1617
1618 rtm->rtm_flags = rt->rt_flags;
1619 rtm->rtm_use = rt->rt_use;
1620 rt_getmetrics(rt, &rtm->rtm_rmx);
1621 rtm->rtm_index = rt->rt_ifp->if_index;
1622 rtm->rtm_pid = 0;
1623 rtm->rtm_seq = 0;
1624 rtm->rtm_errno = 0;
1625 rtm->rtm_addrs = info.rti_addrs;
1626 error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size);
1627 }
1628 } else {
1629 size = rt_msg2(RTM_GET2, &info, NULL, w, credp);
1630 if (w->w_req != NULL && w->w_tmem != NULL) {
1631 struct rt_msghdr2 *rtm =
1632 (struct rt_msghdr2 *)(void *)w->w_tmem;
1633
1634 rtm->rtm_flags = rt->rt_flags;
1635 rtm->rtm_use = rt->rt_use;
1636 rt_getmetrics(rt, &rtm->rtm_rmx);
1637 rtm->rtm_index = rt->rt_ifp->if_index;
1638 rtm->rtm_refcnt = rt->rt_refcnt;
1639 if (rt->rt_parent) {
1640 rtm->rtm_parentflags = rt->rt_parent->rt_flags;
1641 } else {
1642 rtm->rtm_parentflags = 0;
1643 }
1644 rtm->rtm_reserved = 0;
1645 rtm->rtm_addrs = info.rti_addrs;
1646 error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size);
1647 }
1648 }
1649
1650 done:
1651 RT_UNLOCK(rt);
1652 kauth_cred_unref(&cred);
1653 return error;
1654 }
1655
1656 /*
1657 * This is used for dumping extended information from route entries.
1658 */
1659 static int
1660 sysctl_dumpentry_ext(struct radix_node *rn, void *vw)
1661 {
1662 struct walkarg *w = vw;
1663 struct rtentry *rt = (struct rtentry *)rn;
1664 int error = 0, size;
1665 struct rt_addrinfo info;
1666 kauth_cred_t cred;
1667
1668 cred = kauth_cred_proc_ref(current_proc());
1669
1670 RT_LOCK(rt);
1671 if (w->w_op == NET_RT_DUMPX_FLAGS && !(rt->rt_flags & w->w_arg)) {
1672 goto done;
1673 }
1674 bzero(&info, sizeof(info));
1675 info.rti_info[RTAX_DST] = rt_key(rt);
1676 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
1677 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1678 info.rti_info[RTAX_GENMASK] = rt->rt_genmask;
1679
1680 size = rt_msg2(RTM_GET_EXT, &info, NULL, w, &cred);
1681 if (w->w_req != NULL && w->w_tmem != NULL) {
1682 struct rt_msghdr_ext *ertm =
1683 (struct rt_msghdr_ext *)(void *)w->w_tmem;
1684
1685 ertm->rtm_flags = rt->rt_flags;
1686 ertm->rtm_use = rt->rt_use;
1687 rt_getmetrics(rt, &ertm->rtm_rmx);
1688 ertm->rtm_index = rt->rt_ifp->if_index;
1689 ertm->rtm_pid = 0;
1690 ertm->rtm_seq = 0;
1691 ertm->rtm_errno = 0;
1692 ertm->rtm_addrs = info.rti_addrs;
1693 if (rt->rt_llinfo_get_ri == NULL) {
1694 bzero(&ertm->rtm_ri, sizeof(ertm->rtm_ri));
1695 ertm->rtm_ri.ri_rssi = IFNET_RSSI_UNKNOWN;
1696 ertm->rtm_ri.ri_lqm = IFNET_LQM_THRESH_OFF;
1697 ertm->rtm_ri.ri_npm = IFNET_NPM_THRESH_UNKNOWN;
1698 } else {
1699 rt->rt_llinfo_get_ri(rt, &ertm->rtm_ri);
1700 }
1701 error = SYSCTL_OUT(w->w_req, (caddr_t)ertm, size);
1702 }
1703
1704 done:
1705 RT_UNLOCK(rt);
1706 kauth_cred_unref(&cred);
1707 return error;
1708 }
1709
1710 /*
1711 * rdar://9307819
1712 * To avoid to call copyout() while holding locks and to cause problems
1713 * in the paging path, sysctl_iflist() and sysctl_iflist2() contstruct
1714 * the list in two passes. In the first pass we compute the total
1715 * length of the data we are going to copyout, then we release
1716 * all locks to allocate a temporary buffer that gets filled
1717 * in the second pass.
1718 *
1719 * Note that we are verifying the assumption that _MALLOC returns a buffer
1720 * that is at least 32 bits aligned and that the messages and addresses are
1721 * 32 bits aligned.
1722 */
1723 static int
1724 sysctl_iflist(int af, struct walkarg *w)
1725 {
1726 struct ifnet *ifp;
1727 struct ifaddr *ifa;
1728 struct rt_addrinfo info;
1729 int len = 0, error = 0;
1730 int pass = 0;
1731 int total_len = 0, current_len = 0;
1732 char *total_buffer = NULL, *cp = NULL;
1733 kauth_cred_t cred;
1734
1735 cred = kauth_cred_proc_ref(current_proc());
1736
1737 bzero((caddr_t)&info, sizeof(info));
1738
1739 for (pass = 0; pass < 2; pass++) {
1740 ifnet_head_lock_shared();
1741
1742 TAILQ_FOREACH(ifp, &ifnet_head, if_link) {
1743 if (error) {
1744 break;
1745 }
1746 if (w->w_arg && w->w_arg != ifp->if_index) {
1747 continue;
1748 }
1749 ifnet_lock_shared(ifp);
1750 /*
1751 * Holding ifnet lock here prevents the link address
1752 * from changing contents, so no need to hold the ifa
1753 * lock. The link address is always present; it's
1754 * never freed.
1755 */
1756 ifa = ifp->if_lladdr;
1757 info.rti_info[RTAX_IFP] = ifa->ifa_addr;
1758 len = rt_msg2(RTM_IFINFO, &info, NULL, NULL, &cred);
1759 if (pass == 0) {
1760 total_len += len;
1761 } else {
1762 struct if_msghdr *ifm;
1763
1764 if (current_len + len > total_len) {
1765 ifnet_lock_done(ifp);
1766 error = ENOBUFS;
1767 break;
1768 }
1769 info.rti_info[RTAX_IFP] = ifa->ifa_addr;
1770 len = rt_msg2(RTM_IFINFO, &info,
1771 (caddr_t)cp, NULL, &cred);
1772 info.rti_info[RTAX_IFP] = NULL;
1773
1774 ifm = (struct if_msghdr *)(void *)cp;
1775 ifm->ifm_index = ifp->if_index;
1776 ifm->ifm_flags = (u_short)ifp->if_flags;
1777 if_data_internal_to_if_data(ifp, &ifp->if_data,
1778 &ifm->ifm_data);
1779 ifm->ifm_addrs = info.rti_addrs;
1780 /*
1781 * <rdar://problem/32940901>
1782 * Round bytes only for non-platform
1783 */
1784 if (!csproc_get_platform_binary(w->w_req->p)) {
1785 ALIGN_BYTES(ifm->ifm_data.ifi_ibytes);
1786 ALIGN_BYTES(ifm->ifm_data.ifi_obytes);
1787 }
1788
1789 cp += len;
1790 VERIFY(IS_P2ALIGNED(cp, sizeof(u_int32_t)));
1791 current_len += len;
1792 }
1793 while ((ifa = ifa->ifa_link.tqe_next) != NULL) {
1794 IFA_LOCK(ifa);
1795 if (af && af != ifa->ifa_addr->sa_family) {
1796 IFA_UNLOCK(ifa);
1797 continue;
1798 }
1799 if (ifa->ifa_addr->sa_family == AF_INET6 &&
1800 (((struct in6_ifaddr *)ifa)->ia6_flags &
1801 IN6_IFF_CLAT46) != 0) {
1802 IFA_UNLOCK(ifa);
1803 continue;
1804 }
1805 info.rti_info[RTAX_IFA] = ifa->ifa_addr;
1806 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
1807 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
1808 len = rt_msg2(RTM_NEWADDR, &info, NULL, NULL,
1809 &cred);
1810 if (pass == 0) {
1811 total_len += len;
1812 } else {
1813 struct ifa_msghdr *ifam;
1814
1815 if (current_len + len > total_len) {
1816 IFA_UNLOCK(ifa);
1817 error = ENOBUFS;
1818 break;
1819 }
1820 len = rt_msg2(RTM_NEWADDR, &info,
1821 (caddr_t)cp, NULL, &cred);
1822
1823 ifam = (struct ifa_msghdr *)(void *)cp;
1824 ifam->ifam_index =
1825 ifa->ifa_ifp->if_index;
1826 ifam->ifam_flags = ifa->ifa_flags;
1827 ifam->ifam_metric = ifa->ifa_metric;
1828 ifam->ifam_addrs = info.rti_addrs;
1829
1830 cp += len;
1831 VERIFY(IS_P2ALIGNED(cp,
1832 sizeof(u_int32_t)));
1833 current_len += len;
1834 }
1835 IFA_UNLOCK(ifa);
1836 }
1837 ifnet_lock_done(ifp);
1838 info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] =
1839 info.rti_info[RTAX_BRD] = NULL;
1840 }
1841
1842 ifnet_head_done();
1843
1844 if (error != 0) {
1845 if (error == ENOBUFS) {
1846 printf("%s: current_len (%d) + len (%d) > "
1847 "total_len (%d)\n", __func__, current_len,
1848 len, total_len);
1849 }
1850 break;
1851 }
1852
1853 if (pass == 0) {
1854 /* Better to return zero length buffer than ENOBUFS */
1855 if (total_len == 0) {
1856 total_len = 1;
1857 }
1858 total_len += total_len >> 3;
1859 total_buffer = _MALLOC(total_len, M_RTABLE,
1860 M_ZERO | M_WAITOK);
1861 if (total_buffer == NULL) {
1862 printf("%s: _MALLOC(%d) failed\n", __func__,
1863 total_len);
1864 error = ENOBUFS;
1865 break;
1866 }
1867 cp = total_buffer;
1868 VERIFY(IS_P2ALIGNED(cp, sizeof(u_int32_t)));
1869 } else {
1870 error = SYSCTL_OUT(w->w_req, total_buffer, current_len);
1871 if (error) {
1872 break;
1873 }
1874 }
1875 }
1876
1877 if (total_buffer != NULL) {
1878 _FREE(total_buffer, M_RTABLE);
1879 }
1880
1881 kauth_cred_unref(&cred);
1882 return error;
1883 }
1884
1885 static int
1886 sysctl_iflist2(int af, struct walkarg *w)
1887 {
1888 struct ifnet *ifp;
1889 struct ifaddr *ifa;
1890 struct rt_addrinfo info;
1891 int len = 0, error = 0;
1892 int pass = 0;
1893 int total_len = 0, current_len = 0;
1894 char *total_buffer = NULL, *cp = NULL;
1895 kauth_cred_t cred;
1896
1897 cred = kauth_cred_proc_ref(current_proc());
1898
1899 bzero((caddr_t)&info, sizeof(info));
1900
1901 for (pass = 0; pass < 2; pass++) {
1902 struct ifmultiaddr *ifma;
1903
1904 ifnet_head_lock_shared();
1905
1906 TAILQ_FOREACH(ifp, &ifnet_head, if_link) {
1907 if (error) {
1908 break;
1909 }
1910 if (w->w_arg && w->w_arg != ifp->if_index) {
1911 continue;
1912 }
1913 ifnet_lock_shared(ifp);
1914 /*
1915 * Holding ifnet lock here prevents the link address
1916 * from changing contents, so no need to hold the ifa
1917 * lock. The link address is always present; it's
1918 * never freed.
1919 */
1920 ifa = ifp->if_lladdr;
1921 info.rti_info[RTAX_IFP] = ifa->ifa_addr;
1922 len = rt_msg2(RTM_IFINFO2, &info, NULL, NULL, &cred);
1923 if (pass == 0) {
1924 total_len += len;
1925 } else {
1926 struct if_msghdr2 *ifm;
1927
1928 if (current_len + len > total_len) {
1929 ifnet_lock_done(ifp);
1930 error = ENOBUFS;
1931 break;
1932 }
1933 info.rti_info[RTAX_IFP] = ifa->ifa_addr;
1934 len = rt_msg2(RTM_IFINFO2, &info,
1935 (caddr_t)cp, NULL, &cred);
1936 info.rti_info[RTAX_IFP] = NULL;
1937
1938 ifm = (struct if_msghdr2 *)(void *)cp;
1939 ifm->ifm_addrs = info.rti_addrs;
1940 ifm->ifm_flags = (u_short)ifp->if_flags;
1941 ifm->ifm_index = ifp->if_index;
1942 ifm->ifm_snd_len = IFCQ_LEN(&ifp->if_snd);
1943 ifm->ifm_snd_maxlen = IFCQ_MAXLEN(&ifp->if_snd);
1944 ifm->ifm_snd_drops =
1945 ifp->if_snd.ifcq_dropcnt.packets;
1946 ifm->ifm_timer = ifp->if_timer;
1947 if_data_internal_to_if_data64(ifp,
1948 &ifp->if_data, &ifm->ifm_data);
1949 /*
1950 * <rdar://problem/32940901>
1951 * Round bytes only for non-platform
1952 */
1953 if (!csproc_get_platform_binary(w->w_req->p)) {
1954 ALIGN_BYTES(ifm->ifm_data.ifi_ibytes);
1955 ALIGN_BYTES(ifm->ifm_data.ifi_obytes);
1956 }
1957
1958 cp += len;
1959 VERIFY(IS_P2ALIGNED(cp, sizeof(u_int32_t)));
1960 current_len += len;
1961 }
1962 while ((ifa = ifa->ifa_link.tqe_next) != NULL) {
1963 IFA_LOCK(ifa);
1964 if (af && af != ifa->ifa_addr->sa_family) {
1965 IFA_UNLOCK(ifa);
1966 continue;
1967 }
1968 if (ifa->ifa_addr->sa_family == AF_INET6 &&
1969 (((struct in6_ifaddr *)ifa)->ia6_flags &
1970 IN6_IFF_CLAT46) != 0) {
1971 IFA_UNLOCK(ifa);
1972 continue;
1973 }
1974
1975 info.rti_info[RTAX_IFA] = ifa->ifa_addr;
1976 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
1977 info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr;
1978 len = rt_msg2(RTM_NEWADDR, &info, NULL, NULL,
1979 &cred);
1980 if (pass == 0) {
1981 total_len += len;
1982 } else {
1983 struct ifa_msghdr *ifam;
1984
1985 if (current_len + len > total_len) {
1986 IFA_UNLOCK(ifa);
1987 error = ENOBUFS;
1988 break;
1989 }
1990 len = rt_msg2(RTM_NEWADDR, &info,
1991 (caddr_t)cp, NULL, &cred);
1992
1993 ifam = (struct ifa_msghdr *)(void *)cp;
1994 ifam->ifam_index =
1995 ifa->ifa_ifp->if_index;
1996 ifam->ifam_flags = ifa->ifa_flags;
1997 ifam->ifam_metric = ifa->ifa_metric;
1998 ifam->ifam_addrs = info.rti_addrs;
1999
2000 cp += len;
2001 VERIFY(IS_P2ALIGNED(cp,
2002 sizeof(u_int32_t)));
2003 current_len += len;
2004 }
2005 IFA_UNLOCK(ifa);
2006 }
2007 if (error) {
2008 ifnet_lock_done(ifp);
2009 break;
2010 }
2011
2012 for (ifma = LIST_FIRST(&ifp->if_multiaddrs);
2013 ifma != NULL; ifma = LIST_NEXT(ifma, ifma_link)) {
2014 struct ifaddr *ifa0;
2015
2016 IFMA_LOCK(ifma);
2017 if (af && af != ifma->ifma_addr->sa_family) {
2018 IFMA_UNLOCK(ifma);
2019 continue;
2020 }
2021 bzero((caddr_t)&info, sizeof(info));
2022 info.rti_info[RTAX_IFA] = ifma->ifma_addr;
2023 /*
2024 * Holding ifnet lock here prevents the link
2025 * address from changing contents, so no need
2026 * to hold the ifa0 lock. The link address is
2027 * always present; it's never freed.
2028 */
2029 ifa0 = ifp->if_lladdr;
2030 info.rti_info[RTAX_IFP] = ifa0->ifa_addr;
2031 if (ifma->ifma_ll != NULL) {
2032 info.rti_info[RTAX_GATEWAY] =
2033 ifma->ifma_ll->ifma_addr;
2034 }
2035 len = rt_msg2(RTM_NEWMADDR2, &info, NULL, NULL,
2036 &cred);
2037 if (pass == 0) {
2038 total_len += len;
2039 } else {
2040 struct ifma_msghdr2 *ifmam;
2041
2042 if (current_len + len > total_len) {
2043 IFMA_UNLOCK(ifma);
2044 error = ENOBUFS;
2045 break;
2046 }
2047 len = rt_msg2(RTM_NEWMADDR2, &info,
2048 (caddr_t)cp, NULL, &cred);
2049
2050 ifmam =
2051 (struct ifma_msghdr2 *)(void *)cp;
2052 ifmam->ifmam_addrs = info.rti_addrs;
2053 ifmam->ifmam_flags = 0;
2054 ifmam->ifmam_index =
2055 ifma->ifma_ifp->if_index;
2056 ifmam->ifmam_refcount =
2057 ifma->ifma_reqcnt;
2058
2059 cp += len;
2060 VERIFY(IS_P2ALIGNED(cp,
2061 sizeof(u_int32_t)));
2062 current_len += len;
2063 }
2064 IFMA_UNLOCK(ifma);
2065 }
2066 ifnet_lock_done(ifp);
2067 info.rti_info[RTAX_IFA] = info.rti_info[RTAX_NETMASK] =
2068 info.rti_info[RTAX_BRD] = NULL;
2069 }
2070 ifnet_head_done();
2071
2072 if (error) {
2073 if (error == ENOBUFS) {
2074 printf("%s: current_len (%d) + len (%d) > "
2075 "total_len (%d)\n", __func__, current_len,
2076 len, total_len);
2077 }
2078 break;
2079 }
2080
2081 if (pass == 0) {
2082 /* Better to return zero length buffer than ENOBUFS */
2083 if (total_len == 0) {
2084 total_len = 1;
2085 }
2086 total_len += total_len >> 3;
2087 total_buffer = _MALLOC(total_len, M_RTABLE,
2088 M_ZERO | M_WAITOK);
2089 if (total_buffer == NULL) {
2090 printf("%s: _MALLOC(%d) failed\n", __func__,
2091 total_len);
2092 error = ENOBUFS;
2093 break;
2094 }
2095 cp = total_buffer;
2096 VERIFY(IS_P2ALIGNED(cp, sizeof(u_int32_t)));
2097 } else {
2098 error = SYSCTL_OUT(w->w_req, total_buffer, current_len);
2099 if (error) {
2100 break;
2101 }
2102 }
2103 }
2104
2105 if (total_buffer != NULL) {
2106 _FREE(total_buffer, M_RTABLE);
2107 }
2108
2109 kauth_cred_unref(&cred);
2110 return error;
2111 }
2112
2113
2114 static int
2115 sysctl_rtstat(struct sysctl_req *req)
2116 {
2117 return SYSCTL_OUT(req, &rtstat, sizeof(struct rtstat));
2118 }
2119
2120 static int
2121 sysctl_rttrash(struct sysctl_req *req)
2122 {
2123 return SYSCTL_OUT(req, &rttrash, sizeof(rttrash));
2124 }
2125
2126 static int
2127 sysctl_rtsock SYSCTL_HANDLER_ARGS
2128 {
2129 #pragma unused(oidp)
2130 int *name = (int *)arg1;
2131 u_int namelen = arg2;
2132 struct radix_node_head *rnh;
2133 int i, error = EINVAL;
2134 u_char af;
2135 struct walkarg w;
2136
2137 name++;
2138 namelen--;
2139 if (req->newptr) {
2140 return EPERM;
2141 }
2142 if (namelen != 3) {
2143 return EINVAL;
2144 }
2145 af = name[0];
2146 Bzero(&w, sizeof(w));
2147 w.w_op = name[1];
2148 w.w_arg = name[2];
2149 w.w_req = req;
2150
2151 switch (w.w_op) {
2152 case NET_RT_DUMP:
2153 case NET_RT_DUMP2:
2154 case NET_RT_FLAGS:
2155 case NET_RT_FLAGS_PRIV:
2156 lck_mtx_lock(rnh_lock);
2157 for (i = 1; i <= AF_MAX; i++) {
2158 if ((rnh = rt_tables[i]) && (af == 0 || af == i) &&
2159 (error = rnh->rnh_walktree(rnh,
2160 sysctl_dumpentry, &w))) {
2161 break;
2162 }
2163 }
2164 lck_mtx_unlock(rnh_lock);
2165 break;
2166 case NET_RT_DUMPX:
2167 case NET_RT_DUMPX_FLAGS:
2168 lck_mtx_lock(rnh_lock);
2169 for (i = 1; i <= AF_MAX; i++) {
2170 if ((rnh = rt_tables[i]) && (af == 0 || af == i) &&
2171 (error = rnh->rnh_walktree(rnh,
2172 sysctl_dumpentry_ext, &w))) {
2173 break;
2174 }
2175 }
2176 lck_mtx_unlock(rnh_lock);
2177 break;
2178 case NET_RT_IFLIST:
2179 error = sysctl_iflist(af, &w);
2180 break;
2181 case NET_RT_IFLIST2:
2182 error = sysctl_iflist2(af, &w);
2183 break;
2184 case NET_RT_STAT:
2185 error = sysctl_rtstat(req);
2186 break;
2187 case NET_RT_TRASH:
2188 error = sysctl_rttrash(req);
2189 break;
2190 }
2191 if (w.w_tmem != NULL) {
2192 FREE(w.w_tmem, M_RTABLE);
2193 }
2194 return error;
2195 }
2196
2197 /*
2198 * Definitions of protocols supported in the ROUTE domain.
2199 */
2200 static struct protosw routesw[] = {
2201 {
2202 .pr_type = SOCK_RAW,
2203 .pr_protocol = 0,
2204 .pr_flags = PR_ATOMIC | PR_ADDR,
2205 .pr_output = route_output,
2206 .pr_ctlinput = raw_ctlinput,
2207 .pr_init = raw_init,
2208 .pr_usrreqs = &route_usrreqs,
2209 }
2210 };
2211
2212 static int route_proto_count = (sizeof(routesw) / sizeof(struct protosw));
2213
2214 struct domain routedomain_s = {
2215 .dom_family = PF_ROUTE,
2216 .dom_name = "route",
2217 .dom_init = route_dinit,
2218 };
2219
2220 static void
2221 route_dinit(struct domain *dp)
2222 {
2223 struct protosw *pr;
2224 int i;
2225
2226 VERIFY(!(dp->dom_flags & DOM_INITIALIZED));
2227 VERIFY(routedomain == NULL);
2228
2229 routedomain = dp;
2230
2231 for (i = 0, pr = &routesw[0]; i < route_proto_count; i++, pr++) {
2232 net_add_proto(pr, dp, 1);
2233 }
2234
2235 route_init();
2236 }