2  * Copyright (c) 2000-2017 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   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. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  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. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29  * Copyright (c) 1988, 1991, 1993 
  30  *      The Regents of the University of California.  All rights reserved. 
  32  * Redistribution and use in source and binary forms, with or without 
  33  * modification, are permitted provided that the following conditions 
  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. 
  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 
  60  *      @(#)rtsock.c    8.5 (Berkeley) 11/2/94 
  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> 
  69 #include <sys/malloc.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> 
  81 #include <net/route.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 <netinet6/nd6.h> 
  89 extern struct rtstat rtstat
; 
  90 extern struct domain routedomain_s
; 
  91 static struct domain 
*routedomain 
= NULL
; 
  93 MALLOC_DEFINE(M_RTABLE
, "routetbl", "routing tables"); 
  95 static struct sockaddr route_dst 
= { 2, PF_ROUTE
, { 0, } }; 
  96 static struct sockaddr route_src 
= { 2, PF_ROUTE
, { 0, } }; 
  97 static struct sockaddr sa_zero   
= { sizeof (sa_zero
), AF_INET
, { 0, } }; 
 100         u_int32_t       ip_count
;       /* attached w/ AF_INET */ 
 101         u_int32_t       ip6_count
;      /* attached w/ AF_INET6 */ 
 102         u_int32_t       any_count
;      /* total attached */ 
 105 static struct route_cb route_cb
; 
 111         struct sysctl_req 
*w_req
; 
 114 static void route_dinit(struct domain 
*); 
 115 static int rts_abort(struct socket 
*); 
 116 static int rts_attach(struct socket 
*, int, struct proc 
*); 
 117 static int rts_bind(struct socket 
*, struct sockaddr 
*, struct proc 
*); 
 118 static int rts_connect(struct socket 
*, struct sockaddr 
*, struct proc 
*); 
 119 static int rts_detach(struct socket 
*); 
 120 static int rts_disconnect(struct socket 
*); 
 121 static int rts_peeraddr(struct socket 
*, struct sockaddr 
**); 
 122 static int rts_send(struct socket 
*, int, struct mbuf 
*, struct sockaddr 
*, 
 123     struct mbuf 
*, struct proc 
*); 
 124 static int rts_shutdown(struct socket 
*); 
 125 static int rts_sockaddr(struct socket 
*, struct sockaddr 
**); 
 127 static int route_output(struct mbuf 
*, struct socket 
*); 
 128 static int rt_setmetrics(u_int32_t
, struct rt_metrics 
*, struct rtentry 
*); 
 129 static void rt_getmetrics(struct rtentry 
*, struct rt_metrics 
*); 
 130 static void rt_setif(struct rtentry 
*, struct sockaddr 
*, struct sockaddr 
*, 
 131     struct sockaddr 
*, unsigned int); 
 132 static int rt_xaddrs(caddr_t
, caddr_t
, struct rt_addrinfo 
*); 
 133 static struct mbuf 
*rt_msg1(int, struct rt_addrinfo 
*); 
 134 static int rt_msg2(int, struct rt_addrinfo 
*, caddr_t
, struct walkarg 
*, 
 136 static int sysctl_dumpentry(struct radix_node 
*rn
, void *vw
); 
 137 static int sysctl_dumpentry_ext(struct radix_node 
*rn
, void *vw
); 
 138 static int sysctl_iflist(int af
, struct walkarg 
*w
); 
 139 static int sysctl_iflist2(int af
, struct walkarg 
*w
); 
 140 static int sysctl_rtstat(struct sysctl_req 
*); 
 141 static int sysctl_rttrash(struct sysctl_req 
*); 
 142 static int sysctl_rtsock SYSCTL_HANDLER_ARGS
; 
 144 SYSCTL_NODE(_net
, PF_ROUTE
, routetable
, CTLFLAG_RD 
| CTLFLAG_LOCKED
, 
 147 SYSCTL_NODE(_net
, OID_AUTO
, route
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0, "routing"); 
 149 /* Align x to 1024 (only power of 2) assuming x is positive */ 
 150 #define ALIGN_BYTES(x) do {                                             \ 
 151         x = P2ALIGN(x, 1024);                                           \ 
 154 #define ROUNDUP32(a)                                                    \ 
 155         ((a) > 0 ? (1 + (((a) - 1) | (sizeof (uint32_t) - 1))) :        \ 
 158 #define ADVANCE32(x, n)                                                 \ 
 159         (x += ROUNDUP32((n)->sa_len)) 
 162  * It really doesn't make any sense at all for this code to share much 
 163  * with raw_usrreq.c, since its functionality is so restricted.  XXX 
 166 rts_abort(struct socket 
*so
) 
 168         return (raw_usrreqs
.pru_abort(so
)); 
 171 /* pru_accept is EOPNOTSUPP */ 
 174 rts_attach(struct socket 
*so
, int proto
, struct proc 
*p
) 
 180         VERIFY(so
->so_pcb 
== NULL
); 
 182         MALLOC(rp
, struct rawcb 
*, sizeof (*rp
), M_PCB
, M_WAITOK 
| M_ZERO
); 
 186         so
->so_pcb 
= (caddr_t
)rp
; 
 187         /* don't use raw_usrreqs.pru_attach, it checks for SS_PRIV */ 
 188         error 
= raw_attach(so
, proto
); 
 193                 so
->so_flags 
|= SOF_PCBCLEARING
; 
 197         switch (rp
->rcb_proto
.sp_protocol
) { 
 199                 atomic_add_32(&route_cb
.ip_count
, 1); 
 202                 atomic_add_32(&route_cb
.ip6_count
, 1); 
 205         rp
->rcb_faddr 
= &route_src
; 
 206         atomic_add_32(&route_cb
.any_count
, 1); 
 207         /* the socket is already locked when we enter rts_attach */ 
 209         so
->so_options 
|= SO_USELOOPBACK
; 
 214 rts_bind(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
 216         return (raw_usrreqs
.pru_bind(so
, nam
, p
)); /* xxx just EINVAL */ 
 220 rts_connect(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
 222         return (raw_usrreqs
.pru_connect(so
, nam
, p
)); /* XXX just EINVAL */ 
 225 /* pru_connect2 is EOPNOTSUPP */ 
 226 /* pru_control is EOPNOTSUPP */ 
 229 rts_detach(struct socket 
*so
) 
 231         struct rawcb 
*rp 
= sotorawcb(so
); 
 235         switch (rp
->rcb_proto
.sp_protocol
) { 
 237                 atomic_add_32(&route_cb
.ip_count
, -1); 
 240                 atomic_add_32(&route_cb
.ip6_count
, -1); 
 243         atomic_add_32(&route_cb
.any_count
, -1); 
 244         return (raw_usrreqs
.pru_detach(so
)); 
 248 rts_disconnect(struct socket 
*so
) 
 250         return (raw_usrreqs
.pru_disconnect(so
)); 
 253 /* pru_listen is EOPNOTSUPP */ 
 256 rts_peeraddr(struct socket 
*so
, struct sockaddr 
**nam
) 
 258         return (raw_usrreqs
.pru_peeraddr(so
, nam
)); 
 261 /* pru_rcvd is EOPNOTSUPP */ 
 262 /* pru_rcvoob is EOPNOTSUPP */ 
 265 rts_send(struct socket 
*so
, int flags
, struct mbuf 
*m
, struct sockaddr 
*nam
, 
 266     struct mbuf 
*control
, struct proc 
*p
) 
 268         return (raw_usrreqs
.pru_send(so
, flags
, m
, nam
, control
, p
)); 
 271 /* pru_sense is null */ 
 274 rts_shutdown(struct socket 
*so
) 
 276         return (raw_usrreqs
.pru_shutdown(so
)); 
 280 rts_sockaddr(struct socket 
*so
, struct sockaddr 
**nam
) 
 282         return (raw_usrreqs
.pru_sockaddr(so
, nam
)); 
 285 static struct pr_usrreqs route_usrreqs 
= { 
 286         .pru_abort 
=            rts_abort
, 
 287         .pru_attach 
=           rts_attach
, 
 288         .pru_bind 
=             rts_bind
, 
 289         .pru_connect 
=          rts_connect
, 
 290         .pru_detach 
=           rts_detach
, 
 291         .pru_disconnect 
=       rts_disconnect
, 
 292         .pru_peeraddr 
=         rts_peeraddr
, 
 293         .pru_send 
=             rts_send
, 
 294         .pru_shutdown 
=         rts_shutdown
, 
 295         .pru_sockaddr 
=         rts_sockaddr
, 
 296         .pru_sosend 
=           sosend
, 
 297         .pru_soreceive 
=        soreceive
, 
 302 route_output(struct mbuf 
*m
, struct socket 
*so
) 
 304         struct rt_msghdr 
*rtm 
= NULL
; 
 305         struct rtentry 
*rt 
= NULL
; 
 306         struct rtentry 
*saved_nrt 
= NULL
; 
 307         struct radix_node_head 
*rnh
; 
 308         struct rt_addrinfo info
; 
 310         sa_family_t dst_sa_family 
= 0; 
 311         struct ifnet 
*ifp 
= NULL
; 
 312         struct sockaddr_in dst_in
, gate_in
; 
 313         int sendonlytoself 
= 0; 
 314         unsigned int ifscope 
= IFSCOPE_NONE
; 
 315         struct rawcb 
*rp 
= NULL
; 
 316         boolean_t is_router 
= FALSE
; 
 317 #define senderr(e) { error = (e); goto flush; } 
 318         if (m 
== NULL 
|| ((m
->m_len 
< sizeof (intptr_t)) && 
 319             (m 
= m_pullup(m
, sizeof (intptr_t))) == NULL
)) 
 321         VERIFY(m
->m_flags 
& M_PKTHDR
); 
 324          * Unlock the socket (but keep a reference) it won't be 
 325          * accessed until raw_input appends to it. 
 327         socket_unlock(so
, 0); 
 328         lck_mtx_lock(rnh_lock
); 
 330         len 
= m
->m_pkthdr
.len
; 
 331         if (len 
< sizeof (*rtm
) || 
 332             len 
!= mtod(m
, struct rt_msghdr 
*)->rtm_msglen
) { 
 333                 info
.rti_info
[RTAX_DST
] = NULL
; 
 336         R_Malloc(rtm
, struct rt_msghdr 
*, len
); 
 338                 info
.rti_info
[RTAX_DST
] = NULL
; 
 341         m_copydata(m
, 0, len
, (caddr_t
)rtm
); 
 342         if (rtm
->rtm_version 
!= RTM_VERSION
) { 
 343                 info
.rti_info
[RTAX_DST
] = NULL
; 
 344                 senderr(EPROTONOSUPPORT
); 
 348          * Silent version of RTM_GET for Reachabiltiy APIs. We may change 
 349          * all RTM_GETs to be silent in the future, so this is private for now. 
 351         if (rtm
->rtm_type 
== RTM_GET_SILENT
) { 
 352                 if (!(so
->so_options 
& SO_USELOOPBACK
)) 
 355                 rtm
->rtm_type 
= RTM_GET
; 
 359          * Perform permission checking, only privileged sockets 
 360          * may perform operations other than RTM_GET 
 362         if (rtm
->rtm_type 
!= RTM_GET 
&& !(so
->so_state 
& SS_PRIV
)) { 
 363                 info
.rti_info
[RTAX_DST
] = NULL
; 
 367         rtm
->rtm_pid 
= proc_selfpid(); 
 368         info
.rti_addrs 
= rtm
->rtm_addrs
; 
 369         if (rt_xaddrs((caddr_t
)(rtm 
+ 1), len 
+ (caddr_t
)rtm
, &info
)) { 
 370                 info
.rti_info
[RTAX_DST
] = NULL
; 
 373         if (info
.rti_info
[RTAX_DST
] == NULL 
|| 
 374             info
.rti_info
[RTAX_DST
]->sa_family 
>= AF_MAX 
|| 
 375             (info
.rti_info
[RTAX_GATEWAY
] != NULL 
&& 
 376             info
.rti_info
[RTAX_GATEWAY
]->sa_family 
>= AF_MAX
)) 
 379         if (info
.rti_info
[RTAX_DST
]->sa_family 
== AF_INET 
&& 
 380             info
.rti_info
[RTAX_DST
]->sa_len 
!= sizeof (dst_in
)) { 
 381                 /* At minimum, we need up to sin_addr */ 
 382                 if (info
.rti_info
[RTAX_DST
]->sa_len 
< 
 383                     offsetof(struct sockaddr_in
, sin_zero
)) 
 385                 bzero(&dst_in
, sizeof (dst_in
)); 
 386                 dst_in
.sin_len 
= sizeof (dst_in
); 
 387                 dst_in
.sin_family 
= AF_INET
; 
 388                 dst_in
.sin_port 
= SIN(info
.rti_info
[RTAX_DST
])->sin_port
; 
 389                 dst_in
.sin_addr 
= SIN(info
.rti_info
[RTAX_DST
])->sin_addr
; 
 390                 info
.rti_info
[RTAX_DST
] = (struct sockaddr 
*)&dst_in
; 
 391                 dst_sa_family 
= info
.rti_info
[RTAX_DST
]->sa_family
; 
 394         if (info
.rti_info
[RTAX_GATEWAY
] != NULL 
&& 
 395             info
.rti_info
[RTAX_GATEWAY
]->sa_family 
== AF_INET 
&& 
 396             info
.rti_info
[RTAX_GATEWAY
]->sa_len 
!= sizeof (gate_in
)) { 
 397                 /* At minimum, we need up to sin_addr */ 
 398                 if (info
.rti_info
[RTAX_GATEWAY
]->sa_len 
< 
 399                     offsetof(struct sockaddr_in
, sin_zero
)) 
 401                 bzero(&gate_in
, sizeof (gate_in
)); 
 402                 gate_in
.sin_len 
= sizeof (gate_in
); 
 403                 gate_in
.sin_family 
= AF_INET
; 
 404                 gate_in
.sin_port 
= SIN(info
.rti_info
[RTAX_GATEWAY
])->sin_port
; 
 405                 gate_in
.sin_addr 
= SIN(info
.rti_info
[RTAX_GATEWAY
])->sin_addr
; 
 406                 info
.rti_info
[RTAX_GATEWAY
] = (struct sockaddr 
*)&gate_in
; 
 409         if (info
.rti_info
[RTAX_GENMASK
]) { 
 410                 struct radix_node 
*t
; 
 411                 t 
= rn_addmask((caddr_t
)info
.rti_info
[RTAX_GENMASK
], 0, 1); 
 412                 if (t 
!= NULL 
&& Bcmp(info
.rti_info
[RTAX_GENMASK
], 
 413                     t
->rn_key
, *(u_char 
*)info
.rti_info
[RTAX_GENMASK
]) == 0) 
 414                         info
.rti_info
[RTAX_GENMASK
] = 
 415                             (struct sockaddr 
*)(t
->rn_key
); 
 421          * If RTF_IFSCOPE flag is set, then rtm_index specifies the scope. 
 423         if (rtm
->rtm_flags 
& RTF_IFSCOPE
) { 
 424                 if (info
.rti_info
[RTAX_DST
]->sa_family 
!= AF_INET 
&& 
 425                     info
.rti_info
[RTAX_DST
]->sa_family 
!= AF_INET6
) 
 427                 ifscope 
= rtm
->rtm_index
; 
 430          * Block changes on INTCOPROC interfaces. 
 433                 unsigned int intcoproc_scope 
= 0; 
 434                 ifnet_head_lock_shared(); 
 435                 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) { 
 436                         if (IFNET_IS_INTCOPROC(ifp
)) { 
 437                                 intcoproc_scope 
= ifp
->if_index
; 
 442                 if (intcoproc_scope 
== ifscope 
&& current_proc()->p_pid 
!= 0) 
 447          * RTF_PROXY can only be set internally from within the kernel. 
 449         if (rtm
->rtm_flags 
& RTF_PROXY
) 
 453          * For AF_INET, always zero out the embedded scope ID.  If this is 
 454          * a scoped request, it must be done explicitly by setting RTF_IFSCOPE 
 455          * flag and the corresponding rtm_index value.  This is to prevent 
 456          * false interpretation of the scope ID because it's using the sin_zero 
 457          * field, which might not be properly cleared by the requestor. 
 459         if (info
.rti_info
[RTAX_DST
]->sa_family 
== AF_INET
) 
 460                 sin_set_ifscope(info
.rti_info
[RTAX_DST
], IFSCOPE_NONE
); 
 461         if (info
.rti_info
[RTAX_GATEWAY
] != NULL 
&& 
 462             info
.rti_info
[RTAX_GATEWAY
]->sa_family 
== AF_INET
) 
 463                 sin_set_ifscope(info
.rti_info
[RTAX_GATEWAY
], IFSCOPE_NONE
); 
 464         switch (rtm
->rtm_type
) { 
 466                 if (info
.rti_info
[RTAX_GATEWAY
] == NULL
) 
 469                 error 
= rtrequest_scoped_locked(RTM_ADD
, 
 470                     info
.rti_info
[RTAX_DST
], info
.rti_info
[RTAX_GATEWAY
], 
 471                     info
.rti_info
[RTAX_NETMASK
], rtm
->rtm_flags
, &saved_nrt
, 
 473                 if (error 
== 0 && saved_nrt 
!= NULL
) { 
 476                          * If the route request specified an interface with 
 477                          * IFA and/or IFP, we set the requested interface on 
 478                          * the route with rt_setif.  It would be much better 
 479                          * to do this inside rtrequest, but that would 
 480                          * require passing the desired interface, in some 
 481                          * form, to rtrequest.  Since rtrequest is called in 
 482                          * so many places (roughly 40 in our source), adding 
 483                          * a parameter is to much for us to swallow; this is 
 484                          * something for the FreeBSD developers to tackle. 
 485                          * Instead, we let rtrequest compute whatever 
 486                          * interface it wants, then come in behind it and 
 487                          * stick in the interface that we really want.  This 
 488                          * works reasonably well except when rtrequest can't 
 489                          * figure out what interface to use (with 
 490                          * ifa_withroute) and returns ENETUNREACH.  Ideally 
 491                          * it shouldn't matter if rtrequest can't figure out 
 492                          * the interface if we're going to explicitly set it 
 493                          * ourselves anyway.  But practically we can't 
 494                          * recover here because rtrequest will not do any of 
 495                          * the work necessary to add the route if it can't 
 496                          * find an interface.  As long as there is a default 
 497                          * route that leads to some interface, rtrequest will 
 498                          * find an interface, so this problem should be 
 499                          * rarely encountered. 
 503                             info
.rti_info
[RTAX_IFP
], info
.rti_info
[RTAX_IFA
], 
 504                             info
.rti_info
[RTAX_GATEWAY
], ifscope
); 
 505                         (void)rt_setmetrics(rtm
->rtm_inits
, &rtm
->rtm_rmx
, saved_nrt
); 
 506                         saved_nrt
->rt_rmx
.rmx_locks 
&= ~(rtm
->rtm_inits
); 
 507                         saved_nrt
->rt_rmx
.rmx_locks 
|= 
 508                             (rtm
->rtm_inits 
& rtm
->rtm_rmx
.rmx_locks
); 
 509                         saved_nrt
->rt_genmask 
= info
.rti_info
[RTAX_GENMASK
]; 
 510                         RT_REMREF_LOCKED(saved_nrt
); 
 511                         RT_UNLOCK(saved_nrt
); 
 516                 error 
= rtrequest_scoped_locked(RTM_DELETE
, 
 517                     info
.rti_info
[RTAX_DST
], info
.rti_info
[RTAX_GATEWAY
], 
 518                     info
.rti_info
[RTAX_NETMASK
], rtm
->rtm_flags
, &saved_nrt
, 
 530                 rnh 
= rt_tables
[info
.rti_info
[RTAX_DST
]->sa_family
]; 
 532                         senderr(EAFNOSUPPORT
); 
 534                  * Lookup the best match based on the key-mask pair; 
 535                  * callee adds a reference and checks for root node. 
 537                 rt 
= rt_lookup(TRUE
, info
.rti_info
[RTAX_DST
], 
 538                     info
.rti_info
[RTAX_NETMASK
], rnh
, ifscope
); 
 544                  * Holding rnh_lock here prevents the possibility of 
 545                  * ifa from changing (e.g. in_ifinit), so it is safe 
 546                  * to access its ifa_addr (down below) without locking. 
 548                 switch (rtm
->rtm_type
) { 
 553                         cred 
= kauth_cred_proc_ref(current_proc()); 
 555                         RT_LOCK_ASSERT_HELD(rt
); 
 556                         info
.rti_info
[RTAX_DST
] = rt_key(rt
); 
 557                         dst_sa_family 
= info
.rti_info
[RTAX_DST
]->sa_family
; 
 558                         info
.rti_info
[RTAX_GATEWAY
] = rt
->rt_gateway
; 
 559                         info
.rti_info
[RTAX_NETMASK
] = rt_mask(rt
); 
 560                         info
.rti_info
[RTAX_GENMASK
] = rt
->rt_genmask
; 
 561                         if (rtm
->rtm_addrs 
& (RTA_IFP 
| RTA_IFA
)) { 
 564                                         ifnet_lock_shared(ifp
); 
 565                                         ifa2 
= ifp
->if_lladdr
; 
 566                                         info
.rti_info
[RTAX_IFP
] = 
 569                                         ifnet_lock_done(ifp
); 
 570                                         info
.rti_info
[RTAX_IFA
] = 
 571                                             rt
->rt_ifa
->ifa_addr
; 
 572                                         rtm
->rtm_index 
= ifp
->if_index
; 
 574                                         info
.rti_info
[RTAX_IFP
] = NULL
; 
 575                                         info
.rti_info
[RTAX_IFA
] = NULL
; 
 577                         } else if ((ifp 
= rt
->rt_ifp
) != NULL
) { 
 578                                 rtm
->rtm_index 
= ifp
->if_index
; 
 582                         len 
= rt_msg2(rtm
->rtm_type
, &info
, NULL
, NULL
, &cred
); 
 585                         struct rt_msghdr 
*out_rtm
; 
 586                         R_Malloc(out_rtm
, struct rt_msghdr 
*, len
); 
 587                         if (out_rtm 
== NULL
) { 
 593                         Bcopy(rtm
, out_rtm
, sizeof(struct rt_msghdr
)); 
 596                         (void) rt_msg2(out_rtm
->rtm_type
, &info
, (caddr_t
)out_rtm
, 
 602                         rtm
->rtm_flags 
= rt
->rt_flags
; 
 603                         rt_getmetrics(rt
, &rtm
->rtm_rmx
); 
 604                         rtm
->rtm_addrs 
= info
.rti_addrs
; 
 608                         kauth_cred_unref(&cred
); 
 613                         is_router 
= (rt
->rt_flags 
& RTF_ROUTER
) ? TRUE 
: FALSE
; 
 615                         if (info
.rti_info
[RTAX_GATEWAY
] != NULL 
&& 
 616                             (error 
= rt_setgate(rt
, rt_key(rt
), 
 617                             info
.rti_info
[RTAX_GATEWAY
]))) { 
 623                          * If they tried to change things but didn't specify 
 624                          * the required gateway, then just use the old one. 
 625                          * This can happen if the user tries to change the 
 626                          * flags on the default route without changing the 
 627                          * default gateway. Changing flags still doesn't work. 
 629                         if ((rt
->rt_flags 
& RTF_GATEWAY
) && 
 630                             info
.rti_info
[RTAX_GATEWAY
] == NULL
) 
 631                                 info
.rti_info
[RTAX_GATEWAY
] = rt
->rt_gateway
; 
 634                          * On Darwin, we call rt_setif which contains the 
 635                          * equivalent to the code found at this very spot 
 639                             info
.rti_info
[RTAX_IFP
], info
.rti_info
[RTAX_IFA
], 
 640                             info
.rti_info
[RTAX_GATEWAY
], ifscope
); 
 642                         if ((error 
= rt_setmetrics(rtm
->rtm_inits
, 
 643                             &rtm
->rtm_rmx
, rt
))) { 
 648                         if (info
.rti_info
[RTAX_GENMASK
]) 
 649                                 rt
->rt_genmask 
= info
.rti_info
[RTAX_GENMASK
]; 
 652                          * Enqueue work item to invoke callback for this route entry 
 653                          * This may not be needed always, but for now issue it anytime 
 654                          * RTM_CHANGE gets called. 
 656                         route_event_enqueue_nwk_wq_entry(rt
, NULL
, ROUTE_ENTRY_REFRESH
, NULL
, TRUE
); 
 658                          * If the route is for a router, walk the tree to send refresh 
 659                          * event to protocol cloned entries 
 662                                 struct route_event rt_ev
; 
 663                                 route_event_init(&rt_ev
, rt
, NULL
, ROUTE_ENTRY_REFRESH
); 
 665                                 (void) rnh
->rnh_walktree(rnh
, route_event_walktree
, (void *)&rt_ev
); 
 670                         rt
->rt_rmx
.rmx_locks 
&= ~(rtm
->rtm_inits
); 
 671                         rt
->rt_rmx
.rmx_locks 
|= 
 672                             (rtm
->rtm_inits 
& rtm
->rtm_rmx
.rmx_locks
); 
 684                         rtm
->rtm_errno 
= error
; 
 686                         rtm
->rtm_flags 
|= RTF_DONE
; 
 689                 RT_LOCK_ASSERT_NOTHELD(rt
); 
 692         lck_mtx_unlock(rnh_lock
); 
 694         /* relock the socket now */ 
 697          * Check to see if we don't want our own messages. 
 699         if (!(so
->so_options 
& SO_USELOOPBACK
)) { 
 700                 if (route_cb
.any_count 
<= 1) { 
 706                 /* There is another listener, so construct message */ 
 710                 m_copyback(m
, 0, rtm
->rtm_msglen
, (caddr_t
)rtm
); 
 711                 if (m
->m_pkthdr
.len 
< rtm
->rtm_msglen
) { 
 714                 } else if (m
->m_pkthdr
.len 
> rtm
->rtm_msglen
) { 
 715                         m_adj(m
, rtm
->rtm_msglen 
- m
->m_pkthdr
.len
); 
 719         if (sendonlytoself 
&& m 
!= NULL
) { 
 721                 if (sbappendaddr(&so
->so_rcv
, &route_src
, m
, 
 722                     NULL
, &error
) != 0) { 
 728                 struct sockproto route_proto 
= { PF_ROUTE
, 0 }; 
 730                         rp
->rcb_proto
.sp_family 
= 0; /* Avoid us */ 
 731                 if (dst_sa_family 
!= 0) 
 732                         route_proto
.sp_protocol 
= dst_sa_family
; 
 734                         socket_unlock(so
, 0); 
 735                         raw_input(m
, &route_proto
, &route_src
, &route_dst
); 
 739                         rp
->rcb_proto
.sp_family 
= PF_ROUTE
; 
 745 rt_setexpire(struct rtentry 
*rt
, uint64_t expiry
) 
 747         /* set both rt_expire and rmx_expire */ 
 748         rt
->rt_expire 
= expiry
; 
 750                 rt
->rt_rmx
.rmx_expire 
= expiry 
+ rt
->base_calendartime 
- 
 753                 rt
->rt_rmx
.rmx_expire 
= 0; 
 758 rt_setmetrics(u_int32_t which
, struct rt_metrics 
*in
, struct rtentry 
*out
) 
 760         if (!(which 
& RTV_REFRESH_HOST
)) { 
 761                 struct timeval caltime
; 
 762                 getmicrotime(&caltime
); 
 763 #define metric(f, e) if (which & (f)) out->rt_rmx.e = in->e; 
 764                 metric(RTV_RPIPE
, rmx_recvpipe
); 
 765                 metric(RTV_SPIPE
, rmx_sendpipe
); 
 766                 metric(RTV_SSTHRESH
, rmx_ssthresh
); 
 767                 metric(RTV_RTT
, rmx_rtt
); 
 768                 metric(RTV_RTTVAR
, rmx_rttvar
); 
 769                 metric(RTV_HOPCOUNT
, rmx_hopcount
); 
 770                 metric(RTV_MTU
, rmx_mtu
); 
 771                 metric(RTV_EXPIRE
, rmx_expire
); 
 773                 if (out
->rt_rmx
.rmx_expire 
> 0) { 
 774                         /* account for system time change */ 
 775                         getmicrotime(&caltime
); 
 776                         out
->base_calendartime 
+= 
 777                                 NET_CALCULATE_CLOCKSKEW(caltime
, 
 778                                                 out
->base_calendartime
, 
 779                                                 net_uptime(), out
->base_uptime
); 
 781                                         out
->rt_rmx
.rmx_expire 
- 
 782                                         out
->base_calendartime 
+ 
 785                         rt_setexpire(out
, 0); 
 788                 VERIFY(out
->rt_expire 
== 0 || out
->rt_rmx
.rmx_expire 
!= 0); 
 789                 VERIFY(out
->rt_expire 
!= 0 || out
->rt_rmx
.rmx_expire 
== 0); 
 791                 /* Only RTV_REFRESH_HOST must be set */ 
 792                 if ((which 
& ~RTV_REFRESH_HOST
) || 
 793                     (out
->rt_flags 
& RTF_STATIC
) || 
 794                     !(out
->rt_flags 
& RTF_LLINFO
)) { 
 798                 if (out
->rt_llinfo_refresh 
== NULL
) { 
 802                 out
->rt_llinfo_refresh(out
); 
 808 rt_getmetrics(struct rtentry 
*in
, struct rt_metrics 
*out
) 
 810         struct timeval caltime
; 
 812         VERIFY(in
->rt_expire 
== 0 || in
->rt_rmx
.rmx_expire 
!= 0); 
 813         VERIFY(in
->rt_expire 
!= 0 || in
->rt_rmx
.rmx_expire 
== 0); 
 817         if (in
->rt_expire 
!= 0) { 
 818                 /* account for system time change */ 
 819                 getmicrotime(&caltime
); 
 821                 in
->base_calendartime 
+= 
 822                     NET_CALCULATE_CLOCKSKEW(caltime
, 
 823                     in
->base_calendartime
, net_uptime(), in
->base_uptime
); 
 825                 out
->rmx_expire 
= in
->base_calendartime 
+ 
 826                     in
->rt_expire 
- in
->base_uptime
; 
 833  * Set route's interface given info.rti_info[RTAX_IFP], 
 834  * info.rti_info[RTAX_IFA], and gateway. 
 837 rt_setif(struct rtentry 
*rt
, struct sockaddr 
*Ifpaddr
, struct sockaddr 
*Ifaaddr
, 
 838     struct sockaddr 
*Gate
, unsigned int ifscope
) 
 840         struct ifaddr 
*ifa 
= NULL
; 
 841         struct ifnet 
*ifp 
= NULL
; 
 842         void (*ifa_rtrequest
)(int, struct rtentry 
*, struct sockaddr 
*); 
 844         LCK_MTX_ASSERT(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
 846         RT_LOCK_ASSERT_HELD(rt
); 
 848         /* Don't update a defunct route */ 
 849         if (rt
->rt_flags 
& RTF_CONDEMNED
) 
 852         /* Add an extra ref for ourselves */ 
 853         RT_ADDREF_LOCKED(rt
); 
 855         /* Become a regular mutex, just in case */ 
 859          * New gateway could require new ifaddr, ifp; flags may also 
 860          * be different; ifp may be specified by ll sockaddr when 
 861          * protocol address is ambiguous. 
 863         if (Ifpaddr 
&& (ifa 
= ifa_ifwithnet_scoped(Ifpaddr
, ifscope
)) && 
 864             (ifp 
= ifa
->ifa_ifp
) && (Ifaaddr 
|| Gate
)) { 
 866                 ifa 
= ifaof_ifpforaddr(Ifaaddr 
? Ifaaddr 
: Gate
, ifp
); 
 872                 if (Ifpaddr 
&& (ifp 
= if_withname(Ifpaddr
))) { 
 874                                 ifa 
= ifaof_ifpforaddr(Gate
, ifp
); 
 876                                 ifnet_lock_shared(ifp
); 
 877                                 ifa 
= TAILQ_FIRST(&ifp
->if_addrhead
); 
 880                                 ifnet_lock_done(ifp
); 
 882                 } else if (Ifaaddr 
&& 
 883                     (ifa 
= ifa_ifwithaddr_scoped(Ifaaddr
, ifscope
))) { 
 885                 } else if (Gate 
!= NULL
) { 
 887                          * Safe to drop rt_lock and use rt_key, since holding 
 888                          * rnh_lock here prevents another thread from calling 
 889                          * rt_setgate() on this route.  We cannot hold the 
 890                          * lock across ifa_ifwithroute since the lookup done 
 891                          * by that routine may point to the same route. 
 894                         if ((ifa 
= ifa_ifwithroute_scoped_locked(rt
->rt_flags
, 
 895                             rt_key(rt
), Gate
, ifscope
)) != NULL
) 
 898                         /* Don't update a defunct route */ 
 899                         if (rt
->rt_flags 
& RTF_CONDEMNED
) { 
 902                                 /* Release extra ref */ 
 903                                 RT_REMREF_LOCKED(rt
); 
 909         /* trigger route cache reevaluation */ 
 910         if (rt_key(rt
)->sa_family 
== AF_INET
) 
 911                 routegenid_inet_update(); 
 913         else if (rt_key(rt
)->sa_family 
== AF_INET6
) 
 914                 routegenid_inet6_update(); 
 918                 struct ifaddr 
*oifa 
= rt
->rt_ifa
; 
 922                                 ifa_rtrequest 
= oifa
->ifa_rtrequest
; 
 924                                 if (ifa_rtrequest 
!= NULL
) 
 925                                         ifa_rtrequest(RTM_DELETE
, rt
, Gate
); 
 929                         if (rt
->rt_ifp 
!= ifp
) { 
 931                                  * Purge any link-layer info caching. 
 933                                 if (rt
->rt_llinfo_purge 
!= NULL
) 
 934                                         rt
->rt_llinfo_purge(rt
); 
 937                                  * Adjust route ref count for the interfaces. 
 939                                 if (rt
->rt_if_ref_fn 
!= NULL
) { 
 940                                         rt
->rt_if_ref_fn(ifp
, 1); 
 941                                         rt
->rt_if_ref_fn(rt
->rt_ifp
, -1); 
 946                          * If this is the (non-scoped) default route, record 
 947                          * the interface index used for the primary ifscope. 
 949                         if (rt_primary_default(rt
, rt_key(rt
))) { 
 950                                 set_primary_ifscope(rt_key(rt
)->sa_family
, 
 951                                     rt
->rt_ifp
->if_index
); 
 954                          * If rmx_mtu is not locked, update it 
 955                          * to the MTU used by the new interface. 
 957                         if (!(rt
->rt_rmx
.rmx_locks 
& RTV_MTU
)) 
 958                                 rt
->rt_rmx
.rmx_mtu 
= rt
->rt_ifp
->if_mtu
; 
 960                         if (rt
->rt_ifa 
!= NULL
) { 
 961                                 IFA_LOCK_SPIN(rt
->rt_ifa
); 
 962                                 ifa_rtrequest 
= rt
->rt_ifa
->ifa_rtrequest
; 
 963                                 IFA_UNLOCK(rt
->rt_ifa
); 
 964                                 if (ifa_rtrequest 
!= NULL
) 
 965                                         ifa_rtrequest(RTM_ADD
, rt
, Gate
); 
 968                         /* Release extra ref */ 
 969                         RT_REMREF_LOCKED(rt
); 
 976         /* XXX: to reset gateway to correct value, at RTM_CHANGE */ 
 977         if (rt
->rt_ifa 
!= NULL
) { 
 978                 IFA_LOCK_SPIN(rt
->rt_ifa
); 
 979                 ifa_rtrequest 
= rt
->rt_ifa
->ifa_rtrequest
; 
 980                 IFA_UNLOCK(rt
->rt_ifa
); 
 981                 if (ifa_rtrequest 
!= NULL
) 
 982                         ifa_rtrequest(RTM_ADD
, rt
, Gate
); 
 986          * Workaround for local address routes pointing to the loopback 
 987          * interface added by configd, until <rdar://problem/12970142>. 
 989         if ((rt
->rt_ifp
->if_flags 
& IFF_LOOPBACK
) && 
 990             (rt
->rt_flags 
& RTF_HOST
) && rt
->rt_ifa
->ifa_ifp 
== rt
->rt_ifp
) { 
 991                 ifa 
= ifa_ifwithaddr(rt_key(rt
)); 
 993                         if (ifa 
!= rt
->rt_ifa
) 
 999         /* Release extra ref */ 
1000         RT_REMREF_LOCKED(rt
); 
1004  * Extract the addresses of the passed sockaddrs. 
1005  * Do a little sanity checking so as to avoid bad memory references. 
1006  * This data is derived straight from userland. 
1009 rt_xaddrs(caddr_t cp
, caddr_t cplim
, struct rt_addrinfo 
*rtinfo
) 
1011         struct sockaddr 
*sa
; 
1014         bzero(rtinfo
->rti_info
, sizeof (rtinfo
->rti_info
)); 
1015         for (i 
= 0; (i 
< RTAX_MAX
) && (cp 
< cplim
); i
++) { 
1016                 if ((rtinfo
->rti_addrs 
& (1 << i
)) == 0) 
1018                 sa 
= (struct sockaddr 
*)cp
; 
1022                 if ((cp 
+ sa
->sa_len
) > cplim
) 
1025                  * there are no more.. quit now 
1026                  * If there are more bits, they are in error. 
1027                  * I've seen this. route(1) can evidently generate these. 
1028                  * This causes kernel to core dump. 
1029                  * for compatibility, If we see this, point to a safe address. 
1031                 if (sa
->sa_len 
== 0) { 
1032                         rtinfo
->rti_info
[i
] = &sa_zero
; 
1033                         return (0); /* should be EINVAL but for compat */ 
1036                 rtinfo
->rti_info
[i
] = sa
; 
1042 static struct mbuf 
* 
1043 rt_msg1(int type
, struct rt_addrinfo 
*rtinfo
) 
1045         struct rt_msghdr 
*rtm
; 
1054                 len 
= sizeof (struct ifa_msghdr
); 
1059                 len 
= sizeof (struct ifma_msghdr
); 
1063                 len 
= sizeof (struct if_msghdr
); 
1067                 len 
= sizeof (struct rt_msghdr
); 
1069         m 
= m_gethdr(M_DONTWAIT
, MT_DATA
); 
1070         if (m 
&& len 
> MHLEN
) { 
1071                 MCLGET(m
, M_DONTWAIT
); 
1072                 if (!(m
->m_flags 
& M_EXT
)) { 
1079         m
->m_pkthdr
.len 
= m
->m_len 
= len
; 
1080         m
->m_pkthdr
.rcvif 
= NULL
; 
1081         rtm 
= mtod(m
, struct rt_msghdr 
*); 
1082         bzero((caddr_t
)rtm
, len
); 
1084         for (i 
= 0; i 
< RTAX_MAX
; i
++) { 
1085                 struct sockaddr 
*sa
, *hint
; 
1086                 uint8_t ssbuf
[SOCK_MAXADDRLEN 
+ 1]; 
1089                  * Make sure to accomodate the largest possible size of sa_len. 
1091                 _CASSERT(sizeof (ssbuf
) == (SOCK_MAXADDRLEN 
+ 1)); 
1093                 if ((sa 
= rtinfo
->rti_info
[i
]) == NULL
) 
1099                         if ((hint 
= rtinfo
->rti_info
[RTAX_DST
]) == NULL
) 
1100                                 hint 
= rtinfo
->rti_info
[RTAX_IFA
]; 
1102                         /* Scrub away any trace of embedded interface scope */ 
1103                         sa 
= rtm_scrub(type
, i
, hint
, sa
, &ssbuf
, 
1104                             sizeof (ssbuf
), NULL
); 
1111                 rtinfo
->rti_addrs 
|= (1 << i
); 
1113                 m_copyback(m
, off
, dlen
, (caddr_t
)sa
); 
1115                 off 
+= ROUNDUP32(dlen
); 
1117         if (m
->m_pkthdr
.len 
!= len
) { 
1121         rtm
->rtm_msglen 
= len
; 
1122         rtm
->rtm_version 
= RTM_VERSION
; 
1123         rtm
->rtm_type 
= type
; 
1128 rt_msg2(int type
, struct rt_addrinfo 
*rtinfo
, caddr_t cp
, struct walkarg 
*w
, 
1129         kauth_cred_t
* credp
) 
1132         int len
, dlen
, rlen
, second_time 
= 0; 
1135         rtinfo
->rti_addrs 
= 0; 
1141                 len 
= sizeof (struct ifa_msghdr
); 
1146                 len 
= sizeof (struct ifma_msghdr
); 
1150                 len 
= sizeof (struct if_msghdr
); 
1154                 len 
= sizeof (struct if_msghdr2
); 
1158                 len 
= sizeof (struct ifma_msghdr2
); 
1162                 len 
= sizeof (struct rt_msghdr_ext
); 
1166                 len 
= sizeof (struct rt_msghdr2
); 
1170                 len 
= sizeof (struct rt_msghdr
); 
1175         for (i 
= 0; i 
< RTAX_MAX
; i
++) { 
1176                 struct sockaddr 
*sa
, *hint
; 
1177                 uint8_t ssbuf
[SOCK_MAXADDRLEN 
+ 1]; 
1180                  * Make sure to accomodate the largest possible size of sa_len. 
1182                 _CASSERT(sizeof (ssbuf
) == (SOCK_MAXADDRLEN 
+ 1)); 
1184                 if ((sa 
= rtinfo
->rti_info
[i
]) == NULL
) 
1190                         if ((hint 
= rtinfo
->rti_info
[RTAX_DST
]) == NULL
) 
1191                                 hint 
= rtinfo
->rti_info
[RTAX_IFA
]; 
1193                         /* Scrub away any trace of embedded interface scope */ 
1194                         sa 
= rtm_scrub(type
, i
, hint
, sa
, &ssbuf
, 
1195                             sizeof (ssbuf
), NULL
); 
1199                         sa 
= rtm_scrub(type
, i
, NULL
, sa
, &ssbuf
, 
1200                             sizeof (ssbuf
), credp
); 
1207                 rtinfo
->rti_addrs 
|= (1 << i
); 
1209                 rlen 
= ROUNDUP32(dlen
); 
1211                         bcopy((caddr_t
)sa
, cp
, (size_t)dlen
); 
1213                                 bzero(cp 
+ dlen
, rlen 
- dlen
); 
1218         if (cp 
== NULL 
&& w 
!= NULL 
&& !second_time
) { 
1219                 struct walkarg 
*rw 
= w
; 
1221                 if (rw
->w_req 
!= NULL
) { 
1222                         if (rw
->w_tmemsize 
< len
) { 
1223                                 if (rw
->w_tmem 
!= NULL
) 
1224                                         FREE(rw
->w_tmem
, M_RTABLE
); 
1225                                 rw
->w_tmem 
= _MALLOC(len
, M_RTABLE
, M_WAITOK
); 
1226                                 if (rw
->w_tmem 
!= NULL
) 
1227                                         rw
->w_tmemsize 
= len
; 
1229                         if (rw
->w_tmem 
!= NULL
) { 
1237                 struct rt_msghdr 
*rtm 
= (struct rt_msghdr 
*)(void *)cp0
; 
1239                 rtm
->rtm_version 
= RTM_VERSION
; 
1240                 rtm
->rtm_type 
= type
; 
1241                 rtm
->rtm_msglen 
= len
; 
1247  * This routine is called to generate a message from the routing 
1248  * socket indicating that a redirect has occurred, a routing lookup 
1249  * has failed, or that a protocol has detected timeouts to a particular 
1253 rt_missmsg(int type
, struct rt_addrinfo 
*rtinfo
, int flags
, int error
) 
1255         struct rt_msghdr 
*rtm
; 
1257         struct sockaddr 
*sa 
= rtinfo
->rti_info
[RTAX_DST
]; 
1258         struct sockproto route_proto 
= { PF_ROUTE
, 0 }; 
1260         if (route_cb
.any_count 
== 0) 
1262         m 
= rt_msg1(type
, rtinfo
); 
1265         rtm 
= mtod(m
, struct rt_msghdr 
*); 
1266         rtm
->rtm_flags 
= RTF_DONE 
| flags
; 
1267         rtm
->rtm_errno 
= error
; 
1268         rtm
->rtm_addrs 
= rtinfo
->rti_addrs
; 
1269         route_proto
.sp_family 
= sa 
? sa
->sa_family 
: 0; 
1270         raw_input(m
, &route_proto
, &route_src
, &route_dst
); 
1274  * This routine is called to generate a message from the routing 
1275  * socket indicating that the status of a network interface has changed. 
1278 rt_ifmsg(struct ifnet 
*ifp
) 
1280         struct if_msghdr 
*ifm
; 
1282         struct rt_addrinfo info
; 
1283         struct  sockproto route_proto 
= { PF_ROUTE
, 0 }; 
1285         if (route_cb
.any_count 
== 0) 
1287         bzero((caddr_t
)&info
, sizeof (info
)); 
1288         m 
= rt_msg1(RTM_IFINFO
, &info
); 
1291         ifm 
= mtod(m
, struct if_msghdr 
*); 
1292         ifm
->ifm_index 
= ifp
->if_index
; 
1293         ifm
->ifm_flags 
= (u_short
)ifp
->if_flags
; 
1294         if_data_internal_to_if_data(ifp
, &ifp
->if_data
, &ifm
->ifm_data
); 
1296         raw_input(m
, &route_proto
, &route_src
, &route_dst
); 
1300  * This is called to generate messages from the routing socket 
1301  * indicating a network interface has had addresses associated with it. 
1302  * if we ever reverse the logic and replace messages TO the routing 
1303  * socket indicate a request to configure interfaces, then it will 
1304  * be unnecessary as the routing socket will automatically generate 
1307  * Since this is coming from the interface, it is expected that the 
1308  * interface will be locked.  Caller must hold rnh_lock and rt_lock. 
1311 rt_newaddrmsg(int cmd
, struct ifaddr 
*ifa
, int error
, struct rtentry 
*rt
) 
1313         struct rt_addrinfo info
; 
1314         struct sockaddr 
*sa 
= 0; 
1317         struct ifnet 
*ifp 
= ifa
->ifa_ifp
; 
1318         struct sockproto route_proto 
= { PF_ROUTE
, 0 }; 
1320         LCK_MTX_ASSERT(rnh_lock
, LCK_MTX_ASSERT_OWNED
); 
1321         RT_LOCK_ASSERT_HELD(rt
); 
1323         if (route_cb
.any_count 
== 0) 
1326         /* Become a regular mutex, just in case */ 
1327         RT_CONVERT_LOCK(rt
); 
1328         for (pass 
= 1; pass 
< 3; pass
++) { 
1329                 bzero((caddr_t
)&info
, sizeof (info
)); 
1330                 if ((cmd 
== RTM_ADD 
&& pass 
== 1) || 
1331                     (cmd 
== RTM_DELETE 
&& pass 
== 2)) { 
1332                         struct ifa_msghdr 
*ifam
; 
1333                         int ncmd 
= cmd 
== RTM_ADD 
? RTM_NEWADDR 
: RTM_DELADDR
; 
1335                         /* Lock ifp for if_lladdr */ 
1336                         ifnet_lock_shared(ifp
); 
1338                         info
.rti_info
[RTAX_IFA
] = sa 
= ifa
->ifa_addr
; 
1340                          * Holding ifnet lock here prevents the link address 
1341                          * from changing contents, so no need to hold its 
1342                          * lock.  The link address is always present; it's 
1345                         info
.rti_info
[RTAX_IFP
] = ifp
->if_lladdr
->ifa_addr
; 
1346                         info
.rti_info
[RTAX_NETMASK
] = ifa
->ifa_netmask
; 
1347                         info
.rti_info
[RTAX_BRD
] = ifa
->ifa_dstaddr
; 
1348                         if ((m 
= rt_msg1(ncmd
, &info
)) == NULL
) { 
1350                                 ifnet_lock_done(ifp
); 
1354                         ifnet_lock_done(ifp
); 
1355                         ifam 
= mtod(m
, struct ifa_msghdr 
*); 
1356                         ifam
->ifam_index 
= ifp
->if_index
; 
1358                         ifam
->ifam_metric 
= ifa
->ifa_metric
; 
1359                         ifam
->ifam_flags 
= ifa
->ifa_flags
; 
1361                         ifam
->ifam_addrs 
= info
.rti_addrs
; 
1363                 if ((cmd 
== RTM_ADD 
&& pass 
== 2) || 
1364                     (cmd 
== RTM_DELETE 
&& pass 
== 1)) { 
1365                         struct rt_msghdr 
*rtm
; 
1369                         info
.rti_info
[RTAX_NETMASK
] = rt_mask(rt
); 
1370                         info
.rti_info
[RTAX_DST
] = sa 
= rt_key(rt
); 
1371                         info
.rti_info
[RTAX_GATEWAY
] = rt
->rt_gateway
; 
1372                         if ((m 
= rt_msg1(cmd
, &info
)) == NULL
) 
1374                         rtm 
= mtod(m
, struct rt_msghdr 
*); 
1375                         rtm
->rtm_index 
= ifp
->if_index
; 
1376                         rtm
->rtm_flags 
|= rt
->rt_flags
; 
1377                         rtm
->rtm_errno 
= error
; 
1378                         rtm
->rtm_addrs 
= info
.rti_addrs
; 
1380                 route_proto
.sp_protocol 
= sa 
? sa
->sa_family 
: 0; 
1381                 raw_input(m
, &route_proto
, &route_src
, &route_dst
); 
1386  * This is the analogue to the rt_newaddrmsg which performs the same 
1387  * function but for multicast group memberhips.  This is easier since 
1388  * there is no route state to worry about. 
1391 rt_newmaddrmsg(int cmd
, struct ifmultiaddr 
*ifma
) 
1393         struct rt_addrinfo info
; 
1395         struct ifnet 
*ifp 
= ifma
->ifma_ifp
; 
1396         struct ifma_msghdr 
*ifmam
; 
1397         struct sockproto route_proto 
= { PF_ROUTE
, 0 }; 
1399         if (route_cb
.any_count 
== 0) 
1402         /* Lock ifp for if_lladdr */ 
1403         ifnet_lock_shared(ifp
); 
1404         bzero((caddr_t
)&info
, sizeof (info
)); 
1406         info
.rti_info
[RTAX_IFA
] = ifma
->ifma_addr
; 
1407         /* lladdr doesn't need lock */ 
1408         info
.rti_info
[RTAX_IFP
] = ifp
->if_lladdr
->ifa_addr
; 
1411          * If a link-layer address is present, present it as a ``gateway'' 
1412          * (similarly to how ARP entries, e.g., are presented). 
1414         info
.rti_info
[RTAX_GATEWAY
] = (ifma
->ifma_ll 
!= NULL
) ? 
1415             ifma
->ifma_ll
->ifma_addr 
: NULL
; 
1416         if ((m 
= rt_msg1(cmd
, &info
)) == NULL
) { 
1418                 ifnet_lock_done(ifp
); 
1421         ifmam 
= mtod(m
, struct ifma_msghdr 
*); 
1422         ifmam
->ifmam_index 
= ifp
->if_index
; 
1423         ifmam
->ifmam_addrs 
= info
.rti_addrs
; 
1424         route_proto
.sp_protocol 
= ifma
->ifma_addr
->sa_family
; 
1426         ifnet_lock_done(ifp
); 
1427         raw_input(m
, &route_proto
, &route_src
, &route_dst
); 
1433         const char *c 
= "RTM_?"; 
1484         case RTM_GET_SILENT
: 
1485                 c 
= "RTM_GET_SILENT"; 
1491                 c 
= "RTM_NEWMADDR2"; 
1505  * This is used in dumping the kernel table via sysctl(). 
1508 sysctl_dumpentry(struct radix_node 
*rn
, void *vw
) 
1510         struct walkarg 
*w 
= vw
; 
1511         struct rtentry 
*rt 
= (struct rtentry 
*)rn
; 
1512         int error 
= 0, size
; 
1513         struct rt_addrinfo info
; 
1516         cred 
= kauth_cred_proc_ref(current_proc()); 
1519         if (w
->w_op 
== NET_RT_FLAGS 
&& !(rt
->rt_flags 
& w
->w_arg
)) 
1521         bzero((caddr_t
)&info
, sizeof (info
)); 
1522         info
.rti_info
[RTAX_DST
] = rt_key(rt
); 
1523         info
.rti_info
[RTAX_GATEWAY
] = rt
->rt_gateway
; 
1524         info
.rti_info
[RTAX_NETMASK
] = rt_mask(rt
); 
1525         info
.rti_info
[RTAX_GENMASK
] = rt
->rt_genmask
; 
1527         if (w
->w_op 
!= NET_RT_DUMP2
) { 
1528                 size 
= rt_msg2(RTM_GET
, &info
, NULL
, w
, &cred
); 
1529                 if (w
->w_req 
!= NULL 
&& w
->w_tmem 
!= NULL
) { 
1530                         struct rt_msghdr 
*rtm 
= 
1531                             (struct rt_msghdr 
*)(void *)w
->w_tmem
; 
1533                         rtm
->rtm_flags 
= rt
->rt_flags
; 
1534                         rtm
->rtm_use 
= rt
->rt_use
; 
1535                         rt_getmetrics(rt
, &rtm
->rtm_rmx
); 
1536                         rtm
->rtm_index 
= rt
->rt_ifp
->if_index
; 
1540                         rtm
->rtm_addrs 
= info
.rti_addrs
; 
1541                         error 
= SYSCTL_OUT(w
->w_req
, (caddr_t
)rtm
, size
); 
1544                 size 
= rt_msg2(RTM_GET2
, &info
, NULL
, w
, &cred
); 
1545                 if (w
->w_req 
!= NULL 
&& w
->w_tmem 
!= NULL
) { 
1546                         struct rt_msghdr2 
*rtm 
= 
1547                             (struct rt_msghdr2 
*)(void *)w
->w_tmem
; 
1549                         rtm
->rtm_flags 
= rt
->rt_flags
; 
1550                         rtm
->rtm_use 
= rt
->rt_use
; 
1551                         rt_getmetrics(rt
, &rtm
->rtm_rmx
); 
1552                         rtm
->rtm_index 
= rt
->rt_ifp
->if_index
; 
1553                         rtm
->rtm_refcnt 
= rt
->rt_refcnt
; 
1555                                 rtm
->rtm_parentflags 
= rt
->rt_parent
->rt_flags
; 
1557                                 rtm
->rtm_parentflags 
= 0; 
1558                         rtm
->rtm_reserved 
= 0; 
1559                         rtm
->rtm_addrs 
= info
.rti_addrs
; 
1560                         error 
= SYSCTL_OUT(w
->w_req
, (caddr_t
)rtm
, size
); 
1566         kauth_cred_unref(&cred
); 
1571  * This is used for dumping extended information from route entries. 
1574 sysctl_dumpentry_ext(struct radix_node 
*rn
, void *vw
) 
1576         struct walkarg 
*w 
= vw
; 
1577         struct rtentry 
*rt 
= (struct rtentry 
*)rn
; 
1578         int error 
= 0, size
; 
1579         struct rt_addrinfo info
; 
1582         cred 
= kauth_cred_proc_ref(current_proc()); 
1585         if (w
->w_op 
== NET_RT_DUMPX_FLAGS 
&& !(rt
->rt_flags 
& w
->w_arg
)) 
1587         bzero(&info
, sizeof (info
)); 
1588         info
.rti_info
[RTAX_DST
] = rt_key(rt
); 
1589         info
.rti_info
[RTAX_GATEWAY
] = rt
->rt_gateway
; 
1590         info
.rti_info
[RTAX_NETMASK
] = rt_mask(rt
); 
1591         info
.rti_info
[RTAX_GENMASK
] = rt
->rt_genmask
; 
1593         size 
= rt_msg2(RTM_GET_EXT
, &info
, NULL
, w
, &cred
); 
1594         if (w
->w_req 
!= NULL 
&& w
->w_tmem 
!= NULL
) { 
1595                 struct rt_msghdr_ext 
*ertm 
= 
1596                     (struct rt_msghdr_ext 
*)(void *)w
->w_tmem
; 
1598                 ertm
->rtm_flags 
= rt
->rt_flags
; 
1599                 ertm
->rtm_use 
= rt
->rt_use
; 
1600                 rt_getmetrics(rt
, &ertm
->rtm_rmx
); 
1601                 ertm
->rtm_index 
= rt
->rt_ifp
->if_index
; 
1604                 ertm
->rtm_errno 
= 0; 
1605                 ertm
->rtm_addrs 
= info
.rti_addrs
; 
1606                 if (rt
->rt_llinfo_get_ri 
== NULL
) { 
1607                         bzero(&ertm
->rtm_ri
, sizeof (ertm
->rtm_ri
)); 
1608                         ertm
->rtm_ri
.ri_rssi 
= IFNET_RSSI_UNKNOWN
; 
1609                         ertm
->rtm_ri
.ri_lqm 
= IFNET_LQM_THRESH_OFF
; 
1610                         ertm
->rtm_ri
.ri_npm 
= IFNET_NPM_THRESH_UNKNOWN
; 
1612                         rt
->rt_llinfo_get_ri(rt
, &ertm
->rtm_ri
); 
1614                 error 
= SYSCTL_OUT(w
->w_req
, (caddr_t
)ertm
, size
); 
1619         kauth_cred_unref(&cred
); 
1625  * To avoid to call copyout() while holding locks and to cause problems 
1626  * in the paging path, sysctl_iflist() and sysctl_iflist2() contstruct 
1627  * the list in two passes. In the first pass we compute the total 
1628  * length of the data we are going to copyout, then we release 
1629  * all locks to allocate a temporary buffer that gets filled 
1630  * in the second pass. 
1632  * Note that we are verifying the assumption that _MALLOC returns a buffer 
1633  * that is at least 32 bits aligned and that the messages and addresses are 
1637 sysctl_iflist(int af
, struct walkarg 
*w
) 
1641         struct  rt_addrinfo info
; 
1642         int     len 
= 0, error 
= 0; 
1644         int     total_len 
= 0, current_len 
= 0; 
1645         char    *total_buffer 
= NULL
, *cp 
= NULL
; 
1648         cred 
= kauth_cred_proc_ref(current_proc()); 
1650         bzero((caddr_t
)&info
, sizeof (info
)); 
1652         for (pass 
= 0; pass 
< 2; pass
++) { 
1653                 ifnet_head_lock_shared(); 
1655                 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) { 
1658                         if (w
->w_arg 
&& w
->w_arg 
!= ifp
->if_index
) 
1660                         ifnet_lock_shared(ifp
); 
1662                          * Holding ifnet lock here prevents the link address 
1663                          * from changing contents, so no need to hold the ifa 
1664                          * lock.  The link address is always present; it's 
1667                         ifa 
= ifp
->if_lladdr
; 
1668                         info
.rti_info
[RTAX_IFP
] = ifa
->ifa_addr
; 
1669                         len 
= rt_msg2(RTM_IFINFO
, &info
, NULL
, NULL
, &cred
); 
1673                                 struct if_msghdr 
*ifm
; 
1675                                 if (current_len 
+ len 
> total_len
) { 
1676                                         ifnet_lock_done(ifp
); 
1680                                 info
.rti_info
[RTAX_IFP
] = ifa
->ifa_addr
; 
1681                                 len 
= rt_msg2(RTM_IFINFO
, &info
, 
1682                                     (caddr_t
)cp
, NULL
, &cred
); 
1683                                 info
.rti_info
[RTAX_IFP
] = NULL
; 
1685                                 ifm 
= (struct if_msghdr 
*)(void *)cp
; 
1686                                 ifm
->ifm_index 
= ifp
->if_index
; 
1687                                 ifm
->ifm_flags 
= (u_short
)ifp
->if_flags
; 
1688                                 if_data_internal_to_if_data(ifp
, &ifp
->if_data
, 
1690                                 ifm
->ifm_addrs 
= info
.rti_addrs
; 
1692                                  * <rdar://problem/32940901> 
1693                                  * Round bytes only for non-platform 
1695                                 if (!csproc_get_platform_binary(w
->w_req
->p
)) { 
1696                                         ALIGN_BYTES(ifm
->ifm_data
.ifi_ibytes
); 
1697                                         ALIGN_BYTES(ifm
->ifm_data
.ifi_obytes
); 
1701                                 VERIFY(IS_P2ALIGNED(cp
, sizeof (u_int32_t
))); 
1704                         while ((ifa 
= ifa
->ifa_link
.tqe_next
) != NULL
) { 
1706                                 if (af 
&& af 
!= ifa
->ifa_addr
->sa_family
) { 
1710                                 info
.rti_info
[RTAX_IFA
] = ifa
->ifa_addr
; 
1711                                 info
.rti_info
[RTAX_NETMASK
] = ifa
->ifa_netmask
; 
1712                                 info
.rti_info
[RTAX_BRD
] = ifa
->ifa_dstaddr
; 
1713                                 len 
= rt_msg2(RTM_NEWADDR
, &info
, NULL
, NULL
, 
1718                                         struct ifa_msghdr 
*ifam
; 
1720                                         if (current_len 
+ len 
> total_len
) { 
1725                                         len 
= rt_msg2(RTM_NEWADDR
, &info
, 
1726                                             (caddr_t
)cp
, NULL
, &cred
); 
1728                                         ifam 
= (struct ifa_msghdr 
*)(void *)cp
; 
1730                                             ifa
->ifa_ifp
->if_index
; 
1731                                         ifam
->ifam_flags 
= ifa
->ifa_flags
; 
1732                                         ifam
->ifam_metric 
= ifa
->ifa_metric
; 
1733                                         ifam
->ifam_addrs 
= info
.rti_addrs
; 
1736                                         VERIFY(IS_P2ALIGNED(cp
, 
1737                                             sizeof (u_int32_t
))); 
1742                         ifnet_lock_done(ifp
); 
1743                         info
.rti_info
[RTAX_IFA
] = info
.rti_info
[RTAX_NETMASK
] = 
1744                             info
.rti_info
[RTAX_BRD
] = NULL
; 
1750                         if (error 
== ENOBUFS
) 
1751                                 printf("%s: current_len (%d) + len (%d) > " 
1752                                     "total_len (%d)\n", __func__
, current_len
, 
1758                         /* Better to return zero length buffer than ENOBUFS */ 
1761                         total_len 
+= total_len 
>> 3; 
1762                         total_buffer 
= _MALLOC(total_len
, M_RTABLE
, 
1764                         if (total_buffer 
== NULL
) { 
1765                                 printf("%s: _MALLOC(%d) failed\n", __func__
, 
1771                         VERIFY(IS_P2ALIGNED(cp
, sizeof (u_int32_t
))); 
1773                         error 
= SYSCTL_OUT(w
->w_req
, total_buffer
, current_len
); 
1779         if (total_buffer 
!= NULL
) 
1780                 _FREE(total_buffer
, M_RTABLE
); 
1782         kauth_cred_unref(&cred
); 
1787 sysctl_iflist2(int af
, struct walkarg 
*w
) 
1791         struct  rt_addrinfo info
; 
1792         int     len 
= 0, error 
= 0; 
1794         int     total_len 
= 0, current_len 
= 0; 
1795         char    *total_buffer 
= NULL
, *cp 
= NULL
; 
1798         cred 
= kauth_cred_proc_ref(current_proc()); 
1800         bzero((caddr_t
)&info
, sizeof (info
)); 
1802         for (pass 
= 0; pass 
< 2; pass
++) { 
1803                 struct ifmultiaddr 
*ifma
; 
1805                 ifnet_head_lock_shared(); 
1807                 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) { 
1810                         if (w
->w_arg 
&& w
->w_arg 
!= ifp
->if_index
) 
1812                         ifnet_lock_shared(ifp
); 
1814                          * Holding ifnet lock here prevents the link address 
1815                          * from changing contents, so no need to hold the ifa 
1816                          * lock.  The link address is always present; it's 
1819                         ifa 
= ifp
->if_lladdr
; 
1820                         info
.rti_info
[RTAX_IFP
] = ifa
->ifa_addr
; 
1821                         len 
= rt_msg2(RTM_IFINFO2
, &info
, NULL
, NULL
, &cred
); 
1825                                 struct if_msghdr2 
*ifm
; 
1827                                 if (current_len 
+ len 
> total_len
) { 
1828                                         ifnet_lock_done(ifp
); 
1832                                 info
.rti_info
[RTAX_IFP
] = ifa
->ifa_addr
; 
1833                                 len 
= rt_msg2(RTM_IFINFO2
, &info
, 
1834                                     (caddr_t
)cp
, NULL
, &cred
); 
1835                                 info
.rti_info
[RTAX_IFP
] = NULL
; 
1837                                 ifm 
= (struct if_msghdr2 
*)(void *)cp
; 
1838                                 ifm
->ifm_addrs 
= info
.rti_addrs
; 
1839                                 ifm
->ifm_flags 
= (u_short
)ifp
->if_flags
; 
1840                                 ifm
->ifm_index 
= ifp
->if_index
; 
1841                                 ifm
->ifm_snd_len 
= IFCQ_LEN(&ifp
->if_snd
); 
1842                                 ifm
->ifm_snd_maxlen 
= IFCQ_MAXLEN(&ifp
->if_snd
); 
1843                                 ifm
->ifm_snd_drops 
= 
1844                                     ifp
->if_snd
.ifcq_dropcnt
.packets
; 
1845                                 ifm
->ifm_timer 
= ifp
->if_timer
; 
1846                                 if_data_internal_to_if_data64(ifp
, 
1847                                     &ifp
->if_data
, &ifm
->ifm_data
); 
1849                                  * <rdar://problem/32940901> 
1850                                  * Round bytes only for non-platform 
1852                                 if (!csproc_get_platform_binary(w
->w_req
->p
)) { 
1853                                         ALIGN_BYTES(ifm
->ifm_data
.ifi_ibytes
); 
1854                                         ALIGN_BYTES(ifm
->ifm_data
.ifi_obytes
); 
1858                                 VERIFY(IS_P2ALIGNED(cp
, sizeof (u_int32_t
))); 
1861                         while ((ifa 
= ifa
->ifa_link
.tqe_next
) != NULL
) { 
1863                                 if (af 
&& af 
!= ifa
->ifa_addr
->sa_family
) { 
1867                                 info
.rti_info
[RTAX_IFA
] = ifa
->ifa_addr
; 
1868                                 info
.rti_info
[RTAX_NETMASK
] = ifa
->ifa_netmask
; 
1869                                 info
.rti_info
[RTAX_BRD
] = ifa
->ifa_dstaddr
; 
1870                                 len 
= rt_msg2(RTM_NEWADDR
, &info
, NULL
, NULL
, 
1875                                         struct ifa_msghdr 
*ifam
; 
1877                                         if (current_len 
+ len 
> total_len
) { 
1882                                         len 
= rt_msg2(RTM_NEWADDR
, &info
, 
1883                                             (caddr_t
)cp
, NULL
, &cred
); 
1885                                         ifam 
= (struct ifa_msghdr 
*)(void *)cp
; 
1887                                             ifa
->ifa_ifp
->if_index
; 
1888                                         ifam
->ifam_flags 
= ifa
->ifa_flags
; 
1889                                         ifam
->ifam_metric 
= ifa
->ifa_metric
; 
1890                                         ifam
->ifam_addrs 
= info
.rti_addrs
; 
1893                                         VERIFY(IS_P2ALIGNED(cp
, 
1894                                             sizeof (u_int32_t
))); 
1900                                 ifnet_lock_done(ifp
); 
1904                         for (ifma 
= LIST_FIRST(&ifp
->if_multiaddrs
); 
1905                             ifma 
!= NULL
; ifma 
= LIST_NEXT(ifma
, ifma_link
)) { 
1906                                 struct ifaddr 
*ifa0
; 
1909                                 if (af 
&& af 
!= ifma
->ifma_addr
->sa_family
) { 
1913                                 bzero((caddr_t
)&info
, sizeof (info
)); 
1914                                 info
.rti_info
[RTAX_IFA
] = ifma
->ifma_addr
; 
1916                                  * Holding ifnet lock here prevents the link 
1917                                  * address from changing contents, so no need 
1918                                  * to hold the ifa0 lock.  The link address is 
1919                                  * always present; it's never freed. 
1921                                 ifa0 
= ifp
->if_lladdr
; 
1922                                 info
.rti_info
[RTAX_IFP
] = ifa0
->ifa_addr
; 
1923                                 if (ifma
->ifma_ll 
!= NULL
) 
1924                                         info
.rti_info
[RTAX_GATEWAY
] = 
1925                                             ifma
->ifma_ll
->ifma_addr
; 
1926                                 len 
= rt_msg2(RTM_NEWMADDR2
, &info
, NULL
, NULL
, 
1931                                         struct ifma_msghdr2 
*ifmam
; 
1933                                         if (current_len 
+ len 
> total_len
) { 
1938                                         len 
= rt_msg2(RTM_NEWMADDR2
, &info
, 
1939                                             (caddr_t
)cp
, NULL
, &cred
); 
1942                                             (struct ifma_msghdr2 
*)(void *)cp
; 
1943                                         ifmam
->ifmam_addrs 
= info
.rti_addrs
; 
1944                                         ifmam
->ifmam_flags 
= 0; 
1945                                         ifmam
->ifmam_index 
= 
1946                                             ifma
->ifma_ifp
->if_index
; 
1947                                         ifmam
->ifmam_refcount 
= 
1951                                         VERIFY(IS_P2ALIGNED(cp
, 
1952                                             sizeof (u_int32_t
))); 
1957                         ifnet_lock_done(ifp
); 
1958                         info
.rti_info
[RTAX_IFA
] = info
.rti_info
[RTAX_NETMASK
] = 
1959                             info
.rti_info
[RTAX_BRD
] = NULL
; 
1964                         if (error 
== ENOBUFS
) 
1965                                 printf("%s: current_len (%d) + len (%d) > " 
1966                                     "total_len (%d)\n", __func__
, current_len
, 
1972                         /* Better to return zero length buffer than ENOBUFS */ 
1975                         total_len 
+= total_len 
>> 3; 
1976                         total_buffer 
= _MALLOC(total_len
, M_RTABLE
, 
1978                         if (total_buffer 
== NULL
) { 
1979                                 printf("%s: _MALLOC(%d) failed\n", __func__
, 
1985                         VERIFY(IS_P2ALIGNED(cp
, sizeof (u_int32_t
))); 
1987                         error 
= SYSCTL_OUT(w
->w_req
, total_buffer
, current_len
); 
1993         if (total_buffer 
!= NULL
) 
1994                 _FREE(total_buffer
, M_RTABLE
); 
1996         kauth_cred_unref(&cred
); 
2002 sysctl_rtstat(struct sysctl_req 
*req
) 
2004         return (SYSCTL_OUT(req
, &rtstat
, sizeof (struct rtstat
))); 
2008 sysctl_rttrash(struct sysctl_req 
*req
) 
2010         return (SYSCTL_OUT(req
, &rttrash
, sizeof (rttrash
))); 
2014 sysctl_rtsock SYSCTL_HANDLER_ARGS
 
2016 #pragma unused(oidp) 
2017         int     *name 
= (int *)arg1
; 
2018         u_int   namelen 
= arg2
; 
2019         struct radix_node_head 
*rnh
; 
2020         int     i
, error 
= EINVAL
; 
2031         Bzero(&w
, sizeof (w
)); 
2041                 lck_mtx_lock(rnh_lock
); 
2042                 for (i 
= 1; i 
<= AF_MAX
; i
++) 
2043                         if ((rnh 
= rt_tables
[i
]) && (af 
== 0 || af 
== i
) && 
2044                             (error 
= rnh
->rnh_walktree(rnh
, 
2045                             sysctl_dumpentry
, &w
))) 
2047                 lck_mtx_unlock(rnh_lock
); 
2050         case NET_RT_DUMPX_FLAGS
: 
2051                 lck_mtx_lock(rnh_lock
); 
2052                 for (i 
= 1; i 
<= AF_MAX
; i
++) 
2053                         if ((rnh 
= rt_tables
[i
]) && (af 
== 0 || af 
== i
) && 
2054                             (error 
= rnh
->rnh_walktree(rnh
, 
2055                             sysctl_dumpentry_ext
, &w
))) 
2057                 lck_mtx_unlock(rnh_lock
); 
2060                 error 
= sysctl_iflist(af
, &w
); 
2062         case NET_RT_IFLIST2
: 
2063                 error 
= sysctl_iflist2(af
, &w
); 
2066                 error 
= sysctl_rtstat(req
); 
2069                 error 
= sysctl_rttrash(req
); 
2072         if (w
.w_tmem 
!= NULL
) 
2073                 FREE(w
.w_tmem
, M_RTABLE
); 
2078  * Definitions of protocols supported in the ROUTE domain. 
2080 static struct protosw routesw
[] = { 
2082         .pr_type 
=              SOCK_RAW
, 
2084         .pr_flags 
=             PR_ATOMIC
|PR_ADDR
, 
2085         .pr_output 
=            route_output
, 
2086         .pr_ctlinput 
=          raw_ctlinput
, 
2087         .pr_init 
=              raw_init
, 
2088         .pr_usrreqs 
=           &route_usrreqs
, 
2092 static int route_proto_count 
= (sizeof (routesw
) / sizeof (struct protosw
)); 
2094 struct domain routedomain_s 
= { 
2095         .dom_family 
=           PF_ROUTE
, 
2096         .dom_name 
=             "route", 
2097         .dom_init 
=             route_dinit
, 
2101 route_dinit(struct domain 
*dp
) 
2106         VERIFY(!(dp
->dom_flags 
& DOM_INITIALIZED
)); 
2107         VERIFY(routedomain 
== NULL
); 
2111         for (i 
= 0, pr 
= &routesw
[0]; i 
< route_proto_count
; i
++, pr
++) 
2112                 net_add_proto(pr
, dp
, 1);