]> git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IONetworking/IONetworkStack.cpp
3f5dbc05e03dce46abe124f1bc106f2c8caef2ce
[apple/xnu.git] / iokit / Families / IONetworking / IONetworkStack.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24 *
25 * IONetworkStack.cpp - An IOKit proxy for the BSD network stack.
26 *
27 * HISTORY
28 *
29 * IONetworkStack abstracts essential network stack services. These
30 * include registering/unregistering network interfaces, and interface
31 * name space management.
32 *
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.
38 *
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.
41 */
42
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>
51
52 extern "C" {
53 #include <sys/param.h>
54 #include <sys/mbuf.h>
55 #include <sys/socket.h>
56 #include <net/bpf.h>
57 #include <net/if.h>
58 #include <netinet/if_ether.h>
59 #include <net/dlil.h>
60 #include <sys/sockio.h>
61 void ether_ifattach(struct ifnet * ifp); // FIXME
62 }
63
64 #define super IOService
65 OSDefineMetaClassAndStructors( IONetworkStack, IOService )
66 OSMetaClassDefineReservedUnused( IONetworkStack, 0);
67 OSMetaClassDefineReservedUnused( IONetworkStack, 1);
68 OSMetaClassDefineReservedUnused( IONetworkStack, 2);
69 OSMetaClassDefineReservedUnused( IONetworkStack, 3);
70
71 #ifdef DEBUG_XXX
72 #define __LOG(class, fn, fmt, args...) IOLog(class "::%s " fmt, fn, ## args)
73 #define DLOG(fmt, args...) __LOG("IONetworkStack", __FUNCTION__, fmt, ## args)
74 #else
75 #define DLOG(fmt, args...)
76 #endif
77
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))
81
82 static IONetworkStack * gIONetworkStack = 0;
83
84 // Flags encoded on the interface object.
85 //
86 enum {
87 kInterfaceFlagActive = 0x01, // Interface is awaiting registration
88 kInterfaceFlagRegistered = 0x02, // Interface has registered with DLIL
89 kInterfaceFlagRegistering = 0x04 // Interface is registering with DLIL
90 };
91
92 // IONetworkStackUserClient definition.
93 //
94 #include <IOKit/IOUserClient.h>
95
96 class IONetworkStackUserClient : public IOUserClient
97 {
98 OSDeclareDefaultStructors( IONetworkStackUserClient )
99
100 protected:
101 IONetworkStack * _provider;
102
103 public:
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 );
109 };
110
111 //---------------------------------------------------------------------------
112 // Initialize the IONetworkStack object.
113
114 bool IONetworkStack::init( OSDictionary * properties )
115 {
116 // Init our superclass first.
117
118 if ( super::init(properties) == false )
119 return false;
120
121 return true;
122 }
123
124 //---------------------------------------------------------------------------
125 // IONetworkStack was matched to its provider (IOResources), now start it up.
126
127 bool IONetworkStack::start( IOService * provider )
128 {
129 DLOG("%p\n", provider);
130
131 if ( super::start(provider) == false )
132 return false;
133
134 // Only a single IONetworkStack object is created, and a reference
135 // to this object is stored in a global variable.
136
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 );
141
142 if ( gIONetworkStack != 0 )
143 return false;
144
145 gIONetworkStack = this;
146
147 // Create containers to store interface objects.
148
149 _ifSet = OSOrderedSet::withCapacity(10);
150 if ( _ifSet == 0 )
151 return false;
152
153 _ifDict = OSDictionary::withCapacity(4);
154 if ( _ifDict == 0 )
155 return false;
156
157 // Create a notification object to call a 'C' function, every time an
158 // interface object is first published.
159
160 _interfaceNotifier = addNotification(
161 /* type */ gIOFirstPublishNotification,
162 /* match */ serviceMatching("IONetworkInterface"),
163 /* action */ interfacePublished,
164 /* param */ this );
165
166 if ( _interfaceNotifier == 0 ) return false;
167
168 // Register the IONetworkStack object.
169
170 registerService();
171
172 // Success.
173
174 DLOG("success\n");
175
176 return true;
177 }
178
179 //---------------------------------------------------------------------------
180 // Stop is called by a terminated provider, after being closed, but before
181 // this client object is detached from it.
182
183 void IONetworkStack::stop( IOService * provider )
184 {
185 DLOG("%p\n", provider);
186 super::stop(provider);
187 }
188
189 //---------------------------------------------------------------------------
190 // Release allocated resources.
191
192 void IONetworkStack::free()
193 {
194 DLOG("\n");
195
196 // IONotifier::remove() will remove the notification request
197 // and release the object.
198
199 if ( _interfaceNotifier )
200 {
201 _interfaceNotifier->remove();
202 _interfaceNotifier = 0;
203 }
204
205 // Free interface containers.
206
207 if ( _ifDict )
208 {
209 _ifDict->release();
210 _ifDict = 0;
211 }
212
213 if ( _ifSet )
214 {
215 _ifSet->release();
216 _ifSet = 0;
217 }
218
219 gIONetworkStack = 0;
220
221 // Propagate the free to superclass.
222
223 super::free();
224 }
225
226 //---------------------------------------------------------------------------
227 // A static method to get the global network stack object.
228
229 IONetworkStack * IONetworkStack::getNetworkStack()
230 {
231 return (IONetworkStack *) IOService::waitForService(
232 IOService::serviceMatching("IONetworkStack") );
233 }
234
235
236 //===========================================================================
237 //
238 // Interface object container helpers.
239 //
240 //===========================================================================
241
242 //---------------------------------------------------------------------------
243 // Add the new interface object to an OSOrderedSet.
244
245 bool IONetworkStack::addInterface( IONetworkInterface * netif )
246 {
247 return _ifSet->setObject(netif);
248 }
249
250 //---------------------------------------------------------------------------
251 // Remove an interface object from an OSOrderedSet.
252
253 void IONetworkStack::removeInterface( IONetworkInterface * netif )
254 {
255 _ifSet->removeObject(netif);
256 DLOG("count = %d\n", _ifSet->getCount());
257 }
258
259 //---------------------------------------------------------------------------
260 // Get an interface object at a given index.
261
262 IONetworkInterface * IONetworkStack::getInterface( UInt32 index )
263 {
264 return (IONetworkInterface *) _ifSet->getObject(index);
265 }
266
267 //---------------------------------------------------------------------------
268 // Query whether the specified interface object is a member of the Set.
269
270 bool IONetworkStack::containsInterface( IONetworkInterface * netif )
271 {
272 return _ifSet->containsObject(netif);
273 }
274
275 //---------------------------------------------------------------------------
276 // Add an interface object to the set of registered interfaces.
277
278 bool IONetworkStack::addRegisteredInterface( IONetworkInterface * netif )
279 {
280 bool success = true;
281 OSOrderedSet * set;
282 const char * prefix = netif->getNamePrefix();
283
284 if (prefix == 0) return false;
285
286 // Look for a Set object in the dictionary.
287
288 set = (OSOrderedSet *) _ifDict->getObject(prefix);
289
290 // If not found, then create one and add it to the dictionary.
291
292 if ( (set == 0) &&
293 ((set = OSOrderedSet::withCapacity(10, orderRegisteredInterfaces))) )
294 {
295 success = _ifDict->setObject(prefix, set);
296 set->release();
297 }
298
299 // Add the interface object to its corresponding set.
300 // All objects in a set will have the same name prefix.
301
302 success = (set && success) ? set->setObject(netif) : false;
303
304 return success;
305 }
306
307 //---------------------------------------------------------------------------
308 // Remove an interface object from the set of registered interfaces.
309
310 void IONetworkStack::removeRegisteredInterface( IONetworkInterface * netif )
311 {
312 OSOrderedSet * set;
313 const char * prefix = netif->getNamePrefix();
314
315 if ( prefix )
316 {
317 set = (OSOrderedSet *) _ifDict->getObject(prefix);
318
319 if ( set )
320 {
321 // Remove interface from set.
322
323 set->removeObject(netif);
324 DLOG("set:%s count = %d\n", prefix, set->getCount());
325
326 // Remove (also release) the set from the dictionary.
327
328 if ( set->getCount() == 0 ) _ifDict->removeObject(prefix);
329 }
330 }
331 }
332
333 //---------------------------------------------------------------------------
334 // Get an registered interface with the given prefix and unit number.
335
336 IONetworkInterface *
337 IONetworkStack::getRegisteredInterface( const char * prefix,
338 UInt32 unit )
339 {
340 OSOrderedSet * set;
341 IONetworkInterface * netif = 0;
342
343 set = (OSOrderedSet *) _ifDict->getObject(prefix);
344
345 for ( UInt32 index = 0;
346 ( set && (netif = (IONetworkInterface *) set->getObject(index)) );
347 index++ )
348 {
349 if ( netif->getUnitNumber() == unit )
350 break;
351 }
352
353 return netif;
354 }
355
356 //---------------------------------------------------------------------------
357 // Get the last object (with largest index) in the set of registered
358 // interfaces with the specified prefix.
359
360 IONetworkInterface *
361 IONetworkStack::getLastRegisteredInterface( const char * prefix )
362 {
363 OSOrderedSet * set;
364
365 set = (OSOrderedSet *) _ifDict->getObject(prefix);
366
367 return ( set ) ? (IONetworkInterface *) set->getLastObject() : 0;
368 }
369
370 //---------------------------------------------------------------------------
371 // Get the next available unit number in the set of registered interfaces
372 // with the specified prefix.
373
374 UInt32
375 IONetworkStack::getNextAvailableUnitNumber( const char * prefix,
376 UInt32 startingUnit )
377 {
378 IONetworkInterface * netif = getLastRegisteredInterface(prefix);
379
380 if ( ( netif == 0 ) || ( netif->getUnitNumber() < startingUnit ) )
381 {
382 // The unit number provided is acceptable.
383 }
384 else if ( netif->getUnitNumber() == startingUnit )
385 {
386 // Conflict, bump proposed unit number by one.
387 startingUnit++;
388 }
389 else
390 {
391 OSOrderedSet * set = (OSOrderedSet *) _ifDict->getObject(prefix);
392
393 for ( UInt32 index = 0; set; index++ )
394 {
395 netif = (IONetworkInterface *) set->getObject(index);
396
397 if ( ( netif == 0 ) ||
398 ( netif->getUnitNumber() > startingUnit ) )
399 break;
400 else if ( netif->getUnitNumber() < startingUnit )
401 continue;
402 else
403 startingUnit = netif->getUnitNumber() + 1;
404 }
405 }
406
407 return startingUnit;
408 }
409
410
411 //===========================================================================
412 //
413 // Interface Management.
414 //
415 //===========================================================================
416
417
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.
422
423 bool IONetworkStack::interfacePublished( void * /* target */,
424 void * /* param */,
425 IOService * service )
426 {
427 IONetworkInterface * netif = OSDynamicCast(IONetworkInterface, service);
428 bool success = false;
429
430 DLOG("%p\n", netif);
431
432 if ( gIONetworkStack == 0 )
433 return false;
434
435 gIONetworkStack->lockForArbitration();
436
437 do {
438 if ( netif == 0 ) break;
439
440 // Early exit from redundant notifications.
441
442 if ( gIONetworkStack->containsInterface(netif) == true )
443 {
444 success = true;
445 break;
446 }
447
448 // Add the interface to a collection.
449
450 if ( gIONetworkStack->addInterface(netif) == false )
451 break;
452
453 // Attach the stack object to the interface object as its client.
454
455 if ( gIONetworkStack->attach(netif) == false )
456 break;
457
458 // Initialize the interface flags. These flags are used only
459 // by IONetworkStack.
460
461 NETIF_FLAGS(netif) = kInterfaceFlagActive;
462
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.
469
470 if ( gIONetworkStack->_registerPrimaryInterface &&
471 netif->isPrimaryInterface() )
472 {
473 const char * prefix = netif->getNamePrefix();
474 const UInt32 unit = 0;
475
476 // If another interface already took unit 0, do nothing.
477
478 if ( gIONetworkStack->getRegisteredInterface(prefix, unit) == 0 )
479 {
480 OSArray * array = OSArray::withCapacity(1);
481 if ( array )
482 {
483 gIONetworkStack->preRegisterInterface( netif,
484 prefix,
485 unit,
486 array );
487
488 completeRegistration( array, false ); // Async
489 }
490 }
491 }
492
493 success = true;
494 }
495 while ( false );
496
497 // Remove interface on failure.
498
499 if (success == false) gIONetworkStack->removeInterface(netif);
500
501 gIONetworkStack->unlockForArbitration();
502
503 return success;
504 }
505
506 //---------------------------------------------------------------------------
507 // Handle termination messages sent from the interface object (provider).
508
509 IOReturn IONetworkStack::message( UInt32 type,
510 IOService * provider,
511 void * /* argument */ )
512 {
513 IONetworkInterface * netif = (IONetworkInterface *) provider;
514 IOReturn ret = kIOReturnBadArgument;
515
516 DLOG("%lx %p\n", type, provider);
517
518 if ( type == kIOMessageServiceIsTerminated )
519 {
520 lockForArbitration();
521
522 do {
523 // Verify that the provider object given is known.
524
525 if ( containsInterface(netif) == false )
526 break;
527
528 ret = kIOReturnSuccess;
529
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.
533
534 CLR_NETIF_FLAGS( netif, kInterfaceFlagActive );
535
536 // Interface is registering with DLIL. Postpone termination until
537 // the interface has completed the registration.
538
539 if ( NETIF_FLAGS(netif) & kInterfaceFlagRegistering )
540 break;
541
542 // Remove the interface object. Don't worry, it is still retained.
543
544 removeInterface(netif);
545
546 // If interface was never registered with BSD, no additional
547 // action is required.
548
549 if ( (NETIF_FLAGS(netif) & kInterfaceFlagRegistered) == 0 )
550 break;
551
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.
555
556 thread_call_func( (thread_call_func_t) unregisterBSDInterface,
557 netif,
558 TRUE ); /* unique call desired */
559 }
560 while ( false );
561
562 unlockForArbitration();
563 }
564
565 return ret;
566 }
567
568 //---------------------------------------------------------------------------
569 // Detach an inactive interface that is currently registered with BSD.
570
571 void IONetworkStack::unregisterBSDInterface( IONetworkInterface * netif )
572 {
573 assert( netif );
574
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.
578
579 DLOG("%p\n", netif);
580
581 if ( dlil_if_detach(netif->getIfnet()) != DLIL_WAIT_FOR_FREE )
582 {
583 bsdInterfaceWasUnregistered( netif->getIfnet() );
584 }
585 }
586
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.
591
592 int IONetworkStack::bsdInterfaceWasUnregistered( struct ifnet * ifp )
593 {
594 IONetworkInterface * netif;
595
596 assert( ifp );
597
598 netif = (IONetworkInterface *) ifp->if_private;
599 DLOG("%p\n", netif);
600
601 assert( netif && gIONetworkStack );
602
603 // An interface was detached from DLIL. It is now safe to close the
604 // interface object.
605
606 gIONetworkStack->lockForArbitration();
607
608 assert( NETIF_FLAGS(netif) == kInterfaceFlagRegistered );
609
610 // Update state.
611
612 CLR_NETIF_FLAGS( netif, kInterfaceFlagRegistered );
613
614 // Drop interface from list of registered interfaces,
615 // and decrement interface retain count.
616
617 gIONetworkStack->removeRegisteredInterface(netif);
618
619 gIONetworkStack->unlockForArbitration();
620
621 // Make sure the interface is brought down before it is closed.
622
623 netif->setFlags( 0, IFF_UP ); // clear IFF_UP flag.
624 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, 0);
625
626 // Close interface and allow it to proceed with termination.
627
628 netif->close(gIONetworkStack);
629
630 return 0;
631 }
632
633 //---------------------------------------------------------------------------
634 // Pre-register a network interface. This function assumes that the
635 // caller is holding the arbitration lock.
636
637 bool IONetworkStack::preRegisterInterface( IONetworkInterface * netif,
638 const char * prefix,
639 UInt32 unit,
640 OSArray * array )
641 {
642 bool success = false;
643
644 DLOG("%p %s %d\n", netif, prefix ? prefix : "", unit);
645
646 assert( netif && array );
647
648 do {
649 if ( prefix == 0 ) break;
650
651 // Verify that the interface object given is known.
652
653 if ( containsInterface(netif) == false )
654 break;
655
656 // Interface must be in Active state.
657
658 if ( NETIF_FLAGS(netif) != kInterfaceFlagActive )
659 {
660 break;
661 }
662
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
666 // taken.
667
668 unit = getNextAvailableUnitNumber(prefix, unit);
669
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.
677
678 if ( netif->open(this) == false )
679 {
680 break;
681 }
682
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.
687
688 if ( ( netif->setUnitNumber(unit) == false ) ||
689 ( addRegisteredInterface(netif) == false ) )
690 {
691 netif->close(this);
692 break;
693 }
694
695 success = true;
696 }
697 while ( false );
698
699 if ( success )
700 {
701 // Mark the interface as in the process of registering.
702
703 SET_NETIF_FLAGS( netif, kInterfaceFlagRegistering );
704
705 // Add interface to pre-registration array.
706 // We assume the array has enough storage space for the new entry.
707
708 success = array->setObject( netif );
709 assert( success );
710 }
711
712 return success;
713 }
714
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.
718
719 void
720 IONetworkStack::completeRegistration( OSArray * array, bool isSync )
721 {
722 if ( isSync )
723 {
724 completeRegistrationUsingArray( array );
725 }
726 else
727 {
728 thread_call_func( (thread_call_func_t) completeRegistrationUsingArray,
729 array,
730 TRUE ); /* unique call desired */
731 }
732 }
733
734 void
735 IONetworkStack::completeRegistrationUsingArray( OSArray * array )
736 {
737 IONetworkInterface * netif;
738
739 assert( array );
740
741 for ( UInt32 i = 0; i < array->getCount(); i++ )
742 {
743 netif = (IONetworkInterface *) array->getObject(i);
744 assert( netif );
745
746 registerBSDInterface( netif );
747 }
748
749 array->release(); // consumes a ref count
750 }
751
752 //---------------------------------------------------------------------------
753 // Call DLIL functions to register the BSD interface.
754
755 void IONetworkStack::registerBSDInterface( IONetworkInterface * netif )
756 {
757 char ifname[20];
758 bool doTermination = false;
759
760 assert( netif );
761
762 // Attach the interface to DLIL.
763
764 bpfattach( netif->getIfnet(), DLT_EN10MB, sizeof(struct ether_header) );
765 ether_ifattach( netif->getIfnet() );
766
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.
770
771 sprintf(ifname, "%s%d", netif->getNamePrefix(), netif->getUnitNumber());
772 netif->setProperty(kIOBSDNameKey, ifname);
773
774 // Update state bits and detect for untimely interface termination.
775
776 gIONetworkStack->lockForArbitration();
777
778 assert( ( NETIF_FLAGS(netif) &
779 ( kInterfaceFlagRegistering | kInterfaceFlagRegistered ) ) ==
780 kInterfaceFlagRegistering );
781
782 CLR_NETIF_FLAGS( netif, kInterfaceFlagRegistering );
783 SET_NETIF_FLAGS( netif, kInterfaceFlagRegistered );
784
785 if ( ( NETIF_FLAGS(netif) & kInterfaceFlagActive ) == 0 )
786 {
787 doTermination = true;
788 }
789 else
790 {
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?
794
795 netif->registerService();
796 }
797
798 gIONetworkStack->unlockForArbitration();
799
800 // In the unlikely event that an interface was terminated before
801 // being registered, re-issue the termination message and tear it
802 // all down.
803
804 if ( doTermination )
805 {
806 gIONetworkStack->message(kIOMessageServiceIsTerminated, netif);
807 }
808 }
809
810 //---------------------------------------------------------------------------
811 // External/Public API - Register all interfaces.
812
813 IOReturn
814 IONetworkStack::registerAllInterfaces()
815 {
816 IONetworkInterface * netif;
817 const UInt32 unit = 0;
818 OSArray * array;
819
820 lockForArbitration();
821
822 // Allocate array to hold pre-registered interface objects.
823
824 array = OSArray::withCapacity( _ifSet->getCount() );
825 if ( array == 0 )
826 {
827 unlockForArbitration();
828 return kIOReturnNoMemory;
829 }
830
831 // Iterate through all interface objects.
832
833 for ( UInt32 index = 0; ( netif = getInterface(index) ); index++ )
834 {
835 // Interface must be Active and not yet registered.
836
837 if ( NETIF_FLAGS(netif) != kInterfaceFlagActive )
838 {
839 continue;
840 }
841
842 // Pre-register the interface.
843
844 preRegisterInterface( netif,
845 netif->getNamePrefix(),
846 unit,
847 array );
848 }
849
850 unlockForArbitration();
851
852 // Complete registration without holding the arbitration lock.
853
854 completeRegistration( array, true );
855
856 return kIOReturnSuccess;
857 }
858
859 //---------------------------------------------------------------------------
860 // External/Public API - Register primary interface.
861
862 IOReturn IONetworkStack::registerPrimaryInterface( bool enable )
863 {
864 IONetworkInterface * netif;
865 const UInt32 unit = 0;
866 OSArray * array;
867
868 lockForArbitration();
869
870 _registerPrimaryInterface = enable;
871
872 if ( _registerPrimaryInterface == false )
873 {
874 unlockForArbitration();
875 return kIOReturnSuccess;
876 }
877
878 // Allocate array to hold pre-registered interface objects.
879
880 array = OSArray::withCapacity( _ifSet->getCount() );
881 if ( array == 0 )
882 {
883 unlockForArbitration();
884 return kIOReturnNoMemory;
885 }
886
887 // Iterate through all interface objects.
888
889 for ( UInt32 index = 0; ( netif = getInterface(index) ); index++ )
890 {
891 const char * prefix = netif->getNamePrefix();
892
893 // Interface must be Active and not yet registered.
894
895 if ( NETIF_FLAGS(netif) != kInterfaceFlagActive )
896 {
897 continue;
898 }
899
900 // Primary only.
901
902 if ( netif->isPrimaryInterface() != true )
903 {
904 continue;
905 }
906
907 // If the unit slot is already taken, forget it.
908
909 if ( getRegisteredInterface( prefix, unit ) )
910 {
911 continue;
912 }
913
914 // Pre-register the interface.
915
916 preRegisterInterface( netif, prefix, unit, array );
917 }
918
919 unlockForArbitration();
920
921 // Complete registration without holding the arbitration lock.
922
923 completeRegistration( array, true );
924
925 return kIOReturnSuccess;
926 }
927
928 //---------------------------------------------------------------------------
929 // External/Public API - Register a single interface.
930
931 IOReturn IONetworkStack::registerInterface( IONetworkInterface * netif,
932 const char * prefix,
933 UInt32 unit,
934 bool isSync )
935 {
936 bool ret;
937 OSArray * array;
938
939 // Create pre-registration array.
940
941 array = OSArray::withCapacity( 1 );
942 if ( array == 0 )
943 {
944 return kIOReturnNoMemory;
945 }
946
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.
951
952 lockForArbitration();
953 ret = preRegisterInterface( netif, prefix, unit, array );
954 unlockForArbitration();
955
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.
959
960 completeRegistration( array, isSync );
961
962 return ret ? kIOReturnSuccess : kIOReturnError;
963 }
964
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
969 // a new interface.
970
971 SInt32 IONetworkStack::
972 orderRegisteredInterfaces( const OSMetaClassBase * obj1,
973 const OSMetaClassBase * obj2,
974 void * ref )
975 {
976 const IONetworkInterface * netif1 = (const IONetworkInterface *) obj1;
977 const IONetworkInterface * netif2 = (const IONetworkInterface *) obj2;
978
979 assert( netif1 && netif2 );
980
981 return ( netif2->getUnitNumber() - netif1->getUnitNumber() );
982 }
983
984 //---------------------------------------------------------------------------
985 // Create a user-client object to manage user space access.
986
987 IOReturn IONetworkStack::newUserClient( task_t owningTask,
988 void * /* security_id */,
989 UInt32 /* type */,
990 IOUserClient ** handler )
991 {
992 IOReturn err = kIOReturnSuccess;
993 IOUserClient * client;
994
995 client = IONetworkStackUserClient::withTask(owningTask);
996
997 if (!client || !client->attach(this) || !client->start(this))
998 {
999 if (client)
1000 {
1001 client->detach(this);
1002 client->release();
1003 client = 0;
1004 err = kIOReturnExclusiveAccess;
1005 }
1006 else
1007 {
1008 err = kIOReturnNoMemory;
1009 }
1010 }
1011
1012 *handler = client;
1013
1014 return err;
1015 }
1016
1017 //---------------------------------------------------------------------------
1018 // IONetworkStackUserClient implementation.
1019
1020 #undef super
1021 #define super IOUserClient
1022 OSDefineMetaClassAndStructors( IONetworkStackUserClient, IOUserClient )
1023
1024 IONetworkStackUserClient * IONetworkStackUserClient::withTask( task_t task )
1025 {
1026 IONetworkStackUserClient * me = new IONetworkStackUserClient;
1027
1028 if ( me && me->init() == false )
1029 {
1030 me->release();
1031 return 0;
1032 }
1033 return me;
1034 }
1035
1036 bool IONetworkStackUserClient::start( IOService * provider )
1037 {
1038 if ( super::start(provider) == false )
1039 return false;
1040
1041 if ( provider->open(this) == false )
1042 return false;
1043
1044 _provider = (IONetworkStack *) provider;
1045
1046 return true;
1047 }
1048
1049 IOReturn IONetworkStackUserClient::clientClose()
1050 {
1051 if (_provider)
1052 {
1053 _provider->close(this);
1054 detach(_provider);
1055 }
1056 return kIOReturnSuccess;
1057 }
1058
1059 IOReturn IONetworkStackUserClient::clientDied()
1060 {
1061 return clientClose();
1062 }
1063
1064 IOReturn IONetworkStackUserClient::setProperties( OSObject * properties )
1065 {
1066 IONetworkInterface * netif;
1067 OSDictionary * dict = OSDynamicCast(OSDictionary, properties);
1068 IOReturn ret = kIOReturnBadArgument;
1069 OSString * path = 0;
1070 OSNumber * unit;
1071 OSNumber * cmd;
1072
1073 do {
1074 // Sanity check.
1075
1076 if ( (_provider == 0) || (dict == 0) )
1077 break;
1078
1079 // Switch on the specified user command.
1080
1081 cmd = OSDynamicCast( OSNumber,
1082 dict->getObject( kIONetworkStackUserCommand ) );
1083 if ( cmd == 0 )
1084 break;
1085
1086 switch ( cmd->unsigned32BitValue() )
1087 {
1088 // Register one interface.
1089
1090 case kIORegisterOne:
1091 path = OSDynamicCast( OSString,
1092 dict->getObject( kIOPathMatchKey ));
1093 unit = OSDynamicCast( OSNumber,
1094 dict->getObject( kIOInterfaceUnit ));
1095
1096 if ( (path == 0) || (unit == 0) )
1097 {
1098 break;
1099 }
1100
1101 netif = OSDynamicCast( IONetworkInterface,
1102 IORegistryEntry::fromPath( path->getCStringNoCopy()) );
1103
1104 if ( netif == 0 ) break;
1105
1106 ret = _provider->registerInterface( netif,
1107 netif->getNamePrefix(),
1108 unit->unsigned32BitValue() );
1109
1110 netif->release(); // offset the retain by fromPath().
1111
1112 break;
1113
1114 // Register all interfaces.
1115
1116 case kIORegisterAll:
1117 ret = _provider->registerAllInterfaces();
1118 break;
1119 }
1120 }
1121 while ( false );
1122
1123 return ret;
1124 }