2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
25 * IONetworkStack.cpp - An IOKit proxy for the BSD network stack.
29 * IONetworkStack abstracts essential network stack services. These
30 * include registering/unregistering network interfaces, and interface
31 * name space management.
33 * Only a single IONetworkStack object is instantiated. This object will
34 * register to receive a notification when a network interface object is
35 * first published. The notification handler is responsible for attaching
36 * the network stack object to the interface object as a client. When the
37 * interface is terminated, this linkage is severed.
39 * This object does not participate in the data/packet flow. The interface
40 * object will interact directly with DLIL to send and to receive packets.
43 #include <IOKit/assert.h>
44 #include <IOKit/IOLib.h>
45 #include <IOKit/IOBSD.h>
46 #include <IOKit/IOMessage.h>
47 #include <IOKit/IOKitKeys.h>
48 #include <IOKit/network/IONetworkInterface.h>
49 #include <IOKit/network/IONetworkStack.h>
50 #include <libkern/c++/OSDictionary.h>
53 #include <sys/param.h>
55 #include <sys/socket.h>
58 #include <netinet/if_ether.h>
60 #include <sys/sockio.h>
61 void ether_ifattach(struct ifnet
* ifp
); // FIXME
64 #define super IOService
65 OSDefineMetaClassAndStructors( IONetworkStack
, IOService
)
66 OSMetaClassDefineReservedUnused( IONetworkStack
, 0);
67 OSMetaClassDefineReservedUnused( IONetworkStack
, 1);
68 OSMetaClassDefineReservedUnused( IONetworkStack
, 2);
69 OSMetaClassDefineReservedUnused( IONetworkStack
, 3);
72 #define __LOG(class, fn, fmt, args...) IOLog(class "::%s " fmt, fn, ## args)
73 #define DLOG(fmt, args...) __LOG("IONetworkStack", __FUNCTION__, fmt, ## args)
75 #define DLOG(fmt, args...)
78 #define NETIF_FLAGS(n) ((n)->_clientVar[0])
79 #define SET_NETIF_FLAGS(n, x) (NETIF_FLAGS(n) |= (x))
80 #define CLR_NETIF_FLAGS(n, x) (NETIF_FLAGS(n) &= ~(x))
82 static IONetworkStack
* gIONetworkStack
= 0;
84 // Flags encoded on the interface object.
87 kInterfaceFlagActive
= 0x01, // Interface is awaiting registration
88 kInterfaceFlagRegistered
= 0x02, // Interface has registered with DLIL
89 kInterfaceFlagRegistering
= 0x04 // Interface is registering with DLIL
92 // IONetworkStackUserClient definition.
94 #include <IOKit/IOUserClient.h>
96 class IONetworkStackUserClient
: public IOUserClient
98 OSDeclareDefaultStructors( IONetworkStackUserClient
)
101 IONetworkStack
* _provider
;
104 static IONetworkStackUserClient
* withTask( task_t owningTask
);
105 virtual bool start( IOService
* provider
);
106 virtual IOReturn
clientClose();
107 virtual IOReturn
clientDied();
108 virtual IOReturn
setProperties( OSObject
* properties
);
111 //---------------------------------------------------------------------------
112 // Initialize the IONetworkStack object.
114 bool IONetworkStack::init( OSDictionary
* properties
)
116 // Init our superclass first.
118 if ( super::init(properties
) == false )
124 //---------------------------------------------------------------------------
125 // IONetworkStack was matched to its provider (IOResources), now start it up.
127 bool IONetworkStack::start( IOService
* provider
)
129 DLOG("%p\n", provider
);
131 if ( super::start(provider
) == false )
134 // Only a single IONetworkStack object is created, and a reference
135 // to this object is stored in a global variable.
137 // When the boot process is VERY VERY slow for some unknown reason
138 // we get two instances of IONetworkStack and theassert below fires.
139 // so I am commenting the assert and replacing it with an if statement.
140 // assert( gIONetworkStack == 0 );
142 if ( gIONetworkStack
!= 0 )
145 gIONetworkStack
= this;
147 // Create containers to store interface objects.
149 _ifSet
= OSOrderedSet::withCapacity(10);
153 _ifDict
= OSDictionary::withCapacity(4);
157 // Create a notification object to call a 'C' function, every time an
158 // interface object is first published.
160 _interfaceNotifier
= addNotification(
161 /* type */ gIOFirstPublishNotification
,
162 /* match */ serviceMatching("IONetworkInterface"),
163 /* action */ interfacePublished
,
166 if ( _interfaceNotifier
== 0 ) return false;
168 // Register the IONetworkStack object.
179 //---------------------------------------------------------------------------
180 // Stop is called by a terminated provider, after being closed, but before
181 // this client object is detached from it.
183 void IONetworkStack::stop( IOService
* provider
)
185 DLOG("%p\n", provider
);
186 super::stop(provider
);
189 //---------------------------------------------------------------------------
190 // Release allocated resources.
192 void IONetworkStack::free()
196 // IONotifier::remove() will remove the notification request
197 // and release the object.
199 if ( _interfaceNotifier
)
201 _interfaceNotifier
->remove();
202 _interfaceNotifier
= 0;
205 // Free interface containers.
221 // Propagate the free to superclass.
226 //---------------------------------------------------------------------------
227 // A static method to get the global network stack object.
229 IONetworkStack
* IONetworkStack::getNetworkStack()
231 return (IONetworkStack
*) IOService::waitForService(
232 IOService::serviceMatching("IONetworkStack") );
236 //===========================================================================
238 // Interface object container helpers.
240 //===========================================================================
242 //---------------------------------------------------------------------------
243 // Add the new interface object to an OSOrderedSet.
245 bool IONetworkStack::addInterface( IONetworkInterface
* netif
)
247 return _ifSet
->setObject(netif
);
250 //---------------------------------------------------------------------------
251 // Remove an interface object from an OSOrderedSet.
253 void IONetworkStack::removeInterface( IONetworkInterface
* netif
)
255 _ifSet
->removeObject(netif
);
256 DLOG("count = %d\n", _ifSet
->getCount());
259 //---------------------------------------------------------------------------
260 // Get an interface object at a given index.
262 IONetworkInterface
* IONetworkStack::getInterface( UInt32 index
)
264 return (IONetworkInterface
*) _ifSet
->getObject(index
);
267 //---------------------------------------------------------------------------
268 // Query whether the specified interface object is a member of the Set.
270 bool IONetworkStack::containsInterface( IONetworkInterface
* netif
)
272 return _ifSet
->containsObject(netif
);
275 //---------------------------------------------------------------------------
276 // Add an interface object to the set of registered interfaces.
278 bool IONetworkStack::addRegisteredInterface( IONetworkInterface
* netif
)
282 const char * prefix
= netif
->getNamePrefix();
284 if (prefix
== 0) return false;
286 // Look for a Set object in the dictionary.
288 set
= (OSOrderedSet
*) _ifDict
->getObject(prefix
);
290 // If not found, then create one and add it to the dictionary.
293 ((set
= OSOrderedSet::withCapacity(10, orderRegisteredInterfaces
))) )
295 success
= _ifDict
->setObject(prefix
, set
);
299 // Add the interface object to its corresponding set.
300 // All objects in a set will have the same name prefix.
302 success
= (set
&& success
) ? set
->setObject(netif
) : false;
307 //---------------------------------------------------------------------------
308 // Remove an interface object from the set of registered interfaces.
310 void IONetworkStack::removeRegisteredInterface( IONetworkInterface
* netif
)
313 const char * prefix
= netif
->getNamePrefix();
317 set
= (OSOrderedSet
*) _ifDict
->getObject(prefix
);
321 // Remove interface from set.
323 set
->removeObject(netif
);
324 DLOG("set:%s count = %d\n", prefix
, set
->getCount());
326 // Remove (also release) the set from the dictionary.
328 if ( set
->getCount() == 0 ) _ifDict
->removeObject(prefix
);
333 //---------------------------------------------------------------------------
334 // Get an registered interface with the given prefix and unit number.
337 IONetworkStack::getRegisteredInterface( const char * prefix
,
341 IONetworkInterface
* netif
= 0;
343 set
= (OSOrderedSet
*) _ifDict
->getObject(prefix
);
345 for ( UInt32 index
= 0;
346 ( set
&& (netif
= (IONetworkInterface
*) set
->getObject(index
)) );
349 if ( netif
->getUnitNumber() == unit
)
356 //---------------------------------------------------------------------------
357 // Get the last object (with largest index) in the set of registered
358 // interfaces with the specified prefix.
361 IONetworkStack::getLastRegisteredInterface( const char * prefix
)
365 set
= (OSOrderedSet
*) _ifDict
->getObject(prefix
);
367 return ( set
) ? (IONetworkInterface
*) set
->getLastObject() : 0;
370 //---------------------------------------------------------------------------
371 // Get the next available unit number in the set of registered interfaces
372 // with the specified prefix.
375 IONetworkStack::getNextAvailableUnitNumber( const char * prefix
,
376 UInt32 startingUnit
)
378 IONetworkInterface
* netif
= getLastRegisteredInterface(prefix
);
380 if ( ( netif
== 0 ) || ( netif
->getUnitNumber() < startingUnit
) )
382 // The unit number provided is acceptable.
384 else if ( netif
->getUnitNumber() == startingUnit
)
386 // Conflict, bump proposed unit number by one.
391 OSOrderedSet
* set
= (OSOrderedSet
*) _ifDict
->getObject(prefix
);
393 for ( UInt32 index
= 0; set
; index
++ )
395 netif
= (IONetworkInterface
*) set
->getObject(index
);
397 if ( ( netif
== 0 ) ||
398 ( netif
->getUnitNumber() > startingUnit
) )
400 else if ( netif
->getUnitNumber() < startingUnit
)
403 startingUnit
= netif
->getUnitNumber() + 1;
411 //===========================================================================
413 // Interface Management.
415 //===========================================================================
418 //---------------------------------------------------------------------------
419 // A static member function that is called by a notification object when an
420 // interface is published. This function is called with arbitration lock of
421 // the interface object held.
423 bool IONetworkStack::interfacePublished( void * /* target */,
425 IOService
* service
)
427 IONetworkInterface
* netif
= OSDynamicCast(IONetworkInterface
, service
);
428 bool success
= false;
432 if ( gIONetworkStack
== 0 )
435 gIONetworkStack
->lockForArbitration();
438 if ( netif
== 0 ) break;
440 // Early exit from redundant notifications.
442 if ( gIONetworkStack
->containsInterface(netif
) == true )
448 // Add the interface to a collection.
450 if ( gIONetworkStack
->addInterface(netif
) == false )
453 // Attach the stack object to the interface object as its client.
455 if ( gIONetworkStack
->attach(netif
) == false )
458 // Initialize the interface flags. These flags are used only
459 // by IONetworkStack.
461 NETIF_FLAGS(netif
) = kInterfaceFlagActive
;
463 // No outside intervention is required for the primary interface
464 // to be registered at unit 0. This is to assure that we have 'en0'
465 // even if something is really fouled up. Ideally, this should be
466 // removed in the future and have a single entity manage the
467 // naming responsibility. And on Intel, there is no concept of a
468 // "built-in" interface, so this will do nothing for Intel.
470 if ( gIONetworkStack
->_registerPrimaryInterface
&&
471 netif
->isPrimaryInterface() )
473 const char * prefix
= netif
->getNamePrefix();
474 const UInt32 unit
= 0;
476 // If another interface already took unit 0, do nothing.
478 if ( gIONetworkStack
->getRegisteredInterface(prefix
, unit
) == 0 )
480 OSArray
* array
= OSArray::withCapacity(1);
483 gIONetworkStack
->preRegisterInterface( netif
,
488 completeRegistration( array
, false ); // Async
497 // Remove interface on failure.
499 if (success
== false) gIONetworkStack
->removeInterface(netif
);
501 gIONetworkStack
->unlockForArbitration();
506 //---------------------------------------------------------------------------
507 // Handle termination messages sent from the interface object (provider).
509 IOReturn
IONetworkStack::message( UInt32 type
,
510 IOService
* provider
,
511 void * /* argument */ )
513 IONetworkInterface
* netif
= (IONetworkInterface
*) provider
;
514 IOReturn ret
= kIOReturnBadArgument
;
516 DLOG("%lx %p\n", type
, provider
);
518 if ( type
== kIOMessageServiceIsTerminated
)
520 lockForArbitration();
523 // Verify that the provider object given is known.
525 if ( containsInterface(netif
) == false )
528 ret
= kIOReturnSuccess
;
530 // Interface has become inactive, it is no longer possible
531 // to open or to attach to the interface object.
532 // Mark the interface as Inactive.
534 CLR_NETIF_FLAGS( netif
, kInterfaceFlagActive
);
536 // Interface is registering with DLIL. Postpone termination until
537 // the interface has completed the registration.
539 if ( NETIF_FLAGS(netif
) & kInterfaceFlagRegistering
)
542 // Remove the interface object. Don't worry, it is still retained.
544 removeInterface(netif
);
546 // If interface was never registered with BSD, no additional
547 // action is required.
549 if ( (NETIF_FLAGS(netif
) & kInterfaceFlagRegistered
) == 0 )
552 // Need to unregister the interface. Do this asynchronously.
553 // The interface will be waiting for a close before advancing
554 // to the next stage in the termination process.
556 thread_call_func( (thread_call_func_t
) unregisterBSDInterface
,
558 TRUE
); /* unique call desired */
562 unlockForArbitration();
568 //---------------------------------------------------------------------------
569 // Detach an inactive interface that is currently registered with BSD.
571 void IONetworkStack::unregisterBSDInterface( IONetworkInterface
* netif
)
575 // If dlil_if_detach() returns DLIL_WAIT_FOR_FREE, then we
576 // must not close the interface until we receive a callback
577 // from DLIL. Otherwise, proceed with the close.
581 if ( dlil_if_detach(netif
->getIfnet()) != DLIL_WAIT_FOR_FREE
)
583 bsdInterfaceWasUnregistered( netif
->getIfnet() );
587 //---------------------------------------------------------------------------
588 // Handle a callback from DLIL to signal that an interface can now be safely
589 // destroyed. DLIL will issue this call only if the dlil_if_detach() function
590 // returned DLIL_WAIT_FOR_FREE.
592 int IONetworkStack::bsdInterfaceWasUnregistered( struct ifnet
* ifp
)
594 IONetworkInterface
* netif
;
598 netif
= (IONetworkInterface
*) ifp
->if_private
;
601 assert( netif
&& gIONetworkStack
);
603 // An interface was detached from DLIL. It is now safe to close the
606 gIONetworkStack
->lockForArbitration();
608 assert( NETIF_FLAGS(netif
) == kInterfaceFlagRegistered
);
612 CLR_NETIF_FLAGS( netif
, kInterfaceFlagRegistered
);
614 // Drop interface from list of registered interfaces,
615 // and decrement interface retain count.
617 gIONetworkStack
->removeRegisteredInterface(netif
);
619 gIONetworkStack
->unlockForArbitration();
621 // Make sure the interface is brought down before it is closed.
623 netif
->setFlags( 0, IFF_UP
); // clear IFF_UP flag.
624 (*ifp
->if_ioctl
)(ifp
, SIOCSIFFLAGS
, 0);
626 // Close interface and allow it to proceed with termination.
628 netif
->close(gIONetworkStack
);
633 //---------------------------------------------------------------------------
634 // Pre-register a network interface. This function assumes that the
635 // caller is holding the arbitration lock.
637 bool IONetworkStack::preRegisterInterface( IONetworkInterface
* netif
,
642 bool success
= false;
644 DLOG("%p %s %d\n", netif
, prefix
? prefix
: "", unit
);
646 assert( netif
&& array
);
649 if ( prefix
== 0 ) break;
651 // Verify that the interface object given is known.
653 if ( containsInterface(netif
) == false )
656 // Interface must be in Active state.
658 if ( NETIF_FLAGS(netif
) != kInterfaceFlagActive
)
663 // The unit argument provided is a hint to indicate the lowest unit
664 // number that can be assigned to the interface. We are allowed to
665 // increment the unit number provided if the number is already
668 unit
= getNextAvailableUnitNumber(prefix
, unit
);
670 // Open the interface object. This will fail if the interface
671 // object has become inactive. Beware of reverse lock acquisition
672 // sequence, which is interface then stack arbitration lock.
673 // Must avoid taking locks in that order to avoid deadlocks.
674 // The only exception is when handling the "First Publish"
675 // notification, which is safe since the stack object does not
676 // yet have a reference to the new interface.
678 if ( netif
->open(this) == false )
683 // Update interface name properties and add the interface object
684 // to a collection of registered interfaces. The chosen name will
685 // be reserved until the interface is removed from the collection
686 // of registered interfaces.
688 if ( ( netif
->setUnitNumber(unit
) == false ) ||
689 ( addRegisteredInterface(netif
) == false ) )
701 // Mark the interface as in the process of registering.
703 SET_NETIF_FLAGS( netif
, kInterfaceFlagRegistering
);
705 // Add interface to pre-registration array.
706 // We assume the array has enough storage space for the new entry.
708 success
= array
->setObject( netif
);
715 //---------------------------------------------------------------------------
716 // Complete the registration of interface objects stored in the array provided.
717 // The arbitration lock should not be held when the 'isSync' flag is true.
720 IONetworkStack::completeRegistration( OSArray
* array
, bool isSync
)
724 completeRegistrationUsingArray( array
);
728 thread_call_func( (thread_call_func_t
) completeRegistrationUsingArray
,
730 TRUE
); /* unique call desired */
735 IONetworkStack::completeRegistrationUsingArray( OSArray
* array
)
737 IONetworkInterface
* netif
;
741 for ( UInt32 i
= 0; i
< array
->getCount(); i
++ )
743 netif
= (IONetworkInterface
*) array
->getObject(i
);
746 registerBSDInterface( netif
);
749 array
->release(); // consumes a ref count
752 //---------------------------------------------------------------------------
753 // Call DLIL functions to register the BSD interface.
755 void IONetworkStack::registerBSDInterface( IONetworkInterface
* netif
)
758 bool doTermination
= false;
762 // Attach the interface to DLIL.
764 bpfattach( netif
->getIfnet(), DLT_EN10MB
, sizeof(struct ether_header
) );
765 ether_ifattach( netif
->getIfnet() );
767 // Add a kIOBSDNameKey property to the interface AFTER the interface
768 // has registered with DLIL. The order is very important to avoid
769 // rooting from an interface which is not yet known by BSD.
771 sprintf(ifname
, "%s%d", netif
->getNamePrefix(), netif
->getUnitNumber());
772 netif
->setProperty(kIOBSDNameKey
, ifname
);
774 // Update state bits and detect for untimely interface termination.
776 gIONetworkStack
->lockForArbitration();
778 assert( ( NETIF_FLAGS(netif
) &
779 ( kInterfaceFlagRegistering
| kInterfaceFlagRegistered
) ) ==
780 kInterfaceFlagRegistering
);
782 CLR_NETIF_FLAGS( netif
, kInterfaceFlagRegistering
);
783 SET_NETIF_FLAGS( netif
, kInterfaceFlagRegistered
);
785 if ( ( NETIF_FLAGS(netif
) & kInterfaceFlagActive
) == 0 )
787 doTermination
= true;
791 // Re-register interface after the interface has registered with BSD.
792 // Is there a danger in calling registerService while holding the
793 // gIONetworkStack's arbitration lock?
795 netif
->registerService();
798 gIONetworkStack
->unlockForArbitration();
800 // In the unlikely event that an interface was terminated before
801 // being registered, re-issue the termination message and tear it
806 gIONetworkStack
->message(kIOMessageServiceIsTerminated
, netif
);
810 //---------------------------------------------------------------------------
811 // External/Public API - Register all interfaces.
814 IONetworkStack::registerAllInterfaces()
816 IONetworkInterface
* netif
;
817 const UInt32 unit
= 0;
820 lockForArbitration();
822 // Allocate array to hold pre-registered interface objects.
824 array
= OSArray::withCapacity( _ifSet
->getCount() );
827 unlockForArbitration();
828 return kIOReturnNoMemory
;
831 // Iterate through all interface objects.
833 for ( UInt32 index
= 0; ( netif
= getInterface(index
) ); index
++ )
835 // Interface must be Active and not yet registered.
837 if ( NETIF_FLAGS(netif
) != kInterfaceFlagActive
)
842 // Pre-register the interface.
844 preRegisterInterface( netif
,
845 netif
->getNamePrefix(),
850 unlockForArbitration();
852 // Complete registration without holding the arbitration lock.
854 completeRegistration( array
, true );
856 return kIOReturnSuccess
;
859 //---------------------------------------------------------------------------
860 // External/Public API - Register primary interface.
862 IOReturn
IONetworkStack::registerPrimaryInterface( bool enable
)
864 IONetworkInterface
* netif
;
865 const UInt32 unit
= 0;
868 lockForArbitration();
870 _registerPrimaryInterface
= enable
;
872 if ( _registerPrimaryInterface
== false )
874 unlockForArbitration();
875 return kIOReturnSuccess
;
878 // Allocate array to hold pre-registered interface objects.
880 array
= OSArray::withCapacity( _ifSet
->getCount() );
883 unlockForArbitration();
884 return kIOReturnNoMemory
;
887 // Iterate through all interface objects.
889 for ( UInt32 index
= 0; ( netif
= getInterface(index
) ); index
++ )
891 const char * prefix
= netif
->getNamePrefix();
893 // Interface must be Active and not yet registered.
895 if ( NETIF_FLAGS(netif
) != kInterfaceFlagActive
)
902 if ( netif
->isPrimaryInterface() != true )
907 // If the unit slot is already taken, forget it.
909 if ( getRegisteredInterface( prefix
, unit
) )
914 // Pre-register the interface.
916 preRegisterInterface( netif
, prefix
, unit
, array
);
919 unlockForArbitration();
921 // Complete registration without holding the arbitration lock.
923 completeRegistration( array
, true );
925 return kIOReturnSuccess
;
928 //---------------------------------------------------------------------------
929 // External/Public API - Register a single interface.
931 IOReturn
IONetworkStack::registerInterface( IONetworkInterface
* netif
,
939 // Create pre-registration array.
941 array
= OSArray::withCapacity( 1 );
944 return kIOReturnNoMemory
;
947 // Pre-registration has to be serialized, but the registration can
948 // (and should) be completed without holding a lock. If the interface
949 // has already been registered, or cannot be registered, then the
950 // return value will be false.
952 lockForArbitration();
953 ret
= preRegisterInterface( netif
, prefix
, unit
, array
);
954 unlockForArbitration();
956 // Complete the registration synchronously or asynchronously.
957 // If synchronous, then this call will return after the interface
958 // object in the array has registered with DLIL.
960 completeRegistration( array
, isSync
);
962 return ret
? kIOReturnSuccess
: kIOReturnError
;
965 //---------------------------------------------------------------------------
966 // Registered interfaces are ordered by their assigned unit number. Those with
967 // larger unit numbers will be placed behind those with smaller unit numbers.
968 // This ordering makes it easier to hunt for an available unit number slot for
971 SInt32
IONetworkStack::
972 orderRegisteredInterfaces( const OSMetaClassBase
* obj1
,
973 const OSMetaClassBase
* obj2
,
976 const IONetworkInterface
* netif1
= (const IONetworkInterface
*) obj1
;
977 const IONetworkInterface
* netif2
= (const IONetworkInterface
*) obj2
;
979 assert( netif1
&& netif2
);
981 return ( netif2
->getUnitNumber() - netif1
->getUnitNumber() );
984 //---------------------------------------------------------------------------
985 // Create a user-client object to manage user space access.
987 IOReturn
IONetworkStack::newUserClient( task_t owningTask
,
988 void * /* security_id */,
990 IOUserClient
** handler
)
992 IOReturn err
= kIOReturnSuccess
;
993 IOUserClient
* client
;
995 client
= IONetworkStackUserClient::withTask(owningTask
);
997 if (!client
|| !client
->attach(this) || !client
->start(this))
1001 client
->detach(this);
1004 err
= kIOReturnExclusiveAccess
;
1008 err
= kIOReturnNoMemory
;
1017 //---------------------------------------------------------------------------
1018 // IONetworkStackUserClient implementation.
1021 #define super IOUserClient
1022 OSDefineMetaClassAndStructors( IONetworkStackUserClient
, IOUserClient
)
1024 IONetworkStackUserClient
* IONetworkStackUserClient::withTask( task_t task
)
1026 IONetworkStackUserClient
* me
= new IONetworkStackUserClient
;
1028 if ( me
&& me
->init() == false )
1036 bool IONetworkStackUserClient::start( IOService
* provider
)
1038 if ( super::start(provider
) == false )
1041 if ( provider
->open(this) == false )
1044 _provider
= (IONetworkStack
*) provider
;
1049 IOReturn
IONetworkStackUserClient::clientClose()
1053 _provider
->close(this);
1056 return kIOReturnSuccess
;
1059 IOReturn
IONetworkStackUserClient::clientDied()
1061 return clientClose();
1064 IOReturn
IONetworkStackUserClient::setProperties( OSObject
* properties
)
1066 IONetworkInterface
* netif
;
1067 OSDictionary
* dict
= OSDynamicCast(OSDictionary
, properties
);
1068 IOReturn ret
= kIOReturnBadArgument
;
1069 OSString
* path
= 0;
1076 if ( (_provider
== 0) || (dict
== 0) )
1079 // Switch on the specified user command.
1081 cmd
= OSDynamicCast( OSNumber
,
1082 dict
->getObject( kIONetworkStackUserCommand
) );
1086 switch ( cmd
->unsigned32BitValue() )
1088 // Register one interface.
1090 case kIORegisterOne
:
1091 path
= OSDynamicCast( OSString
,
1092 dict
->getObject( kIOPathMatchKey
));
1093 unit
= OSDynamicCast( OSNumber
,
1094 dict
->getObject( kIOInterfaceUnit
));
1096 if ( (path
== 0) || (unit
== 0) )
1101 netif
= OSDynamicCast( IONetworkInterface
,
1102 IORegistryEntry::fromPath( path
->getCStringNoCopy()) );
1104 if ( netif
== 0 ) break;
1106 ret
= _provider
->registerInterface( netif
,
1107 netif
->getNamePrefix(),
1108 unit
->unsigned32BitValue() );
1110 netif
->release(); // offset the retain by fromPath().
1114 // Register all interfaces.
1116 case kIORegisterAll
:
1117 ret
= _provider
->registerAllInterfaces();