2  * Copyright (c) 2003-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 #include <sys/kpi_socketfilter.h> 
  31 #include <sys/socket.h> 
  32 #include <sys/param.h> 
  33 #include <sys/errno.h> 
  34 #include <sys/malloc.h> 
  35 #include <sys/protosw.h> 
  36 #include <sys/domain.h> 
  38 #include <kern/locks.h> 
  39 #include <kern/thread.h> 
  40 #include <kern/debug.h> 
  41 #include <net/kext_net.h> 
  43 #include <net/net_api_stats.h> 
  44 #include <netinet/in_var.h> 
  45 #include <netinet/ip.h> 
  46 #include <netinet/ip_var.h> 
  47 #include <netinet/tcp.h> 
  48 #include <netinet/tcp_var.h> 
  49 #include <netinet/udp.h> 
  50 #include <netinet/udp_var.h> 
  52 #include <libkern/libkern.h> 
  53 #include <libkern/OSAtomic.h> 
  54 #include <os/refcnt.h> 
  59 #define SFEF_ATTACHED           0x1     /* SFE is on socket list */ 
  60 #define SFEF_NODETACH           0x2     /* Detach should not be called */ 
  61 #define SFEF_NOSOCKET           0x4     /* Socket is gone */ 
  64  * If you need accounting for KM_IFADDR consider using 
  65  * KALLOC_HEAP_DEFINE to define a view. 
  67 #define KM_IFADDR       KHEAP_DEFAULT 
  69 struct socket_filter_entry 
{ 
  70         struct socket_filter_entry      
*sfe_next_onsocket
; 
  71         struct socket_filter_entry      
*sfe_next_onfilter
; 
  72         struct socket_filter_entry      
*sfe_next_oncleanup
; 
  74         struct socket_filter            
*sfe_filter
; 
  75         struct socket                   
*sfe_socket
; 
  82 struct socket_filter 
{ 
  83         TAILQ_ENTRY(socket_filter
)      sf_protosw_next
; 
  84         TAILQ_ENTRY(socket_filter
)      sf_global_next
; 
  85         struct socket_filter_entry      
*sf_entry_head
; 
  87         struct protosw                  
*sf_proto
; 
  88         struct sflt_filter              sf_filter
; 
  89         struct os_refcnt                sf_refcount
; 
  92 TAILQ_HEAD(socket_filter_list
, socket_filter
); 
  94 static LCK_GRP_DECLARE(sock_filter_lock_grp
, "socket filter lock"); 
  95 static LCK_RW_DECLARE(sock_filter_lock
, &sock_filter_lock_grp
); 
  96 static LCK_MTX_DECLARE(sock_filter_cleanup_lock
, &sock_filter_lock_grp
); 
  98 static struct socket_filter_list        sock_filter_head 
= 
  99     TAILQ_HEAD_INITIALIZER(sock_filter_head
); 
 100 static struct socket_filter_entry       
*sock_filter_cleanup_entries 
= NULL
; 
 101 static thread_t                         sock_filter_cleanup_thread 
= NULL
; 
 103 static void sflt_cleanup_thread(void *, wait_result_t
); 
 104 static void sflt_detach_locked(struct socket_filter_entry 
*entry
); 
 107 static errno_t 
sflt_register_common(const struct sflt_filter 
*filter
, int domain
, 
 108     int type
, int protocol
, bool is_internal
); 
 109 errno_t 
sflt_register(const struct sflt_filter 
*filter
, int domain
, 
 110     int type
, int protocol
); 
 113 #pragma mark -- Internal State Management -- 
 115 __private_extern__ 
int 
 116 sflt_permission_check(struct inpcb 
*inp
) 
 118         /* Only IPv4 or IPv6 sockets can bypass filters */ 
 119         if (!(inp
->inp_vflag 
& INP_IPV4
) && 
 120             !(inp
->inp_vflag 
& INP_IPV6
)) { 
 123         /* Sockets that have this entitlement bypass socket filters. */ 
 124         if (INP_INTCOPROC_ALLOWED(inp
)) { 
 127         /* Sockets bound to an intcoproc interface bypass socket filters. */ 
 128         if ((inp
->inp_flags 
& INP_BOUND_IF
) && 
 129             IFNET_IS_INTCOPROC(inp
->inp_boundifp
)) { 
 134          * Make sure that the NECP policy is populated. 
 135          * If result is not populated, the policy ID will be 
 136          * NECP_KERNEL_POLICY_ID_NONE. Note that if the result 
 137          * is populated, but there was no match, it will be 
 138          * NECP_KERNEL_POLICY_ID_NO_MATCH. 
 139          * Do not call inp_update_necp_policy() to avoid scoping 
 140          * a socket prior to calls to bind(). 
 142         if (inp
->inp_policyresult
.policy_id 
== NECP_KERNEL_POLICY_ID_NONE
) { 
 143                 necp_socket_find_policy_match(inp
, NULL
, NULL
, 0); 
 146         /* If the filter unit is marked to be "no filter", bypass filters */ 
 147         if (inp
->inp_policyresult
.results
.filter_control_unit 
== 
 148             NECP_FILTER_UNIT_NO_FILTER
) { 
 156 sflt_retain_locked(struct socket_filter 
*filter
) 
 158         os_ref_retain_locked(&filter
->sf_refcount
); 
 162 sflt_release_locked(struct socket_filter 
*filter
) 
 164         if (os_ref_release_locked(&filter
->sf_refcount
) == 0) { 
 165                 /* Call the unregistered function */ 
 166                 if (filter
->sf_filter
.sf_unregistered
) { 
 167                         lck_rw_unlock_exclusive(&sock_filter_lock
); 
 168                         filter
->sf_filter
.sf_unregistered( 
 169                                 filter
->sf_filter
.sf_handle
); 
 170                         lck_rw_lock_exclusive(&sock_filter_lock
); 
 174                 kheap_free(KM_IFADDR
, filter
, sizeof(struct socket_filter
)); 
 179 sflt_entry_retain(struct socket_filter_entry 
*entry
) 
 181         if (OSIncrementAtomic(&entry
->sfe_refcount
) <= 0) { 
 182                 panic("sflt_entry_retain - sfe_refcount <= 0\n"); 
 188 sflt_entry_release(struct socket_filter_entry 
*entry
) 
 190         SInt32 old 
= OSDecrementAtomic(&entry
->sfe_refcount
); 
 192                 /* That was the last reference */ 
 194                 /* Take the cleanup lock */ 
 195                 lck_mtx_lock(&sock_filter_cleanup_lock
); 
 197                 /* Put this item on the cleanup list */ 
 198                 entry
->sfe_next_oncleanup 
= sock_filter_cleanup_entries
; 
 199                 sock_filter_cleanup_entries 
= entry
; 
 201                 /* If the item is the first item in the list */ 
 202                 if (entry
->sfe_next_oncleanup 
== NULL
) { 
 203                         if (sock_filter_cleanup_thread 
== NULL
) { 
 204                                 /* Create a thread */ 
 205                                 kernel_thread_start(sflt_cleanup_thread
, 
 206                                     NULL
, &sock_filter_cleanup_thread
); 
 208                                 /* Wakeup the thread */ 
 209                                 wakeup(&sock_filter_cleanup_entries
); 
 213                 /* Drop the cleanup lock */ 
 214                 lck_mtx_unlock(&sock_filter_cleanup_lock
); 
 215         } else if (old 
<= 0) { 
 216                 panic("sflt_entry_release - sfe_refcount (%d) <= 0\n", 
 222 __attribute__((noreturn
)) 
 224 sflt_cleanup_thread(void *blah
, wait_result_t blah2
) 
 226 #pragma unused(blah, blah2) 
 228                 lck_mtx_lock(&sock_filter_cleanup_lock
); 
 229                 while (sock_filter_cleanup_entries 
== NULL
) { 
 230                         /* Sleep until we've got something better to do */ 
 231                         msleep(&sock_filter_cleanup_entries
, 
 232                             &sock_filter_cleanup_lock
, PWAIT
, 
 233                             "sflt_cleanup", NULL
); 
 236                 /* Pull the current list of dead items */ 
 237                 struct socket_filter_entry 
*dead 
= sock_filter_cleanup_entries
; 
 238                 sock_filter_cleanup_entries 
= NULL
; 
 241                 lck_mtx_unlock(&sock_filter_cleanup_lock
); 
 243                 /* Take the socket filter lock */ 
 244                 lck_rw_lock_exclusive(&sock_filter_lock
); 
 246                 /* Cleanup every dead item */ 
 247                 struct socket_filter_entry      
*entry
; 
 248                 for (entry 
= dead
; entry
; entry 
= dead
) { 
 249                         struct socket_filter_entry      
**nextpp
; 
 251                         dead 
= entry
->sfe_next_oncleanup
; 
 253                         /* Call detach function if necessary - drop the lock */ 
 254                         if ((entry
->sfe_flags 
& SFEF_NODETACH
) == 0 && 
 255                             entry
->sfe_filter
->sf_filter
.sf_detach
) { 
 256                                 entry
->sfe_flags 
|= SFEF_NODETACH
; 
 257                                 lck_rw_unlock_exclusive(&sock_filter_lock
); 
 260                                  * Warning - passing a potentially 
 261                                  * dead socket may be bad 
 263                                 entry
->sfe_filter
->sf_filter
.sf_detach( 
 264                                         entry
->sfe_cookie
, entry
->sfe_socket
); 
 266                                 lck_rw_lock_exclusive(&sock_filter_lock
); 
 270                          * Pull entry off the socket list -- 
 271                          * if the socket still exists 
 273                         if ((entry
->sfe_flags 
& SFEF_NOSOCKET
) == 0) { 
 274                                 for (nextpp 
= &entry
->sfe_socket
->so_filt
; 
 276                                     nextpp 
= &(*nextpp
)->sfe_next_onsocket
) { 
 277                                         if (*nextpp 
== entry
) { 
 279                                                     entry
->sfe_next_onsocket
; 
 285                         /* Pull entry off the filter list */ 
 286                         for (nextpp 
= &entry
->sfe_filter
->sf_entry_head
; 
 287                             *nextpp
; nextpp 
= &(*nextpp
)->sfe_next_onfilter
) { 
 288                                 if (*nextpp 
== entry
) { 
 289                                         *nextpp 
= entry
->sfe_next_onfilter
; 
 295                          * Release the filter -- may drop lock, but that's okay 
 297                         sflt_release_locked(entry
->sfe_filter
); 
 298                         entry
->sfe_socket 
= NULL
; 
 299                         entry
->sfe_filter 
= NULL
; 
 300                         kheap_free(KM_IFADDR
, entry
, sizeof(struct socket_filter_entry
)); 
 303                 /* Drop the socket filter lock */ 
 304                 lck_rw_unlock_exclusive(&sock_filter_lock
); 
 310 sflt_attach_locked(struct socket 
*so
, struct socket_filter 
*filter
, 
 314         struct socket_filter_entry 
*entry 
= NULL
; 
 316         if (sflt_permission_check(sotoinpcb(so
))) { 
 320         if (filter 
== NULL
) { 
 324         for (entry 
= so
->so_filt
; entry
; entry 
= entry
->sfe_next_onfilter
) { 
 325                 if (entry
->sfe_filter
->sf_filter
.sf_handle 
== 
 326                     filter
->sf_filter
.sf_handle
) { 
 330         /* allocate the socket filter entry */ 
 331         entry 
= kheap_alloc(KM_IFADDR
, sizeof(struct socket_filter_entry
), 
 337         /* Initialize the socket filter entry */ 
 338         entry
->sfe_cookie 
= NULL
; 
 339         entry
->sfe_flags 
= SFEF_ATTACHED
; 
 340         entry
->sfe_refcount 
= 1; /* corresponds to SFEF_ATTACHED flag set */ 
 342         /* Put the entry in the filter list */ 
 343         sflt_retain_locked(filter
); 
 344         entry
->sfe_filter 
= filter
; 
 345         entry
->sfe_next_onfilter 
= filter
->sf_entry_head
; 
 346         filter
->sf_entry_head 
= entry
; 
 348         /* Put the entry on the socket filter list */ 
 349         entry
->sfe_socket 
= so
; 
 350         entry
->sfe_next_onsocket 
= so
->so_filt
; 
 353         if (entry
->sfe_filter
->sf_filter
.sf_attach
) { 
 354                 /* Retain the entry while we call attach */ 
 355                 sflt_entry_retain(entry
); 
 358                  * Release the filter lock -- 
 359                  * callers must be aware we will do this 
 361                 lck_rw_unlock_exclusive(&sock_filter_lock
); 
 363                 /* Unlock the socket */ 
 365                         socket_unlock(so
, 0); 
 368                 /* It's finally safe to call the filter function */ 
 369                 error 
= entry
->sfe_filter
->sf_filter
.sf_attach( 
 370                         &entry
->sfe_cookie
, so
); 
 372                 /* Lock the socket again */ 
 377                 /* Lock the filters again */ 
 378                 lck_rw_lock_exclusive(&sock_filter_lock
); 
 381                  * If the attach function returns an error, 
 382                  * this filter must be detached 
 385                         /* don't call sf_detach */ 
 386                         entry
->sfe_flags 
|= SFEF_NODETACH
; 
 387                         sflt_detach_locked(entry
); 
 390                 /* Release the retain we held through the attach call */ 
 391                 sflt_entry_release(entry
); 
 398 sflt_attach_internal(socket_t socket
, sflt_handle handle
) 
 400         if (socket 
== NULL 
|| handle 
== 0) { 
 406         lck_rw_lock_exclusive(&sock_filter_lock
); 
 408         struct socket_filter 
*filter 
= NULL
; 
 409         TAILQ_FOREACH(filter
, &sock_filter_head
, sf_global_next
) { 
 410                 if (filter
->sf_filter
.sf_handle 
== handle
) { 
 416                 result 
= sflt_attach_locked(socket
, filter
, 1); 
 419         lck_rw_unlock_exclusive(&sock_filter_lock
); 
 425 sflt_detach_locked(struct socket_filter_entry 
*entry
) 
 427         if ((entry
->sfe_flags 
& SFEF_ATTACHED
) != 0) { 
 428                 entry
->sfe_flags 
&= ~SFEF_ATTACHED
; 
 429                 sflt_entry_release(entry
); 
 433 #pragma mark -- Socket Layer Hooks -- 
 435 __private_extern__ 
void 
 436 sflt_initsock(struct socket 
*so
) 
 439          * Point to the real protosw, as so_proto might have been 
 440          * pointed to a modified version. 
 442         struct protosw 
*proto 
= so
->so_proto
->pr_protosw
; 
 444         lck_rw_lock_shared(&sock_filter_lock
); 
 445         if (TAILQ_FIRST(&proto
->pr_filter_head
) != NULL
) { 
 446                 /* Promote lock to exclusive */ 
 447                 if (!lck_rw_lock_shared_to_exclusive(&sock_filter_lock
)) { 
 448                         lck_rw_lock_exclusive(&sock_filter_lock
); 
 452                  * Warning: A filter unregistering will be pulled out of 
 453                  * the list.  This could happen while we drop the lock in 
 454                  * sftl_attach_locked or sflt_release_locked.  For this 
 455                  * reason we retain a reference on the filter (or next_filter) 
 456                  * while calling this function.  This protects us from a panic, 
 457                  * but it could result in a socket being created without all 
 458                  * of the global filters if we're attaching a filter as it 
 459                  * is removed, if that's possible. 
 461                 struct socket_filter 
*filter 
= 
 462                     TAILQ_FIRST(&proto
->pr_filter_head
); 
 464                 sflt_retain_locked(filter
); 
 467                         struct socket_filter 
*filter_next
; 
 469                          * Warning: sflt_attach_private_locked 
 472                         sflt_attach_locked(so
, filter
, 0); 
 474                         filter_next 
= TAILQ_NEXT(filter
, sf_protosw_next
); 
 476                                 sflt_retain_locked(filter_next
); 
 480                          * Warning: filt_release_locked may remove 
 481                          * the filter from the queue 
 483                         sflt_release_locked(filter
); 
 484                         filter 
= filter_next
; 
 487         lck_rw_done(&sock_filter_lock
); 
 493  * Detaches all filters from the socket. 
 495 __private_extern__ 
void 
 496 sflt_termsock(struct socket 
*so
) 
 498         lck_rw_lock_exclusive(&sock_filter_lock
); 
 500         struct socket_filter_entry 
*entry
; 
 502         while ((entry 
= so
->so_filt
) != NULL
) { 
 503                 /* Pull filter off the socket */ 
 504                 so
->so_filt 
= entry
->sfe_next_onsocket
; 
 505                 entry
->sfe_flags 
|= SFEF_NOSOCKET
; 
 508                 sflt_detach_locked(entry
); 
 511                  * On sflt_termsock, we can't return until the detach function 
 512                  * has been called.  Call the detach function - this is gross 
 513                  * because the socket filter entry could be freed when we drop 
 514                  * the lock, so we make copies on  the stack and retain 
 515                  * everything we need before dropping the lock. 
 517                 if ((entry
->sfe_flags 
& SFEF_NODETACH
) == 0 && 
 518                     entry
->sfe_filter
->sf_filter
.sf_detach
) { 
 519                         void *sfe_cookie 
= entry
->sfe_cookie
; 
 520                         struct socket_filter 
*sfe_filter 
= entry
->sfe_filter
; 
 522                         /* Retain the socket filter */ 
 523                         sflt_retain_locked(sfe_filter
); 
 525                         /* Mark that we've called the detach function */ 
 526                         entry
->sfe_flags 
|= SFEF_NODETACH
; 
 528                         /* Drop the lock before calling the detach function */ 
 529                         lck_rw_unlock_exclusive(&sock_filter_lock
); 
 530                         sfe_filter
->sf_filter
.sf_detach(sfe_cookie
, so
); 
 531                         lck_rw_lock_exclusive(&sock_filter_lock
); 
 533                         /* Release the filter */ 
 534                         sflt_release_locked(sfe_filter
); 
 538         lck_rw_unlock_exclusive(&sock_filter_lock
); 
 543 sflt_notify_internal(struct socket 
*so
, sflt_event_t event
, void *param
, 
 546         if (so
->so_filt 
== NULL
) { 
 550         struct socket_filter_entry 
*entry
; 
 553         lck_rw_lock_shared(&sock_filter_lock
); 
 554         for (entry 
= so
->so_filt
; entry
; entry 
= entry
->sfe_next_onsocket
) { 
 555                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 556                     entry
->sfe_filter
->sf_filter
.sf_notify 
&& 
 557                     ((handle 
&& entry
->sfe_filter
->sf_filter
.sf_handle 
!= 
 558                     handle
) || !handle
)) { 
 560                          * Retain the filter entry and release 
 561                          * the socket filter lock 
 563                         sflt_entry_retain(entry
); 
 564                         lck_rw_unlock_shared(&sock_filter_lock
); 
 566                         /* If the socket isn't already unlocked, unlock it */ 
 569                                 socket_unlock(so
, 0); 
 572                         /* Finally call the filter */ 
 573                         entry
->sfe_filter
->sf_filter
.sf_notify( 
 574                                 entry
->sfe_cookie
, so
, event
, param
); 
 577                          * Take the socket filter lock again 
 578                          * and release the entry 
 580                         lck_rw_lock_shared(&sock_filter_lock
); 
 581                         sflt_entry_release(entry
); 
 584         lck_rw_unlock_shared(&sock_filter_lock
); 
 591 __private_extern__ 
void 
 592 sflt_notify(struct socket 
*so
, sflt_event_t event
, void  *param
) 
 594         sflt_notify_internal(so
, event
, param
, 0); 
 598 sflt_notify_after_register(struct socket 
*so
, sflt_event_t event
, 
 601         sflt_notify_internal(so
, event
, NULL
, handle
); 
 604 __private_extern__ 
int 
 605 sflt_ioctl(struct socket 
*so
, u_long cmd
, caddr_t data
) 
 607         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
 611         struct socket_filter_entry 
*entry
; 
 615         lck_rw_lock_shared(&sock_filter_lock
); 
 616         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
 617             entry 
= entry
->sfe_next_onsocket
) { 
 618                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 619                     entry
->sfe_filter
->sf_filter
.sf_ioctl
) { 
 621                          * Retain the filter entry and release 
 622                          * the socket filter lock 
 624                         sflt_entry_retain(entry
); 
 625                         lck_rw_unlock_shared(&sock_filter_lock
); 
 627                         /* If the socket isn't already unlocked, unlock it */ 
 629                                 socket_unlock(so
, 0); 
 633                         /* Call the filter */ 
 634                         error 
= entry
->sfe_filter
->sf_filter
.sf_ioctl( 
 635                                 entry
->sfe_cookie
, so
, cmd
, data
); 
 638                          * Take the socket filter lock again 
 639                          * and release the entry 
 641                         lck_rw_lock_shared(&sock_filter_lock
); 
 642                         sflt_entry_release(entry
); 
 645         lck_rw_unlock_shared(&sock_filter_lock
); 
 654 __private_extern__ 
int 
 655 sflt_bind(struct socket 
*so
, const struct sockaddr 
*nam
) 
 657         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
 661         struct socket_filter_entry 
*entry
; 
 665         lck_rw_lock_shared(&sock_filter_lock
); 
 666         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
 667             entry 
= entry
->sfe_next_onsocket
) { 
 668                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 669                     entry
->sfe_filter
->sf_filter
.sf_bind
) { 
 671                          * Retain the filter entry and 
 672                          * release the socket filter lock 
 674                         sflt_entry_retain(entry
); 
 675                         lck_rw_unlock_shared(&sock_filter_lock
); 
 677                         /* If the socket isn't already unlocked, unlock it */ 
 679                                 socket_unlock(so
, 0); 
 683                         /* Call the filter */ 
 684                         error 
= entry
->sfe_filter
->sf_filter
.sf_bind( 
 685                                 entry
->sfe_cookie
, so
, nam
); 
 688                          * Take the socket filter lock again and 
 691                         lck_rw_lock_shared(&sock_filter_lock
); 
 692                         sflt_entry_release(entry
); 
 695         lck_rw_unlock_shared(&sock_filter_lock
); 
 704 __private_extern__ 
int 
 705 sflt_listen(struct socket 
*so
) 
 707         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
 711         struct socket_filter_entry 
*entry
; 
 715         lck_rw_lock_shared(&sock_filter_lock
); 
 716         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
 717             entry 
= entry
->sfe_next_onsocket
) { 
 718                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 719                     entry
->sfe_filter
->sf_filter
.sf_listen
) { 
 721                          * Retain the filter entry and release 
 722                          * the socket filter lock 
 724                         sflt_entry_retain(entry
); 
 725                         lck_rw_unlock_shared(&sock_filter_lock
); 
 727                         /* If the socket isn't already unlocked, unlock it */ 
 729                                 socket_unlock(so
, 0); 
 733                         /* Call the filter */ 
 734                         error 
= entry
->sfe_filter
->sf_filter
.sf_listen( 
 735                                 entry
->sfe_cookie
, so
); 
 738                          * Take the socket filter lock again 
 739                          * and release the entry 
 741                         lck_rw_lock_shared(&sock_filter_lock
); 
 742                         sflt_entry_release(entry
); 
 745         lck_rw_unlock_shared(&sock_filter_lock
); 
 754 __private_extern__ 
int 
 755 sflt_accept(struct socket 
*head
, struct socket 
*so
, 
 756     const struct sockaddr 
*local
, const struct sockaddr 
*remote
) 
 758         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
 762         struct socket_filter_entry 
*entry
; 
 766         lck_rw_lock_shared(&sock_filter_lock
); 
 767         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
 768             entry 
= entry
->sfe_next_onsocket
) { 
 769                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 770                     entry
->sfe_filter
->sf_filter
.sf_accept
) { 
 772                          * Retain the filter entry and 
 773                          * release the socket filter lock 
 775                         sflt_entry_retain(entry
); 
 776                         lck_rw_unlock_shared(&sock_filter_lock
); 
 778                         /* If the socket isn't already unlocked, unlock it */ 
 780                                 socket_unlock(so
, 0); 
 784                         /* Call the filter */ 
 785                         error 
= entry
->sfe_filter
->sf_filter
.sf_accept( 
 786                                 entry
->sfe_cookie
, head
, so
, local
, remote
); 
 789                          * Take the socket filter lock again 
 790                          * and release the entry 
 792                         lck_rw_lock_shared(&sock_filter_lock
); 
 793                         sflt_entry_release(entry
); 
 796         lck_rw_unlock_shared(&sock_filter_lock
); 
 805 __private_extern__ 
int 
 806 sflt_getsockname(struct socket 
*so
, struct sockaddr 
**local
) 
 808         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
 812         struct socket_filter_entry 
*entry
; 
 816         lck_rw_lock_shared(&sock_filter_lock
); 
 817         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
 818             entry 
= entry
->sfe_next_onsocket
) { 
 819                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 820                     entry
->sfe_filter
->sf_filter
.sf_getsockname
) { 
 822                          * Retain the filter entry and 
 823                          * release the socket filter lock 
 825                         sflt_entry_retain(entry
); 
 826                         lck_rw_unlock_shared(&sock_filter_lock
); 
 828                         /* If the socket isn't already unlocked, unlock it */ 
 830                                 socket_unlock(so
, 0); 
 834                         /* Call the filter */ 
 835                         error 
= entry
->sfe_filter
->sf_filter
.sf_getsockname( 
 836                                 entry
->sfe_cookie
, so
, local
); 
 839                          * Take the socket filter lock again 
 840                          * and release the entry 
 842                         lck_rw_lock_shared(&sock_filter_lock
); 
 843                         sflt_entry_release(entry
); 
 846         lck_rw_unlock_shared(&sock_filter_lock
); 
 855 __private_extern__ 
int 
 856 sflt_getpeername(struct socket 
*so
, struct sockaddr 
**remote
) 
 858         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
 862         struct socket_filter_entry 
*entry
; 
 866         lck_rw_lock_shared(&sock_filter_lock
); 
 867         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
 868             entry 
= entry
->sfe_next_onsocket
) { 
 869                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 870                     entry
->sfe_filter
->sf_filter
.sf_getpeername
) { 
 872                          * Retain the filter entry and release 
 873                          * the socket filter lock 
 875                         sflt_entry_retain(entry
); 
 876                         lck_rw_unlock_shared(&sock_filter_lock
); 
 878                         /* If the socket isn't already unlocked, unlock it */ 
 880                                 socket_unlock(so
, 0); 
 884                         /* Call the filter */ 
 885                         error 
= entry
->sfe_filter
->sf_filter
.sf_getpeername( 
 886                                 entry
->sfe_cookie
, so
, remote
); 
 889                          * Take the socket filter lock again 
 890                          * and release the entry 
 892                         lck_rw_lock_shared(&sock_filter_lock
); 
 893                         sflt_entry_release(entry
); 
 896         lck_rw_unlock_shared(&sock_filter_lock
); 
 905 __private_extern__ 
int 
 906 sflt_connectin(struct socket 
*so
, const struct sockaddr 
*remote
) 
 908         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
 912         struct socket_filter_entry 
*entry
; 
 916         lck_rw_lock_shared(&sock_filter_lock
); 
 917         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
 918             entry 
= entry
->sfe_next_onsocket
) { 
 919                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 920                     entry
->sfe_filter
->sf_filter
.sf_connect_in
) { 
 922                          * Retain the filter entry and release 
 923                          * the socket filter lock 
 925                         sflt_entry_retain(entry
); 
 926                         lck_rw_unlock_shared(&sock_filter_lock
); 
 928                         /* If the socket isn't already unlocked, unlock it */ 
 930                                 socket_unlock(so
, 0); 
 934                         /* Call the filter */ 
 935                         error 
= entry
->sfe_filter
->sf_filter
.sf_connect_in( 
 936                                 entry
->sfe_cookie
, so
, remote
); 
 939                          * Take the socket filter lock again 
 940                          * and release the entry 
 942                         lck_rw_lock_shared(&sock_filter_lock
); 
 943                         sflt_entry_release(entry
); 
 946         lck_rw_unlock_shared(&sock_filter_lock
); 
 956 sflt_connectout_common(struct socket 
*so
, const struct sockaddr 
*nam
) 
 958         struct socket_filter_entry 
*entry
; 
 962         lck_rw_lock_shared(&sock_filter_lock
); 
 963         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
 964             entry 
= entry
->sfe_next_onsocket
) { 
 965                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
 966                     entry
->sfe_filter
->sf_filter
.sf_connect_out
) { 
 968                          * Retain the filter entry and release 
 969                          * the socket filter lock 
 971                         sflt_entry_retain(entry
); 
 972                         lck_rw_unlock_shared(&sock_filter_lock
); 
 974                         /* If the socket isn't already unlocked, unlock it */ 
 976                                 socket_unlock(so
, 0); 
 980                         /* Call the filter */ 
 981                         error 
= entry
->sfe_filter
->sf_filter
.sf_connect_out( 
 982                                 entry
->sfe_cookie
, so
, nam
); 
 985                          * Take the socket filter lock again 
 986                          * and release the entry 
 988                         lck_rw_lock_shared(&sock_filter_lock
); 
 989                         sflt_entry_release(entry
); 
 992         lck_rw_unlock_shared(&sock_filter_lock
); 
1001 __private_extern__ 
int 
1002 sflt_connectout(struct socket 
*so
, const struct sockaddr 
*nam
) 
1004         char buf
[SOCK_MAXADDRLEN
]; 
1005         struct sockaddr 
*sa
; 
1008         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
1013          * Workaround for rdar://23362120 
1014          * Always pass a buffer that can hold an IPv6 socket address 
1016         bzero(buf
, sizeof(buf
)); 
1017         bcopy(nam
, buf
, nam
->sa_len
); 
1018         sa 
= (struct sockaddr 
*)buf
; 
1020         error 
= sflt_connectout_common(so
, sa
); 
1026          * If the address was modified, copy it back 
1028         if (bcmp(sa
, nam
, nam
->sa_len
) != 0) { 
1029                 bcopy(sa
, (struct sockaddr 
*)(uintptr_t)nam
, nam
->sa_len
); 
1035 __private_extern__ 
int 
1036 sflt_setsockopt(struct socket 
*so
, struct sockopt 
*sopt
) 
1038         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
1042         struct socket_filter_entry 
*entry
; 
1046         lck_rw_lock_shared(&sock_filter_lock
); 
1047         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
1048             entry 
= entry
->sfe_next_onsocket
) { 
1049                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
1050                     entry
->sfe_filter
->sf_filter
.sf_setoption
) { 
1052                          * Retain the filter entry and release 
1053                          * the socket filter lock 
1055                         sflt_entry_retain(entry
); 
1056                         lck_rw_unlock_shared(&sock_filter_lock
); 
1058                         /* If the socket isn't already unlocked, unlock it */ 
1059                         if (unlocked 
== 0) { 
1060                                 socket_unlock(so
, 0); 
1064                         /* Call the filter */ 
1065                         error 
= entry
->sfe_filter
->sf_filter
.sf_setoption( 
1066                                 entry
->sfe_cookie
, so
, sopt
); 
1069                          * Take the socket filter lock again 
1070                          * and release the entry 
1072                         lck_rw_lock_shared(&sock_filter_lock
); 
1073                         sflt_entry_release(entry
); 
1076         lck_rw_unlock_shared(&sock_filter_lock
); 
1085 __private_extern__ 
int 
1086 sflt_getsockopt(struct socket 
*so
, struct sockopt 
*sopt
) 
1088         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
1092         struct socket_filter_entry 
*entry
; 
1096         lck_rw_lock_shared(&sock_filter_lock
); 
1097         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
1098             entry 
= entry
->sfe_next_onsocket
) { 
1099                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
1100                     entry
->sfe_filter
->sf_filter
.sf_getoption
) { 
1102                          * Retain the filter entry and release 
1103                          * the socket filter lock 
1105                         sflt_entry_retain(entry
); 
1106                         lck_rw_unlock_shared(&sock_filter_lock
); 
1108                         /* If the socket isn't already unlocked, unlock it */ 
1109                         if (unlocked 
== 0) { 
1110                                 socket_unlock(so
, 0); 
1114                         /* Call the filter */ 
1115                         error 
= entry
->sfe_filter
->sf_filter
.sf_getoption( 
1116                                 entry
->sfe_cookie
, so
, sopt
); 
1119                          * Take the socket filter lock again 
1120                          * and release the entry 
1122                         lck_rw_lock_shared(&sock_filter_lock
); 
1123                         sflt_entry_release(entry
); 
1126         lck_rw_unlock_shared(&sock_filter_lock
); 
1135 __private_extern__ 
int 
1136 sflt_data_out(struct socket 
*so
, const struct sockaddr 
*to
, mbuf_t 
*data
, 
1137     mbuf_t 
*control
, sflt_data_flag_t flags
) 
1139         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
1143         struct socket_filter_entry 
*entry
; 
1145         int setsendthread 
= 0; 
1148         lck_rw_lock_shared(&sock_filter_lock
); 
1149         for (entry 
= so
->so_filt
; entry 
&& error 
== 0; 
1150             entry 
= entry
->sfe_next_onsocket
) { 
1151                 /* skip if this is a subflow socket */ 
1152                 if (so
->so_flags 
& SOF_MP_SUBFLOW
) { 
1155                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
1156                     entry
->sfe_filter
->sf_filter
.sf_data_out
) { 
1158                          * Retain the filter entry and 
1159                          * release the socket filter lock 
1161                         sflt_entry_retain(entry
); 
1162                         lck_rw_unlock_shared(&sock_filter_lock
); 
1164                         /* If the socket isn't already unlocked, unlock it */ 
1165                         if (unlocked 
== 0) { 
1166                                 if (so
->so_send_filt_thread 
== NULL
) { 
1168                                         so
->so_send_filt_thread 
= 
1171                                 socket_unlock(so
, 0); 
1175                         /* Call the filter */ 
1176                         error 
= entry
->sfe_filter
->sf_filter
.sf_data_out( 
1177                                 entry
->sfe_cookie
, so
, to
, data
, control
, flags
); 
1180                          * Take the socket filter lock again 
1181                          * and release the entry 
1183                         lck_rw_lock_shared(&sock_filter_lock
); 
1184                         sflt_entry_release(entry
); 
1187         lck_rw_unlock_shared(&sock_filter_lock
); 
1191                 if (setsendthread
) { 
1192                         so
->so_send_filt_thread 
= NULL
; 
1199 __private_extern__ 
int 
1200 sflt_data_in(struct socket 
*so
, const struct sockaddr 
*from
, mbuf_t 
*data
, 
1201     mbuf_t 
*control
, sflt_data_flag_t flags
) 
1203         if (so
->so_filt 
== NULL 
|| sflt_permission_check(sotoinpcb(so
))) { 
1207         struct socket_filter_entry 
*entry
; 
1211         lck_rw_lock_shared(&sock_filter_lock
); 
1213         for (entry 
= so
->so_filt
; entry 
&& (error 
== 0); 
1214             entry 
= entry
->sfe_next_onsocket
) { 
1215                 /* skip if this is a subflow socket */ 
1216                 if (so
->so_flags 
& SOF_MP_SUBFLOW
) { 
1219                 if ((entry
->sfe_flags 
& SFEF_ATTACHED
) && 
1220                     entry
->sfe_filter
->sf_filter
.sf_data_in
) { 
1222                          * Retain the filter entry and 
1223                          * release the socket filter lock 
1225                         sflt_entry_retain(entry
); 
1226                         lck_rw_unlock_shared(&sock_filter_lock
); 
1228                         /* If the socket isn't already unlocked, unlock it */ 
1229                         if (unlocked 
== 0) { 
1231                                 socket_unlock(so
, 0); 
1234                         /* Call the filter */ 
1235                         error 
= entry
->sfe_filter
->sf_filter
.sf_data_in( 
1236                                 entry
->sfe_cookie
, so
, from
, data
, control
, flags
); 
1239                          * Take the socket filter lock again 
1240                          * and release the entry 
1242                         lck_rw_lock_shared(&sock_filter_lock
); 
1243                         sflt_entry_release(entry
); 
1246         lck_rw_unlock_shared(&sock_filter_lock
); 
1255 #pragma mark -- KPI -- 
1258 sflt_attach(socket_t socket
, sflt_handle handle
) 
1260         socket_lock(socket
, 1); 
1261         errno_t result 
= sflt_attach_internal(socket
, handle
); 
1262         socket_unlock(socket
, 1); 
1267 sflt_detach(socket_t socket
, sflt_handle handle
) 
1269         struct socket_filter_entry 
*entry
; 
1272         if (socket 
== NULL 
|| handle 
== 0) { 
1276         lck_rw_lock_exclusive(&sock_filter_lock
); 
1277         for (entry 
= socket
->so_filt
; entry
; entry 
= entry
->sfe_next_onsocket
) { 
1278                 if (entry
->sfe_filter
->sf_filter
.sf_handle 
== handle 
&& 
1279                     (entry
->sfe_flags 
& SFEF_ATTACHED
) != 0) { 
1284         if (entry 
!= NULL
) { 
1285                 sflt_detach_locked(entry
); 
1287         lck_rw_unlock_exclusive(&sock_filter_lock
); 
1293         struct solist 
*next
; 
1298 sflt_register_common(const struct sflt_filter 
*filter
, int domain
, int type
, 
1299     int  protocol
, bool is_internal
) 
1301         struct socket_filter 
*sock_filt 
= NULL
; 
1302         struct socket_filter 
*match 
= NULL
; 
1308         struct solist 
*solisthead 
= NULL
, *solist 
= NULL
; 
1310         if ((domain 
!= PF_INET
) && (domain 
!= PF_INET6
)) { 
1314         pr 
= pffindproto(domain
, protocol
, type
); 
1319         if (filter
->sf_attach 
== NULL 
|| filter
->sf_detach 
== NULL 
|| 
1320             filter
->sf_handle 
== 0 || filter
->sf_name 
== NULL
) { 
1324         /* Allocate the socket filter */ 
1325         sock_filt 
= kheap_alloc(KM_IFADDR
, 
1326             sizeof(struct socket_filter
), Z_WAITOK 
| Z_ZERO
); 
1327         if (sock_filt 
== NULL
) { 
1331         /* Legacy sflt_filter length; current structure minus extended */ 
1332         len 
= sizeof(*filter
) - sizeof(struct sflt_filter_ext
); 
1334          * Include extended fields if filter defines SFLT_EXTENDED. 
1335          * We've zeroed out our internal sflt_filter placeholder, 
1336          * so any unused portion would have been taken care of. 
1338         if (filter
->sf_flags 
& SFLT_EXTENDED
) { 
1339                 unsigned int ext_len 
= filter
->sf_len
; 
1341                 if (ext_len 
> sizeof(struct sflt_filter_ext
)) { 
1342                         ext_len 
= sizeof(struct sflt_filter_ext
); 
1347         bcopy(filter
, &sock_filt
->sf_filter
, len
); 
1349         lck_rw_lock_exclusive(&sock_filter_lock
); 
1350         /* Look for an existing entry */ 
1351         TAILQ_FOREACH(match
, &sock_filter_head
, sf_global_next
) { 
1352                 if (match
->sf_filter
.sf_handle 
== 
1353                     sock_filt
->sf_filter
.sf_handle
) { 
1358         /* Add the entry only if there was no existing entry */ 
1359         if (match 
== NULL
) { 
1360                 TAILQ_INSERT_TAIL(&sock_filter_head
, sock_filt
, sf_global_next
); 
1361                 if ((sock_filt
->sf_filter
.sf_flags 
& SFLT_GLOBAL
) != 0) { 
1362                         TAILQ_INSERT_TAIL(&pr
->pr_filter_head
, sock_filt
, 
1364                         sock_filt
->sf_proto 
= pr
; 
1366                 os_ref_init(&sock_filt
->sf_refcount
, NULL
); 
1368                 OSIncrementAtomic64(&net_api_stats
.nas_sfltr_register_count
); 
1369                 INC_ATOMIC_INT64_LIM(net_api_stats
.nas_sfltr_register_total
); 
1371                         INC_ATOMIC_INT64_LIM(net_api_stats
.nas_sfltr_register_os_total
); 
1374         lck_rw_unlock_exclusive(&sock_filter_lock
); 
1376         if (match 
!= NULL
) { 
1377                 kheap_free(KM_IFADDR
, sock_filt
, sizeof(struct socket_filter
)); 
1381         if (!(filter
->sf_flags 
& SFLT_EXTENDED_REGISTRY
)) { 
1386          * Setup the filter on the TCP and UDP sockets already created. 
1388 #define SOLIST_ADD(_so) do {                                            \ 
1389         solist->next = solisthead;                                      \ 
1390         sock_retain((_so));                                             \ 
1391         solist->so = (_so);                                             \ 
1392         solisthead = solist;                                            \ 
1394         if (protocol 
== IPPROTO_TCP
) { 
1395                 lck_rw_lock_shared(tcbinfo
.ipi_lock
); 
1396                 LIST_FOREACH(inp
, tcbinfo
.ipi_listhead
, inp_list
) { 
1397                         so 
= inp
->inp_socket
; 
1398                         if (so 
== NULL 
|| (so
->so_state 
& SS_DEFUNCT
) || 
1399                             (!(so
->so_flags 
& SOF_MP_SUBFLOW
) && 
1400                             (so
->so_state 
& SS_NOFDREF
)) || 
1401                             !SOCK_CHECK_DOM(so
, domain
) || 
1402                             !SOCK_CHECK_TYPE(so
, type
)) { 
1405                         solist 
= kheap_alloc(KHEAP_TEMP
, sizeof(struct solist
), Z_NOWAIT
); 
1411                 lck_rw_done(tcbinfo
.ipi_lock
); 
1412         } else if (protocol 
== IPPROTO_UDP
) { 
1413                 lck_rw_lock_shared(udbinfo
.ipi_lock
); 
1414                 LIST_FOREACH(inp
, udbinfo
.ipi_listhead
, inp_list
) { 
1415                         so 
= inp
->inp_socket
; 
1416                         if (so 
== NULL 
|| (so
->so_state 
& SS_DEFUNCT
) || 
1417                             (!(so
->so_flags 
& SOF_MP_SUBFLOW
) && 
1418                             (so
->so_state 
& SS_NOFDREF
)) || 
1419                             !SOCK_CHECK_DOM(so
, domain
) || 
1420                             !SOCK_CHECK_TYPE(so
, type
)) { 
1423                         solist 
= kheap_alloc(KHEAP_TEMP
, sizeof(struct solist
), Z_NOWAIT
); 
1429                 lck_rw_done(udbinfo
.ipi_lock
); 
1431         /* XXX it's possible to walk the raw socket list as well */ 
1434         while (solisthead
) { 
1435                 sflt_handle handle 
= filter
->sf_handle
; 
1437                 so 
= solisthead
->so
; 
1440                 if (so
->so_state 
& SS_ISCONNECTING
) { 
1441                         sflt_notify_after_register(so
, sock_evt_connecting
, 
1443                 } else if (so
->so_state 
& SS_ISCONNECTED
) { 
1444                         sflt_notify_after_register(so
, sock_evt_connected
, 
1446                 } else if ((so
->so_state 
& 
1447                     (SS_ISDISCONNECTING 
| SS_CANTRCVMORE 
| SS_CANTSENDMORE
)) == 
1448                     (SS_ISDISCONNECTING 
| SS_CANTRCVMORE 
| SS_CANTSENDMORE
)) { 
1449                         sflt_notify_after_register(so
, sock_evt_disconnecting
, 
1451                 } else if ((so
->so_state 
& 
1452                     (SS_CANTRCVMORE 
| SS_CANTSENDMORE 
| SS_ISDISCONNECTED
)) == 
1453                     (SS_CANTRCVMORE 
| SS_CANTSENDMORE 
| SS_ISDISCONNECTED
)) { 
1454                         sflt_notify_after_register(so
, sock_evt_disconnected
, 
1456                 } else if (so
->so_state 
& SS_CANTSENDMORE
) { 
1457                         sflt_notify_after_register(so
, sock_evt_cantsendmore
, 
1459                 } else if (so
->so_state 
& SS_CANTRCVMORE
) { 
1460                         sflt_notify_after_register(so
, sock_evt_cantrecvmore
, 
1463                 socket_unlock(so
, 0); 
1464                 /* XXX no easy way to post the sock_evt_closing event */ 
1466                 solist 
= solisthead
; 
1467                 solisthead 
= solisthead
->next
; 
1468                 kheap_free(KHEAP_TEMP
, solist
, sizeof(struct solist
)); 
1475 sflt_register_internal(const struct sflt_filter 
*filter
, int domain
, int type
, 
1478         return sflt_register_common(filter
, domain
, type
, protocol
, true); 
1482 sflt_register(const struct sflt_filter 
*filter
, int domain
, int type
, 
1485         return sflt_register_common(filter
, domain
, type
, protocol
, false); 
1489 sflt_unregister(sflt_handle handle
) 
1491         struct socket_filter 
*filter
; 
1492         lck_rw_lock_exclusive(&sock_filter_lock
); 
1494         /* Find the entry by the handle */ 
1495         TAILQ_FOREACH(filter
, &sock_filter_head
, sf_global_next
) { 
1496                 if (filter
->sf_filter
.sf_handle 
== handle
) { 
1502                 VERIFY(OSDecrementAtomic64(&net_api_stats
.nas_sfltr_register_count
) > 0); 
1504                 /* Remove it from the global list */ 
1505                 TAILQ_REMOVE(&sock_filter_head
, filter
, sf_global_next
); 
1507                 /* Remove it from the protosw list */ 
1508                 if ((filter
->sf_filter
.sf_flags 
& SFLT_GLOBAL
) != 0) { 
1509                         TAILQ_REMOVE(&filter
->sf_proto
->pr_filter_head
, 
1510                             filter
, sf_protosw_next
); 
1513                 /* Detach from any sockets */ 
1514                 struct socket_filter_entry 
*entry 
= NULL
; 
1516                 for (entry 
= filter
->sf_entry_head
; entry
; 
1517                     entry 
= entry
->sfe_next_onfilter
) { 
1518                         sflt_detach_locked(entry
); 
1521                 /* Release the filter */ 
1522                 sflt_release_locked(filter
); 
1525         lck_rw_unlock_exclusive(&sock_filter_lock
); 
1527         if (filter 
== NULL
) { 
1535 sock_inject_data_in(socket_t so
, const struct sockaddr 
*from
, mbuf_t data
, 
1536     mbuf_t control
, sflt_data_flag_t flags
) 
1540         if (so 
== NULL 
|| data 
== NULL
) { 
1544         if (flags 
& sock_data_filt_flag_oob
) { 
1550         /* reject if this is a subflow socket */ 
1551         if (so
->so_flags 
& SOF_MP_SUBFLOW
) { 
1557                 if (sbappendaddr(&so
->so_rcv
, 
1558                     (struct sockaddr 
*)(uintptr_t)from
, data
, control
, NULL
)) { 
1565                 if (sbappendcontrol(&so
->so_rcv
, data
, control
, NULL
)) { 
1571         if (flags 
& sock_data_filt_flag_record
) { 
1572                 if (control 
|| from
) { 
1576                 if (sbappendrecord(&so
->so_rcv
, (struct mbuf 
*)data
)) { 
1582         if (sbappend(&so
->so_rcv
, data
)) { 
1586         socket_unlock(so
, 1); 
1591 sock_inject_data_out(socket_t so
, const struct sockaddr 
*to
, mbuf_t data
, 
1592     mbuf_t control
, sflt_data_flag_t flags
) 
1594         int sosendflags 
= 0; 
1596         /* reject if this is a subflow socket */ 
1597         if (so
->so_flags 
& SOF_MP_SUBFLOW
) { 
1601         if (flags 
& sock_data_filt_flag_oob
) { 
1602                 sosendflags 
= MSG_OOB
; 
1604         return sosend(so
, (struct sockaddr 
*)(uintptr_t)to
, NULL
, 
1605                    data
, control
, sosendflags
); 
1609 sockopt_direction(sockopt_t sopt
) 
1611         return (sopt
->sopt_dir 
== SOPT_GET
) ? sockopt_get 
: sockopt_set
; 
1615 sockopt_level(sockopt_t sopt
) 
1617         return sopt
->sopt_level
; 
1621 sockopt_name(sockopt_t sopt
) 
1623         return sopt
->sopt_name
; 
1627 sockopt_valsize(sockopt_t sopt
) 
1629         return sopt
->sopt_valsize
; 
1633 sockopt_copyin(sockopt_t sopt
, void *data
, size_t len
) 
1635         return sooptcopyin(sopt
, data
, len
, len
); 
1639 sockopt_copyout(sockopt_t sopt
, void *data
, size_t len
) 
1641         return sooptcopyout(sopt
, data
, len
);