Core OS • 50:03
The Mach kernel is evolving, and the Kernel APIs (KPIs) will become better defined and more modular, meaning more stability for your code and less need for changes over time. This session discusses the introduction and staging of this evolution, and developers of kernel extensions should view to learn the timing, and how to take advantage, of these changes.
Speakers: Craig Keithley, Simon Patience, Dean Reece, Mark Gorlinsky, Josh Graessley
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Good morning, and welcome to the Kernel Programming Interfaces for Extension sessions. I'm Craig Keithley. I'm the I/O Technology Evangelist in Apple's Worldwide Developer Relations Group. As the I/O Technology Evangelist, I work with a lot of Kecks developers, and over the past couple of years, we've faced some challenges with regard to making sure that we have a set of consistent APIs that will remain useful through the life of a product. So we've now looked at providing what's known as KPIs, or Kernel Programming Interfaces. To talk about that, Simon Patience, Director of Engineering.
Good morning. So let's briefly describe what's going to be covered today. First of all, we'll go through a definition of rationale of kernel interfaces, and where we're gonna be taking them over the course of the next year or so. We'll be looking at how we're going to be managing the version progressions as we evolve them. We'll have a look at the effects on I/O Kit. We'll cover general kernel interfaces and the file system interfaces. Then we'll have a look at some networking interfaces for kernel extensions, and then we'll sum up, and then Q&A.
So KPI's, so what are they? Well, obviously kernel programming interfaces, there's obviously a relationship between those and API's, just in the same way that in libraries there's a whole lot of functions, but you don't actually get to program to them all. We're using that kind of analogy here for the kernel. The sets of well-defined interfaces are bounded, as I mentioned. They cover both functions that the kernel provides, but also the rules by which you can access data.
The sets are versioned. As we move through time, we will be evolving these interfaces. Some will be changing, some will be being added. And the reasons that they're versioned is because they really reflect the implementation rather than the interface as the system moves on. And we want to have a well-defined lifecycle so that you know what's coming and what to We're currently targeting specific classes of kernel extensions. We will be adding new classes as there is demand, and as we can identify what the correct interfaces for those will be.
So let's have a look at one of the motivating factors that we have for putting in kernel interfaces, which is what we could describe as the Keck dependency problem. So here's a picture of the OS X kernel. There's a picture of your KEXT. As you load it, let's say it's a networking KEXT.
There's a set of interfaces which we can clearly see you're dependent on, because those are the unresolved symbols in your KEXT. The big problem for us is that we have no idea, especially if you're going through data, what these additional implicit dependencies are, and so we cannot define what the compatibility points are that your KEXT is depending on.
So, why do we need these kernel interfaces? Well, as I just mentioned, KEX have no explicit dependencies, not a total set of explicit dependencies. We cannot work out exactly what it is that we can't change. And OS X needs to evolve. There's a whole set of reasons why we need to change the kernel. We have new features that we're coming in to provide a better user experience. We have performance improvements that we need to do.
There are bug fixes, obviously. We try to limit the number of bugs that we have in the system, but they do occur from time to time, and we need to be able to fix those in ways that don't break binary compatibility for KEX. Clearly, there's new hardware, such as the hardware that was announced today, this week. I mean, that takes a certain amount of change in the kernel, and has ramifications on KEX, if there are no boundaries.
And, SMP support. The funnels are well-known within the system, and we need to do something about them to get better SMP performance. And so, without these interfaces, this really makes change within the kernel very difficult to achieve. So, these interfaces define what I like to call our innovation sandbox.
So why would developers want kernel interfaces? Well, first of all, it means that we can have a set of interfaces that are best suited for your needs. We can design them such that they perform the functions that you're trying to achieve in the most efficient manner. We can improve the stability of the environment, and we can provide binary compatibility from release to release for these interfaces. and they've significantly reduced the chance of us changing things that unbeknownst to us is breaking your KEXT, because we can now test those interfaces and ensure that they are semantically and syntactically equivalent from release to release.
So we have a number of states, just to let you know exactly where the status of this interface is. We have defined four states. The stable interface, these are basically the things that you've seen in the kernel, and the general stuff, all the libc functions, for example, stuff like that. They're not going away, and they're guaranteed to be in the next major release, and so you can rely on those in your products.
Compatibility interfaces are basically the same as stable interfaces in terms of their longevity. The difference is the fact that we're trying to mark them specially because they are there for porting from one system to another, and they may not necessarily be the most efficient interface to use. So we don't want to mix them in with the stable interfaces. We want to indicate which ones are the ones that you should really be going towards. When we decide that an interface has to change or go away for various implementation reasons, then we'll mark it as being deprecated.
This means that the interface is going to be removed or is planned to be removed in the following major release. And finally, we have another set, which is called evolving. What is evolving? These interfaces are under development, and normally under development with you. This is in order to be able to support new kinds of KEX that we don't really know what the right interface is, and we would like to work with you in order to be able to develop the best set of interfaces, both for your purposes and for ours.
So when are we going to be doing this? Well, the draft specification for these interfaces is available now. We'll be giving you information about how to get hold of them later on. This is really just the interface specifications. The implementation for those will be coming in the Panther timeframe.
And during Panther, as the system evolves in the Panther updates, we'll be also evolving these interfaces and the implementations of them, so that you can track them to see how we're adding to them and evolving them so that they become something that we can actually make stable and say that we can live behind.
The first set of stable interfaces will be declared with enough time before Panther, so that you can actually port to them and make sure that you are in a stable place by the time the next release comes out, the post-Panther major release comes out, where we will start to enforce these interfaces. And with that, I'd like to hand over to Dean Reece, who's the Engineering Manager of the I/O Kit team, who will talk about how we're going to manage the versions of these interfaces.
Thanks Simon, good morning. I'm going to be talking a bit about the KEXT system and how we're going to manage the KPIs that Simon just talked about. So let's get right into it. For Panther, the KEXT tools have not really changed. As you recall, for Jaguar, we totally revved the entire set of kernel extension management and development tools.
Pretty much got them where we wanted them to be, so for Panther, we didn't really change them. We have, however, added some new capabilities to support the kernel programming interfaces. Basically, we've created a new type of KEXT. It's not something that you're going to be needing to use directly. We're going to provide them. You'll link against them. It'll be pretty much transparent, and I'm going to talk about that in the next few slides.
But the fundamental change that you'll notice, and again, it shouldn't really cause any code changes for you, is that right now, your KEXTs link directly against the kernel. And in Panther and beyond, they will link indirectly against the kernel. I've got some diagrams to show how that works. works.
So in Jaguar, if you list a dependency for your text on any of these CFBundle identifiers here listed in blue, then you're saying that you need the kernel. And because of the way that we did the linking for kernel extensions, if you said you needed something from BSD, then you actually got the entire set of kernel symbols.
So you could have a dependency over an I/O Kit that you didn't actually declare, and it would actually work. But the linking would succeed because you were getting the whole kernel and all the symbols in it. Obviously, as we're trying to move towards an enforced interface design, we can't have this. We have to have a little bit more partitioning between the different programming interfaces.
For all versions prior to 7.0, this is true. If you link against one of these, you get all of them for free. This is what it looks like, sort of in a pictorial form. Basically, all of the sub-identifiers for the kernel represented the whole kernel, and no matter which one you linked on, you got the whole kernel.
So in Panther, we're going to provide binary compatibility through a set of interface keks, the new type of keks I talked about. And basically all they contain is a set of symbols. They're basically re-exporting the symbols from the kernel. But they only export the set of symbols that you should be using for whatever version you wanted.
Basically what we're doing is taking all of the symbols that shipped in, all the versions of Jaguar, for all of the com.apple.kernel bundle identifiers, and we're putting them together in one big interface KEXT. And if you list a dependency on one of those, a version prior to 7.0, then you're going to get that interface KEXT, and you'll get all the symbols that you got before, modulo a few that we had to take out to support the new G5 hardware. Basically, you're going to get exactly what you got before. It should just come up and work.
Yeah, let's move on and look at a picture of how this looks. So, in this case, your KEXT in orange there is linking against the BSD interface KEXT, which supports compatibility, everything from version 1.1 up through version 6.0. Actually, I think we've made that up through 6.9, just to give us some leeway there. And that, in turn, links against the actual kernel, the actual running kernel, and that sort of provides the filter to give you the correct set of symbols for the version that you've asked for.
So we're also going to provide a new set of kernel interface KEXTs for Panther. These are going to be version number seven. So they're going to contain all the symbols that we believe we should support carrying forward. We're going to remove a large number of symbols that are sort of internal support functions that really shouldn't have ever been exported in the first place.
And we're also going to add the new functionality that we've introduced in Panther there. So basically, if you've got a kernel extension that you've been shipping, it'll continue to run in link in Panther because it'll link against the older version one through version six compatibility interface KEXTs. And if you've got a brand new kernel extension that needs to take advantage of new functionality, then you use the new set. Okay, and this picture looks exactly like the picture before, the only thing that's changed is the version numbers. You'll see everything across the board is 7.0.
Now, we still provide a capability in Panther that we provided in Jaguar, and that is you can still link directly against the kernel. It's necessary, in fact, as an implementation detail. Our interface keks link directly against the kernel, and they actually play by the same rules that your keks do. So, if you select com.apple.kernel as the dependency, you will still get all of the symbols exported by the kernel.
Now, we don't guarantee any release-to-release compatibility with the global set of symbol kernels, because we can't, as Simon said, unless we have some enforcement and partitioning here, we can't guarantee you compatibility, because we can't know what exactly you've used out of that large mass of interfaces. So, what we do, every time we ship a new kernel, it gets a new version number, as it should. And if you list a dependency on the kernel, you must list a dependency on an exact version of the kernel.
The implication being that the next time we ship a software update with a new kernel in it, your kernel extension will not load on that version of the OS, or the next major version as well. So, this is really not a good way to ship product. It's useful in, say with open source projects, where you're shipping source code, and the client can recompile for whatever version of the OS they want to use, or maybe in educational institutions where you're working on a particular OS for a class.
But, I thought I would point it out, it is still a possibility, it just isn't something you would really want to do as part of a product. and that's what that looks like. Basically you're bypassing all of the compatibility interfaces, and you're linking straight against the kernel. And again here you'll notice the dependency version listed in the KEXT is identical to the version of the kernel listed, otherwise the linkage would fail.
So what does this mean going beyond Panther? Well, basically you'll continue to use the same rules you used today. We're introducing a new namespace, actually not a new namespace, a new naming convention within the existing CFBundle Identifier namespace that we already use. And that is com.apple.kpi. You'll see this in the Panther seed CD that we've given out this week, and you'll see it more going forward. So com.apple.kernel will still be around, and will represent the compatibility interfaces. com.apple.kpi will be used going forward to present the new supportable interfaces, and the two will coexist on the system as much as possible.
We'll also use this mechanism to make experimental interfaces available to you, as we, over the life of Panther, deliver newer updates to our KPI package. We'll deliver that, and that will introduce new interface kecks to your system, possibly a new kernel as well for the implementation behind them, but that'll partition them off from the compatibility interfaces, because, again, the version numbers kind of separate them into past and future.
Obviously, and again as Simon said, as the kernel evolves, we're going to need to deprecate APIs, particularly initially as we start to thin that set down to the ones that we really can support. KPIs allows us to do this because we can have a version set that we maintain as long as possible, and then whenever point in time it becomes impossible for us to continue to support that, we can remove them, and it won't affect anybody who's dependent on a different interface or a different version of that interface. It will only affect the people needing the old version of that particular interface.
So it really provides us a sliding window, or what I like to view it as sort of a conveyor belt that's some length long, and we introduce an interface, and we can support it pretty much as long as we want to, but eventually we may have to move off of it as we evolve the kernel.
Alright, so I'm also going to talk a little bit this morning, put on my I/O Kit manager hat, and talk about how this Panther release introduces new things for I/O Kit. So the good news is, the I/O Kit in Panther is binary compatible with what we shipped in Jaguar.
So the V6 versions of the interfaces that we ship will continue to load your I/O Kit keks from Jaguar on Panther, and they should work. Obviously there's always a potential for bugs. This is what you need to do, is take the seed that we've given you, try it out with your products, make sure that they work. Let us know if they don't. But the expectation is that properly written kernel extensions for I/O kits should continue to load and run on Panther.
We've also introduced a few new interfaces for Panther. Those are only available in the V7 interface. Again, a kex needing V6 shouldn't need those interfaces. And we've also deprecated a few interfaces. I think they've actually been marked in the header files for a couple years now as going to be deprecated. Well, now we have a mechanism to actually deprecate them, so we're making use of that.
Alright, so the V7 interface that we provide in Panther for I/O Kit, it has a number of changes to I/O Memory Descriptor. As you can imagine, being able to address greater than 4 GB of memory has some implications for the way drivers deal with physical memory. So, if you've used the abstractions for I/O Memory Descriptor correctly, you should not have any problem with your driver continuing to work on those machines and addressing large memory.
If you've gone directly to the PMAP functions or other workarounds, so that you've avoided Memory Descriptor, then you probably won't work on those machines. So, you need to use Memory Descriptor. We've added some convenience functions listed down here: I/O Mapped Read 8, 16, 32, 64. Basically, these allow you to do direct I/O to your hardware without generating, having to create new Memory Descriptors just for your registers.
We've also removed a few from Panther V7, from I/O Kit. These are two classes, I think there's another one on the list. This is not a final list, obviously, as Panther is not yet final. But I/O Command Queue and I/O Sync are two classes that were introduced very early on in I/O Kit, and were realized as not supportable long term, and I think they've been marked as deprecated for quite a while.
Hopefully this shouldn't affect any of you, but again, they will be present in the kernel, but they'll only be available for linking if you have a V6 dependency. They'll just be absent from the V7 dependency. So with that, I would like to introduce Mark Gorlinsky, the manager of the kernel team at Apple. And take it away, Mark.
Thank you for bringing my script with me. So as a kernel manager, it's my job to improve the Mac OS X kernel and maintain the stability, scalability, and performance without breaking binary compatibility. Today we expose all the kernel interfaces, and so every bug fix we make, every feature we add, we risk the opportunity, or we have the opportunity to break binary compatibility. So we needed a way to evolve the Mac OS X kernel without breakage.
So, we need to move forward. Today we used two funnels to address the scalability of the MACWIS10 kernel, but funnel contention has led to a performance impact of MP systems. To address this, we're moving beyond the funnels. We're going to be making the VSD kernel thread-safe and implementing fine-grain locking.
We will also be making extensive changes to the kernel data structures, which includes adding reference and usage counts. So kernel data structures are going opaque, and they'll be accessible only through data accessors, functional routines, and convenience APIs. We will also be exposing locking protocols of the data structures, where it leads to efficiency, but otherwise we will be hiding the locking details behind the interface. All new interfaces will be MP safe. This includes data accessors, functional routines, as well as convenience APIs.
Today the file system block numbers are 32 bits. As we move forward, they're going to be going to 64 bit. This is important for large file system volumes. Also, it will have an impact on all interfaces that use block numbers. File system vnode operations are currently not symmetric with respect to vnode locking and reference counting.
This makes the job of providing efficient stackable file systems very difficult. For example, operations such as vopclose and vopgetatter are entered without locks being held, vnode locks. Moving forward, all vnode locking will be symmetric. There are also many common functions in the VFS layer that the VFS layer should have, that are currently replicated by all the file systems.
To address this, we are moving some of this functionality into the VFS layer. For example, functionality like NFS export, device alias checks, will be moving into this area, this layer. Keep in mind that the goal of these interfaces is to allow the Mac OS X kernel to evolve without breakage.
When we started this, we took a look at our own kernel interfaces, we looked at our shipping file system drivers and networking extensions. We determined that drivers and ILCit based extensions were in good shape, so we decided to first address BSD file systems and network extensions, and we'll address other extensions later. We considered only providing interfaces that were reliable, scalable, and could be implemented without affecting compatibility of the extensions. This is our first round of iterating on these interfaces. We are expecting them to evolve, and we look forward to your feedback.
Okay, this diagram gives you a perspective as to where file system extensions reside in the kernel. As you can see, file system operations are dispatched through the VFS layer as a set of VFS and VNode Operations. Let's look at what other interfaces they may use. Okay, so like I said, they are implemented as VFS and VNodeOps.
They also use Common C functions and Kernel Support functions, which every kernel extension can use. They also utilize functions that the BSD kernel extensions would use, such as credentials for authentication and process APIs. They also utilize file system specific interfaces for file data caching, such as Buffer Cache and UBC. Let's take a look at C functions here. Thank you.
Okay, so the kernel provides a subset of standard C functions, such as string and memory manipulation. As a kernel extension developer, you should be aware that these functions are not as fully featured as their user layer libc counterparts. Also, there's really no change that's any significance here. Kernel extensions will continue to have access to all the standard C functions that exist today.
Additionally, there are kernel support interfaces, That provide access to resource management and thread control, as well as memory management routines such as malloc and free, synchronization routines like sleep and wake up, routines to provide locking using simple locks and mutexes, which can be used by kernel extensions to protect their data.
There are also routines to do thread call out, routines for data copy like copy in, copy out, which will be changing to support 64-bit addresses. So far, the interfaces we've discussed are relatively gone on change, with the exception of 64-bit address support. However, as you'll see from this point on, you'll see a significant change in the interfaces.
Many kernel extension use routines that are considered BSD kernel interfaces, We are providing interfaces for authentication and process limits and process IDs. For example, for a given process ID, you can signal the process or you can get a handle to the process, but you should now be aware that this handle is opaque and does not point to the process struct directly.
and it comes with a reference count that will have to be dropped later. Also we are moving towards thread based credentials. These credentials, the credentials that are processed, enters the syscall with, you know, the thread enters the syscall actually, will be stored in a thread local data area, so it can be accessed quickly without contention. We will also be providing interfaces to obtain a reference V node or socket through a file descriptor, we will consider adding other interfaces to things like file ops and TTYs sometime in the future. If you need access to something that is not covered, send us your feedback.
However, some interfaces, we chose not to provide interfaces at risk stability and that are not sustainable. For example, direct access to the system call table is not going to be provided. In these cases, you will have to work with us, possibly find alternative mechanisms or work with us so we can provide you with a sustainable and stable mechanism.
File Caching These interfaces are mostly used by file system kernel extensions to do caching of meta and file data. Both structbuf and ubcinfo are going opaque. All data structures are going opaque. For buffer cache, we have left the semantics and usage the same, but we have implemented new interfaces to use 64-bit block numbers. For example, getblock is now called buff_getblock, and it takes a 64-bit block number. We have also left the semantics of UBC the same, except for the UBC macros, such as UBC is invalid, are now actually functions.
Otherwise, we have maintained the same API, but remember, these structures are now opaque. So, another example would be bwrite. Instead of taking a struct buff, it now takes a buff t. Throughout all our efforts, we've tried to maintain the familiarity of the subsystem. We didn't want you to have to learn all new interfaces. But we had to make changes to support the opaqueness of the data structures and for locking and reference counting. If there's an interface, again, that we missed, send us your feedback.
Okay. VFS Ops. VFS operations are already a set of well-defined routines to manipulate individual volumes through a mount structure. However, the mount structure is now opaque, and is called mount_t, mount_t. This is the data type every VFS operation will receive. We are now providing new accessors, accessor functions to the mount structure.
For example, instead of testing mount_rd only in the mount flags, you would now use VFS is_rd only to check the file system is mounted read only. All mount flags that are visible directly to user level will be exposed. Additional functions will cover access to other kernel mount flags. Oop, I need to go back.
We have also added interfaces like VFS Iterate to provide access to VNodes on a given mount. These are done in an MP Safe way. We have renamed and modified the StataFS structure. It is now called VFS StataFS. We have changed the block number fields to 64-bit, so we can support large file system volumes. We have expanded the path names to max_path_length to address localization issues. We have created a new I/O attribute structure called VFS I/O Atter.
Again, this is the structure that contains IO attributes associated with the map point, but we have added some new New information about the device capabilities such as how many bytes the device can actually read and write at one time. There are also new interfaces to get and set these structures within the mount structure. Also, we've added some new VFS operations to support dynamic growth of a file system. They are VFS Extend and VFS Truncate. We have added VFS Uninit to complement VFS Init.
We moved them both to file system registration instead of VFS op. We have untangled VFS mount operations and defined new VFS ops for update and reload. This was done to keep the logic and code clean and uncomplicated. VFS operations are defined by a structure with various function pointers. We are changing this to be similar to the way that VNode ops are done. We will make VFF ops extensible so that we don't have to worry about breakage when we add new VFS ops.
Okay, VNode Ops, VNode operations are a set of well-defined routines to manipulate individual files through a VNode structure. Again, As in all the data structures, VNode structure is now opaque and is called VNodeT. This will be the data type all VNode operations will receive. and we are also providing new accessor functions for this structure. We are making VNode operations symmetric with respect to VNode locking, and this does have an impact on We have also modified the VNode locks with respect to how you manage your VNode locks.
We wanted to empower the file systems to enforce the locking their way, so now file systems don't have to use the same locking rules that VFS used to be enforcing. So if a file system wants to provide multi-reader, single writer locks, they will be able to do so without having every file system support the locking semantics. We have also modified the sequence of events to create a VNode. Instead of calling get new VNode, and then associating the relevant data and so on to the VNode structure, You can now call vnode create, which passes in all the relevant information in one call.
and others. The main thing is to make sure that the kernel is fully structured and has complete information. In this way we avoid having to use too many accessors to set all this up. The side effect is you have the ability to manage your own inode pool without tying it to the vnode pool.
We are adding new functionality to suspend and resume a VNode and a mounted file system. This can be used to acquiesce an entire file system, so we can make on-disk manipulation changes. Finally, there's a new VADDR structure that's been updated to support 64-bit blocks called VNode VADDRT. And I just want to close with saying that, again, we are iterating on these interfaces, and your feedback is going to be very important to us. Otherwise, We consider the interfaces not complete if you don't give us your feedback. You get to help determine our future and your own future as to where these interfaces go. That's it. I'd like to introduce Josh Graessley, who will be doing Network Extensions.
Hi, I'm going to be telling you about the network kernel programming interfaces that we've been working on. We have six interfaces we've been planning. The mbuf socket, socket filter, IP filter, interface filter, and interface. And here's a diagram of the networking stack. So at the top we have the sockets, and between the sockets and the protocols we have socket filters. And attached to IP we have IP filters. and down at the bottom we have interfaces with interface filters attached to those. All of the items in purple will be, kernel extensions can supply to the stack.
So, as a engineer that's been working on the stack for quite a while, I spend a lot of time tracking down bugs, and I quite often run into a bug that has a simple fix, but the simple fix would end up breaking a kernel extension. So we end up with some pretty innovative fixes in the kernel, which we're getting a little... we'd like to do better. So one of our goals is to make all of the data structures opaque, so we can extend them when we need to.
We're going to change a lot of the filters to be based on operations instead of implementation. As much of the implementation as we can hide from you, the better off we are, because that lets us change it. We'll modify a lot of the fun-- The new APIs return errors more often than the old ones did.
So, for example, instead of-- When you call mclget, instead of checking a flag to determine whether or not the call succeeded, the call will just return an error if it didn't work. We're also looking at additional interface sets. We're looking at adding support for new interface families, as well as new protocols.
First KPI is the mbuf KPI. All of the packets in the networking stack are stored in mbufs. The mbuf structure used to be visible to kernel extensions, but we're making a change. The mbuf will be opaque, and it will be referenced with an mbuf_t. You'll be provided accessor functions for allocating and manipulating mbufs, as well as inspecting them and getting to the data that they contain.
The naming of the new functions will be consistent with the old functions, so it should be pretty simple to port most of your code. For example, mtd becomes mbuf_mtd, and m_freem becomes mbuf_freem. Most of the functions will return errors now. MCL_GET is a great example of that. It should make the code a little bit less error prone.
Again, we have the network diagram, the diagram of the stack, and at the top we have the sockets, and we will be providing a socket interface, or socket KPI to kernel extensions, so they can make use of sockets within the kernel. Common use of this would be a network file system.
The socket KPI will be provided so they can perform all of their network operations using this. The KPI is based on the user space APIs. To create a socket, the kernel extension uses sock underscore socket. To bind to a specific address and port, it uses sock underscore bind.
The socket and proto-SW structures will now be opaque. You will have no direct access to these structures, and the protocol control block will also be hidden. So you'll need to use things such as get_sock_name, get_peer_name, and get_sock_opt to get access to the information that's stored in the protocol control blocks.
Between the sockets and the protocols, we have socket filters. Socket filters have been completely rewritten. They are now based on the operations, instead of the implementation. It lets you filter data and commands at the socket layer. You'll be able to receive notification of changes, of state changes to the socket. For example, you'll get a state change notification when the socket goes from the connecting state to the connected state. You'll no longer be able to intercept or prevent these changes.
We also allow you to specify inbound and outbound data filters. The inbound data filter will pass data to you, no matter how it comes in. In the past, you used to have to filter SBAppend, SBAppend data, SBAppend control, and a wide variety of similar things. And there were some other problems with that.
If you're filtering inbound data and TCP input called SBAppend to put the data in the socket buffer, When, if your kernel extension held onto the data, so that it could later re-inject it, and it returned, you just return, SBA pin didn't actually have any semantics to let the caller know whether or not there was data appended to the socket buffer. So, TCP would go ahead and wake up the, and the client who was waiting on the socket. The client would read, get 0 bytes read, and it would think it was an end of file and erroneously close the socket, which would lead to lots of strange problems.
So we have inbound and outbound data filters that should just work, and make things a lot simpler. We also have inbound and outbound connection filters. So your inbound connection filter is past the address that the connection is coming in from, and you'll have an opportunity to refuse that.
In the case of TCP, we'll actually send a reset, if you refuse the connection. So you could potentially build a firewall using these filters at the socket layer, instead of doing it at the packet layer. We can also filter outbound connections, so you can enforce stricter security. You can also filter on binds and get and set socket options, as well as listen and di-octal.
Moving down the stack a little bit, attached to the IP protocol, we have IP filters. The IP filters give you a place to filter packets at the IP layer, it's brand new. You can filter inbound and outbound packets, and on the inbound side, you get the packet after it's been reassembled, and after all of the media specific headers have been stripped off. You also get to filter both before and after IPSec processing has occurred. So if the packets are encrypted and authenticated, you'll get to see it both when it's encrypted and after it's been decrypted. And you'll get to see any credentials or any authentication that's occurred.
On the outbound side, you'll get to filter before the packet's been fragmented, and before Before we apply the IPSec processing, this will let you modify the data before it gets encrypted and authenticated, and inspect it before it's encrypted and won't mean anything to you anymore. The filters can be attached to IPv4 as well as IPv6.
and moving down the stack further, attached to the interfaces we have interface filters that let you filter packets at the interface layer. The Network Interface Filter KPI provides kernel extensions the ability to attach these filters to interfaces. The interface filters are based on the DLL interface filters, the difference being that the types are all opaque. You'll be able to filter inbound and outbound packets on an interface, as well as iOctyls to an interface, and events coming from an interface.
and at the bottom of the networking stack, we have the interfaces themselves. The Network Interface KPI provides a number of things you can do with the interfaces. The interface is used to be represented by IFNET structures. The IFNET structure will now be opaque, and you will get a reference to it. The structure is reference counted, and will provide accessors for inspecting various properties of the interface, as well as sending packets, and performing I-Octols, and other various operations.
We'll also give you functions for getting a list of interfaces, and finding a specific interface. You'll also have the ability to retrieve a list of addresses that are attached to the interface, as well as multicast addresses, and you'll be able to join and leave multicasts. You'll also be able to add an interface, but you'll only be able to add an interface that belongs to an existing interface family, such as Ethernet, PPP, and FireWire. And with that, I'd like to bring Simon up for a summary.
So, obviously we can't go into huge amounts of detail in the amount of time that we've had available, but I hope that's given you an indication of the direction that we're going. So to summarize, the reason that we're doing this is numerous actually, it's to allow Apple to innovate in the kernel, to take the OS X kernel into the future where the new hardware and the new configurations are waiting and the new functionality is waiting for us. It allows us to improve the quality of the kernel. As was mentioned a couple of times, there have been bug fixes where we've actually found it difficult to fix without breaking compatibility, and somewhere it's actually been impossible.
It allows developers to write keks more easily. You now don't have 100,000 interfaces to choose from, many of which will be the wrong ones, which you may not know at the time. So now the programming interface becomes a lot more clear as to exactly how you can develop your keks.
We can provide some future proofing for you. We guarantee the compatibility of an interface from release to release. We actually have a much greater chance of ensuring that that's correct as we move forward, because assuring the 100,000 interfaces that are currently in the kernel, including all the data usage models that there may be, is almost an impossible job.
With this, because of the state transitions of interfaces, we can provide a much more predictable rate of change for developers. We can guarantee that interfaces will exist from one release to another. We understand the contract, and you understand the contract, so we can give you a much more predictable environment.
We also believe that this will provide a better user experience for when kecks become out of date, and things do go wrong. At the moment, probably what will happen is that the kecks will be loaded, and then sometime later the kernel will crash, because there's some incompatibility of data usage between the kernel and your kecks. So now it becomes much more apparent, we actually catch it at load time, that something has changed, and this kecks is no longer available to be used on this particular rev of the system.
The other big thing is that they start today. Well, actually, perhaps not quite today, because we don't have the interfaces actually available on the web yet. However, we will be getting them onto the developer website very soon, where you can download the draft interface specifications. You should look at developer.apple.com, and there will be a new section, I believe, Craig will correct me if I'm wrong, the new section there, which will announce their availability, and so keep your eyes on that space.
What we would like you to do is to review the interfaces against your KEXTs to tell us where we've not gone far enough, or things that we're missing, or actually whether we've done a good job, and that you're quite happy with them. That's also very valuable information. We'd like you to send us feedback.
There is an email address that you can use that will come directly through to us in engineering, and we'll be monitoring that very carefully, so be gentle with us. We will be continuing to update both the header files containing the interfaces, and the specifications of the interfaces, and the implementation behind it, so you should track the updates for this and make sure that they're going in the right direction.
Ultimately, when we actually have the implementations, we would like you to port your KEX to use these interfaces, and then give us your feedback on your experiences. Ultimately, what we want to do in the release after Panther is to actually have these interfaces in place, so we're very concerned that we get this right.
We'd like you to work with us, work with Apple, to make this a success for everyone. I mean, for a success for us, so that we end up with a kernel that we can develop in, and make progress in, and support future configurations and hardware, and future functionality, and make it a success for you, that you can implement your KEX in a much more reliable and predictable manner, and a success for our user base, where they now actually have much more sensible things happening when the kernel moves on and your KEX hasn't.
[Transcript missing]
Oh, you have them on the DVD, sorry. So, Session 100, the I/O Kit Kernel Extension Programming, this actually was very interesting about how you deal with multi-threaded environments and real-time priority environments. The open source at Apple, The Bluetooth update, all these have passed, the USB update, and the Firewire in depth. The Darwin update was yesterday, and the one today, this afternoon, Firewire and USB, that's a feedback session, which I encourage you to attend.
So Craig Keithley is the person that you need to talk to if you're having trouble with this, like you can't find the downloads.
[Transcript missing]
So we have some URLs that you can refer to. and the documentation you can refer to inside the OS X kernel. Kernel Programming. These are all things on the developer website. and the ADC website. I/O Kit Fundamentals, Device Drivers, API Reference, Kernel Extensions API Reference, and these things are areas where you could expect to, that we will add to and extend quite considerably as we go through this process.