|
|
1.1 root 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 certain essential network stack services.
30: * Those services include attaching/detaching network interfaces, and
31: * interface naming. Note that although BSD network stack does not assign
32: * interface names, it is the responsibility of this object to manage the
33: * interface name space.
34: *
35: * IONetworkStack is a client of IONetworkInterface. This object uses the
36: * standard IOKit matching mechanism to discover and attach to interface
37: * objects. Each interface object is expected to have only a single
38: * IONetworkStack client. Under IOKit, the stack object initiates the
39: * action to attach to an interface. And subsequently, detaches from an
40: * interface when signaled to do so.
41: *
42: * The packet flow bypasses this object for efficiency sake. The interface
43: * object interact directly with the 'real' network stack to send and
44: * receive packets.
45: */
46:
47: #include <IOKit/assert.h>
48: #include <IOKit/IOLib.h>
49: #include <IOKit/IOBSD.h>
50: #include <IOKit/IOMessage.h>
51: #include <IOKit/network/IONetworkInterface.h>
52: #include <IOKit/network/IONetworkController.h>
53: #include "IONetworkStack.h"
54:
55: extern "C" {
56: #include <sys/param.h>
57: #include <sys/mbuf.h>
58: #include <sys/socket.h>
59: #include <net/bpf.h>
60: #include <net/if.h>
61: #include <netinet/if_ether.h>
62: }
63:
64: #define super IOService
65:
66: OSDefineMetaClassAndStructorsWithInit( IONetworkStack,
67: IOService,
68: IONetworkStack::initialize())
69:
70: #ifdef DEBUG
71: #define DLOG(fmt, args...) IOLog(fmt, ## args)
72: #else
73: #define DLOG
74: #endif
75:
76: // Maintain a linked list of network interfaces.
77: // Each time a new interface is added, an unit number is assigned,
78: // and an interface entry is added to the list. When the interface
79: // goes away, the entry is removed from the list and deallocated.
80: //
81: static queue_head_t netifTable;
82: static IOLock * netifTableLock;
83:
84: typedef struct {
85: IONetworkInterface * netif;
86: const char * name;
87: short unit;
88: queue_chain_t link;
89: } netifEntry;
90:
91: #define BSD_IFNET_ENTRY ((IONetworkInterface *) 0)
92: #define NETIF_LOCK IOTakeLock(netifTableLock)
93: #define NETIF_UNLOCK IOUnlock(netifTableLock)
94:
95: #define LOCK IOTakeLock(_lock);
96: #define UNLOCK IOUnlock(_lock);
97:
98: // --------------------------------------------------------------------------
99: //
100: // Add a new entry to the netifTable for the interface 'netif'.
101: // Return true if the entry was added successfully, otherwise
102: // returns false.
103: //
104: // The table lock must be held by the caller of this function.
105: //
106: static bool addNetworkInterfaceEntry(IONetworkInterface * netif,
107: const char * name,
108: short unit)
109: {
110: if (!netif || !name || (unit < 0)) return false;
111:
112: netifEntry * entry = (netifEntry *) IOMalloc(sizeof(netifEntry));
113: if (!entry)
114: return false;
115: bzero(entry, sizeof(*entry));
116:
117: entry->netif = netif;
118: entry->unit = unit;
119: entry->name = name;
120:
121: queue_enter(&netifTable, entry, netifEntry *, link);
122:
123: return true;
124: }
125:
126: // --------------------------------------------------------------------------
127: //
128: // Release the table entry occupied by the 'netif' instance.
129: // Returns true if an entry was found and removed, otherwise
130: // return false.
131: //
132: static bool releaseNetworkInterfaceEntry(IONetworkInterface * netif)
133: {
134: netifEntry * foundEntry = 0;
135:
136: if (!netif) return false;
137:
138: NETIF_LOCK;
139: if (!queue_empty(&netifTable)) {
140: netifEntry * entry;
141: queue_iterate(&netifTable, entry, netifEntry *, link) {
142: if (entry->netif == netif) {
143: foundEntry = entry;
144: break;
145: }
146: }
147: }
148: if (foundEntry) {
149: queue_remove(&netifTable, foundEntry, netifEntry *, link);
150: IOFree(foundEntry, sizeof(*foundEntry));
151: }
152: NETIF_UNLOCK;
153:
154: return (foundEntry ? true : false);
155: }
156:
157: // --------------------------------------------------------------------------
158: //
159: // Initialize the table, and preload it with any existing BSD network
160: // interfaces.
161: //
162: static void initNetifTable()
163: {
164: netifTableLock = IOLockAlloc();
165: assert(netifTableLock);
166:
167: IOLockInitWithState(netifTableLock, kIOLockStateUnlocked);
168:
169: queue_init(&netifTable);
170:
171: // Insert entries for all existing 'BSD' network interfaces into the
172: // netifTable. Hopefully only lo0 will be found.
173: //
174: #if 1 // FreeBSD 3.2
175: for (struct ifnet * ifp = ifnet.tqh_first;
176: ifp;
177: ifp = ifp->if_link.tqe_next)
178: addNetworkInterfaceEntry(BSD_IFNET_ENTRY, ifp->if_name, ifp->if_unit);
179: #else
180: for (struct ifnet * ifp = ifnet; ifp; ifp = ifp->if_next)
181: addNetworkInterfaceEntry(BSD_IFNET_ENTRY, ifp->if_name, ifp->if_unit);
182: #endif
183: }
184:
185: // --------------------------------------------------------------------------
186: //
187: // Add a entry for the interface object 'netif', with name prefix 'name'.
188: // The chosen unit number is returned in 'unit'. Returns true on success.
189: //
190: static bool reserveNetworkInterfaceEntry(IONetworkInterface * netif,
191: const char * name,
192: short * unit)
193: {
194: bool ret = true;
195: bool addEntry = true; // add new entry to list.
196: bool error = false;
197:
198: if (!netif || !name || !unit || (*unit < 0)) return false;
199:
200: NETIF_LOCK;
201:
202: if (!queue_empty(&netifTable)) {
203: bool rescan;
204: netifEntry * entry;
205:
206: do {
207: rescan = false;
208:
209: // Scan through the interface list and search for duplicates
210: // and conflicts. If a conflict is found, increment the unit
211: // number and rescan.
212: //
213: queue_iterate(&netifTable, entry, netifEntry *, link) {
214: if (entry->netif == netif) { // can't have duplicates
215: addEntry = false; // re-use existing entry
216: *unit = entry->unit;
217: break;
218: }
219: if ((entry->unit == *unit) && !strcmp(entry->name, name)) {
220: // name conflict detected.
221: if (++(*unit) > 0)
222: rescan = true;
223: else
224: error = true;
225: break;
226: }
227: }
228: } while (rescan);
229: }
230:
231: if (error)
232: ret = false;
233: else if (addEntry)
234: ret = addNetworkInterfaceEntry(netif, name, *unit);
235:
236: NETIF_UNLOCK;
237:
238: return ret;
239: }
240:
241: // --------------------------------------------------------------------------
242: //
243: // IONetworkStack class initializer.
244:
245: void IONetworkStack::initialize()
246: {
247: initNetifTable();
248: }
249:
250: // --------------------------------------------------------------------------
251: //
252: // init method.
253:
254: bool IONetworkStack::init(OSDictionary * properties)
255: {
256: _netif = 0; // IONetworkInterface instance (provider).
257: _ifp = 0; // ifnet struct for the interface.
258: _lock = 0; // big serialization lock.
259: _state = kIONetworkStackStateInit; // default state.
260:
261: if (!super::init())
262: return false;
263:
264: // Allocate a lock which will protect all accesses to this object.
265: //
266: _lock = IOLockAlloc();
267: if (!_lock)
268: return false;
269:
270: return true;
271: }
272:
273: // --------------------------------------------------------------------------
274: //
275: // probe. the score forces the probe and start in IONetworkStack to occur
276: // before the notification from IONetworkInterface is sent. We need to delay
277: // that until the network stack object has assigned a BSD name to the
278: // interface.
279:
280: IOService * IONetworkStack::probe(IOService * provider,
281: SInt32 * score)
282: {
283: if (!super::probe(provider, score))
284: return 0;
285:
286: // We are not picky about our provider, but it must be an
287: // IONetworkInterface instance.
288: //
289: IONetworkInterface * netif = OSDynamicCast(IONetworkInterface, provider);
290: if (!netif)
291: return 0;
292:
293: *score = 32; // must be larger than notification score.
294:
295: // Query interface for any requirements before qualifying the probe.
296: // For now, there is nothing that needs to be done. Return 'this' to
297: // indicate successful probe.
298:
299: return this;
300: }
301:
302: // --------------------------------------------------------------------------
303: //
304: // start method. We have attached to our provider, now start ourselve up.
305:
306: bool IONetworkStack::start(IOService * provider)
307: {
308: IONetworkInterface * netif = OSDynamicCast(IONetworkInterface, provider);
309: bool ret = false;
310: bool opened = false;
311:
312: if (!netif) return false;
313:
314: LOCK;
315:
316: do {
317: // Catch illegal state transitions.
318: //
319: if (_state != kIONetworkStackStateInit)
320: break;
321:
322: // Our provider must reveal its ifnet structure.
323: //
324: _netif = netif;
325: _ifp = _netif->getIfnet();
326: if (!_ifp || (_netif != (IONetworkInterface *) _ifp->if_private))
327: break;
328:
329: // Pass start() to our superclass.
330: //
331: if (!super::start(provider))
332: break;
333:
334: // Open our provider.
335: //
336: if (!_netif->open(this))
337: break;
338: opened = true;
339:
340: // Assign a name for the interface. Must do this before the
341: // if_attach() call. Remember to release the OSString object
342: // obtained through this call.
343: //
344: OSString * ifname = _assignInterfaceName(_netif);
345: if (!ifname) {
346: releaseNetworkInterfaceEntry(_netif);
347: break;
348: }
349: ifname->release();
350:
351: // When IONetworkStack gets probed, we assume that BSD is already
352: // up and running. So it is safe to call BSD to attach the network
353: // interface.
354: //
355: // FIXME: This will only work with Ethernet interfaces. Switch to
356: // new DLIL API once that is available.
357: //
358: _netif->lock();
359:
360: // Set the if_free() function pointer in the ifnet to point to our
361: // detachCallBack() static function.
362: //
363: // _ifp->if_free = detachCallBackHandler;
364: // _netif->_stack = this;
365:
366: #if 1 // FreeBSD 3.2
367: bpfattach(_ifp, DLT_EN10MB,sizeof(struct ether_header));
368: #else
369: bpfattach(&_ifp->if_bpf, _ifp, DLT_EN10MB,sizeof(struct ether_header));
370: #endif
371:
372: ether_ifattach(_ifp);
373:
374: _netif->unlock();
375:
376: // Network stack is now attached to the interface.
377: //
378: _state = kIONetworkStackStateAttached;
379:
380: ret = true;
381: }
382: while (0);
383:
384: if (!ret)
385: {
386: // start failed, undo any actions performed.
387: //
388: if (opened)
389: _netif->close(this);
390:
391: _netif = 0;
392: _ifp = 0;
393: }
394:
395: UNLOCK;
396:
397: return ret;
398: }
399:
400: // --------------------------------------------------------------------------
401: //
402: // stop method.
403:
404: void IONetworkStack::stop(IOService * provider)
405: {
406: LOCK;
407:
408: // Catch an illegal stop.
409: //
410: assert((_state == kIONetworkStackStateInit) ||
411: (_state == kIONetworkStackStateDetached));
412:
413: // Remove the interface from linked list.
414: //
415: if (_netif) {
416: assert(_netif == (IONetworkInterface *) provider);
417: releaseNetworkInterfaceEntry(_netif);
418: }
419:
420: _netif = 0;
421: _ifp = 0;
422: _state = kIONetworkStackStateInit;
423:
424: UNLOCK;
425:
426: super::stop(provider);
427: }
428:
429: // --------------------------------------------------------------------------
430: //
431: // sendIfDetachRequest
432: //
433: // Handle a detach request from our provider and signal to the network stack
434: // that the interface wishes to detach. The network stack will callback when
435: // the interface is allowed to proceed with the detach. There is no hard
436: // limit on how soon the callback will occur.
437: //
438: // Returns true if the request was handled. Otherwise, returns false.
439:
440: bool IONetworkStack::sendIfDetachRequest()
441: {
442: bool ret = false;
443:
444: DLOG("IONetworkStack::sendIfDetachRequest() called state = %d\n", _state);
445:
446: LOCK;
447:
448: if (_state == kIONetworkStackStateAttached) {
449:
450: // Send a detach request to the network stack and wait for
451: // a callback indicating detach operation complete.
452: //
453: // if_detach() is a new proposed DLIL call and does not exist yet.
454:
455: _state = kIONetworkStackStateDetaching;
456:
457: ret = true; // detach request handled.
458: }
459:
460: UNLOCK;
461:
462: return ret;
463: }
464:
465: // --------------------------------------------------------------------------
466: //
467: // ifDetachCallback method.
468:
469: void IONetworkStack::ifDetachCallback()
470: {
471: LOCK;
472:
473: if (_state == kIONetworkStackStateDetaching) {
474:
475: // We previously sent a detach request, the network stack is now
476: // calling back to indicate detach completion.
477: //
478: assert(_netif && _ifp);
479:
480: // Close our provider.
481: //
482: _netif->close(this);
483:
484: // Detach is now complete.
485: //
486: _state = kIONetworkStackStateDetached;
487: }
488: else {
489: DLOG("%s: Unexpected detach callback\n", getName());
490: }
491:
492: UNLOCK;
493: }
494:
495: // --------------------------------------------------------------------------
496: //
497: // This static member function is registered as the if_free() handler in
498: // the ifnet structure of our provider. The IONetworkStack instance is
499: // discovered and its ifFreeCallback() method is called.
500:
501: void IONetworkStack::ifDetachCallbackHandler(struct ifnet * ifp)
502: {
503: IONetworkInterface * netif;
504: IONetworkStack * stack;
505:
506: netif = OSDynamicCast(IONetworkInterface,
507: (IONetworkInterface *) ifp->if_private);
508: assert(netif);
509:
510: netif->lockForArbitration();
511:
512: stack = (IONetworkStack *) netif->_client;
513: if (stack)
514: stack->ifDetachCallback();
515: else
516: DLOG("IONetworkStack: No target for ifDetachCallback\n");
517:
518: netif->unlockForArbitration();
519: }
520:
521: // --------------------------------------------------------------------------
522: //
523: // Release allocated resources.
524:
525: void IONetworkStack::free()
526: {
527: assert(_state == kIONetworkStackStateInit);
528:
529: if (_lock)
530: IOLockFree(_lock);
531: }
532:
533: // --------------------------------------------------------------------------
534: //
535: // Facility provided by IOService for general purpose provider-to-client
536: // notification. We catch the kIOMessageServiceIsTerminated message.
537:
538: IOReturn IONetworkStack::message(UInt32 type, IOService * provider,
539: void * argument = 0)
540: {
541: // Our provider has gone into an inactive state, we should begin the
542: // tear-down process by signalling the network stack to unregister
543: // and detach the network interface.
544: //
545: // We do not look at the argument, which contains the options given
546: // to the terminate() method.
547: //
548: if (type == kIOMessageServiceIsTerminated) {
549: sendIfDetachRequest();
550: return kIOReturnSuccess;
551: }
552:
553: return kIOReturnUnsupported;
554: }
555:
556: // --------------------------------------------------------------------------
557: //
558: // Assign a BSD friendly name to the network interface. The interface
559: // object has to assist in this process by returning its name prefix,
560: // i.e. "en". This routine will pick an unit number that does not
561: // conflict with any existing interface.
562:
563: OSString * IONetworkStack::_assignInterfaceName(IONetworkInterface * netif)
564: {
565: SInt16 unit = 0;
566: UInt32 index = 0;
567: const char * namePrefix = netif->getNamePrefix();
568: char nameBuf[40];
569: OSString * nameString;
570: IONetworkController * ctlr = OSDynamicCast(IONetworkController,
571: netif->getProvider());
572:
573: if (!ctlr || !namePrefix || !*namePrefix)
574: return 0;
575:
576: // First, we need to determine the initial interface unit number.
577: // The current scheme needs a lot of work. Currently, motherboard
578: // devices gets unit 0, while add-on PCI cards are assigned
579: // unit 1 and up. Here, we need to determine whether this is an
580: // onboard or a PCI network controller.
581: //
582: if (ctlr->getProvider()) {
583: OSObject * propObject = ctlr->getProvider()->getProperty("built-in");
584:
585: if (!propObject) {
586: propObject = ctlr->getProvider()->getProperty("AAPL,slot-name");
587: if (propObject) {
588: unit = 1; // PCI add-on card
589:
590: // If we have an index number, increment
591: // the unit by the index number.
592: // (for multiport PCI cards).
593: ctlr->doGetControllerIndex(this, &index);
594: unit += index;
595: }
596: }
597: }
598:
599: // "unit" is now the initial unit number requested by the interface.
600: // If this unit number is already taken by an existing interface, we
601: // will automatically increment the unit number until there are no
602: // conflicts. We don't want to confuse BSD with identical names.
603: //
604: // Now try to reserve the chosen name.
605: //
606: if (!reserveNetworkInterfaceEntry(netif, namePrefix, &unit))
607: return 0;
608:
609: // Update the interface object with its assigned name.
610: //
611: sprintf(nameBuf, "%s%d", namePrefix, unit);
612: nameString = OSString::withCString(nameBuf);
613: if (nameString) {
614: //
615: // Now fill in the ifnet name fields.
616: //
617: netif->setInterfaceNameInt(namePrefix);
618: netif->setUnitNumberInt(unit);
619:
620: // Set the interface's kIOBSDName property.
621: //
622: netif->setProperty(kIOBSDName, nameString);
623: }
624:
625: return nameString;
626: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.