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:

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.

Figure 7-1  Network Interfaces in the Networking Stack
Network Interfaces in the Networking Stack

Network Interface Callbacks

Your network interface should define the following callbacks, which are called by protocols and drivers:

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:

  1. ifnet_allocate, which allocates an interface structure.

  2. ifnet_attach, which attaches an interface to the global interface list.

  3. bpfattach, which enables BPF support on an interface (optional).

  4. ifnet_detach, which removes an interface from the global interface list.

  5. 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 the ifnet_allocate call earlier, and should be called after calling ifnet_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:

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.

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:

  1. The ip_output routine in the IP protocol stack calls ifnet_output.

  2. The ifnet_output function calls the protocol plumber’s proto_media_preout function. In the case of IP, this function calls inet_arp_lookup.

  3. If the ARP cache does not contain an entry for the IP address, inet_arp_lookup then calls the protocol plumber’s proto_media_send_arp callback to resolve the target IP address into a media access control (MAC) address.

  4. When the proto_media_preout callback returns, the ifnet_output function calls the network interface’s ifnet_framer_func function. This framing function prepends interface-specific frame data to the packet.

  5. If any interface filters are present, their iff_output_func callbacks are called consecutively.

  6. The ifnet_output function calls the network interface’s ifnet_output_func callback, which transmits the packet and frees the mbuf.

Receiving Data

The following steps describe the process of receiving a packet:

  1. The hardware driver or its support code calls ifnet_input with pointers to its ifnet structure (ifnet_t) and mbuf chain (mbuf_t).

  2. The packet is queued. Processing resumes on a different thread.

  3. The ifnet_input function calls the network interface’s ifnet_demux_func function for the interface.

  4. The demultiplexing function identifies the frame and returns a protocol_family_t value to indicate which protocol should handle the packet.

  5. The ifnet_input function calls the attached interface filters (if any) sequentially.

  6. Any packets not matching an attached protocol are dropped, as are any promiscuous packets.

  7. The ifnet_input function calls the protocol plumber’s proto_media_input function. The plumber is specific to a given protocol/interface combination.