Network Interfaces and Protocol Plumbers
This chapter describes the network interface KPI. This programming interface allows a KEXT to attach new network interfaces, communicate with and manipulate network interfaces, and create new virtual interfaces.
The mechanism recommended for supporting new interfaces depends on the nature of the interface. The recommended mechanisms are:
Ethernet drivers—subclass the
IOEthernetController
andIOEthernetInterface
classes from the I/O Kit’s I/O Networking Family.Other hardware network controllers—subclass the
IONetworkController
andIONetworkInterface
classes.Virtual interfaces—the interface KPI described in this section is recommended.
This chapter also describes protocol plumbers. Protocol plumbers are used to attach network protocols to interfaces.
If you are creating support for an interface type that the stack does not already support (such as ATM), regardless of whether your KEXT uses the I/O Kit, you must register protocol plumbers for attaching existing protocols to the new interface type.
The functionality in a network interface is utilized by both the interface driver and the protocol stacks, as shown in Figure 7-1.
Network Interface Callbacks
Your network interface should define the following callbacks, which are called by protocols and drivers:
ifnet_add_proto_func
, which is called whenever a protocol is attached to the interface.ifnet_check_multi
, which is called when a multicast address is added to an interface. This allows the interface to reject invalid multicast addresses before they are added to the interface.ifnet_del_proto_func
, which is called when a protocol is detached from the interface.ifnet_demux_func
, which is called with a raw packet from the interface, and returns the protocol family value of the protocol that should process the packet. It can do this using either the demux descriptors registered withifnet_add_proto_func
or hard-coded logic. If the packet does not match any protocol, the function should returnENOENT
.ifnet_detached_func
, which is called when your interface is detached.ifnet_event_func
, which is called when an event occurs on a particular interface.ifnet_framer_func
, which is called with outgoing packets before sending them to outgoing interface filters, and is expected to wrap the packet with a stack frame appropriate to the interface type.ifnet_ioctl_func
, which is called whenever an ioctl is received for the interface. The network interface is expected to pass these on to the I/O Kit driver if it is necessary and appropriate to do so. All undefined ioctls are reserved for future Apple use. You should usekern_control
if you need to add additional control mechanisms.ifnet_output_func
, which is called with a packet that is ready to be sent out the wire. The network interface is expected to transmit the packet and free the mbuf associated with it. For network interfaces backed by I/O Kit drivers, this callback generally calls a function in the I/O Kit driver that handles both of these tasks.ifnet_set_bpf_tap
, which is called by the stack to set the BPF tap function that is installed on the interface. This callback is optional, but recommended; if you do not add this function, BPF cannot be used with your interface.
Good examples of many of these functions can be found in bsd/net/ether_if_module.c
in the xnu
(kernel) source tree.
Installing and Removing Network Interfaces
The following functions are typically called (in the following order) to support the dynamic insertion and removal of network interfaces:
ifnet_allocate
, which allocates an interface structure.ifnet_attach
, which attaches an interface to the global interface list.bpfattach
, which enables BPF support on an interface (optional).ifnet_detach
, which removes an interface from the global interface list.ifnet_release
, which releases a reference to an interface structure. If the reference count reaches zero (0), the structure will be freed. This release matches theifnet_allocate
call earlier, and should be called after callingifnet_detach
.
The related function ifnet_reference
can be used (generally by other KEXTs) to increase the reference count of an interface structure. These calls must be balanced by an equal number of calls to ifnet_release
.
Protocol Plumbers
Protocol plumbers, as mentioned previously, are responsible for attaching a protocol to a network interface. When a protocol needs to attach to an interface, it calls a function that looks up the plumber designated for that protocol and interface type, then calls that plumber’s plumb handler.
Protocol plumbers define the following callbacks, which are called by protocols:
proto_plumb_handler
, which is called to attach a protocol to an interface. This typically consists of a call to the interface’sifnet_attach_protocol
callback.proto_unplumb_handler
, which is called to detach a protocol from an interface. The unplumb handler should call theifnet_detach_protocol
function, but may do other cleanup such as freeing any storage allocated in theproto_plumb_handler
callback.
When attaching a protocol to an interface, the protocol plumber typically fills in the following fields in the ifnet_attach_proto_param
structure, many of which may be defined as part of the protocol itself. This mechanism provides the opportunity for the protocol plumber to intercept these calls and take interface-specific actions where needed.
proto_media_detached
(optional), which is used to notify the protocol that it is being detached.proto_media_event
(optional), which is called to notify a protocol about interface-specific events.proto_media_input
(required), which is used to deliver an inbound packet to the protocol for processing.proto_media_ioctl
(optional), which is typically the protocol’s ioctl handling function.proto_media_preout
(required), which is called just before a packet is transmitted. This allows the protocol to specify a media-specific frame type and destination.proto_media_resolve_multi
(optional), which is used to obtain a link layer address for a given protocol layer multicast address. This is only necessary if your interface supports multicast.proto_media_send_arp
(optional), which is used to obtain the link layer address corresponding to a given protocol layer unicast address. This is necessary for all non-point-to-point interfaces.
Examples of these functions can be found in bsd/net/ether_inet_pr_module.c
in the xnu
(kernel) source tree.
Sending Data
The following steps describe the process of sending a packet, using Ethernet as the example medium:
The
ip_output
routine in the IP protocol stack callsifnet_output
.The
ifnet_output
function calls the protocol plumber’sproto_media_preout
function. In the case of IP, this function callsinet_arp_lookup
.If the ARP cache does not contain an entry for the IP address,
inet_arp_lookup
then calls the protocol plumber’sproto_media_send_arp
callback to resolve the target IP address into a media access control (MAC) address.When the
proto_media_preout
callback returns, theifnet_output
function calls the network interface’sifnet_framer_func
function. This framing function prepends interface-specific frame data to the packet.If any interface filters are present, their
iff_output_func
callbacks are called consecutively.The
ifnet_output
function calls the network interface’sifnet_output_func
callback, which transmits the packet and frees the mbuf.
Receiving Data
The following steps describe the process of receiving a packet:
The hardware driver or its support code calls
ifnet_input
with pointers to itsifnet
structure (ifnet_t
) andmbuf
chain (mbuf_t
).The packet is queued. Processing resumes on a different thread.
The
ifnet_input
function calls the network interface’sifnet_demux_func
function for the interface.The demultiplexing function identifies the frame and returns a
protocol_family_t
value to indicate which protocol should handle the packet.The
ifnet_input
function calls the attached interface filters (if any) sequentially.Any packets not matching an attached protocol are dropped, as are any promiscuous packets.
The
ifnet_input
function calls the protocol plumber’sproto_media_input
function. The plumber is specific to a given protocol/interface combination.
Copyright © 2003, 2012 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2012-01-09