The packet dispatcher provides a mechanism for dispatching packets to one of several entities using packet filter technology. The packet dispatcher API allows the user to specify the type of packet filter machinery to be used internally (BPF+, DPF, etc.). The entities register their interest in a type of packet using filter-specific packet descriptions. The packet dispatcher later demultiplexes incoming packets to the correct owner or, if a packet doesn’t match any of the previously registered descriptions, to a user-defined default netio. (See Section 7.5 for general information about the netio interface.)
The packet dispatcher’s architecture is pictured in Figure 42.1. There are two data paths: one for packet description registration and one for packet dispatch. Packet owners register interest in a certain type of packets by calling oskit_packet_dispatcher_register with a description of the packets along with a netio object to which subsequently received, matching packets are pushed. The packet dispatcher’s PID (Process ID, for lack of a better term) table provides the level-of-indirection necessary to map filter-generated Filter IDs with caller-supplied PIDs.
The type of packet filter used determines what format the packet descriptions take on. (As of this writing, only a single packet filter is implemented in the OSKit, but the packet dispatcher code is implemented as if more than one were available to ease the burden in future work.)
Because the packet dispatcher uses the OSKit netio interface for both incoming and outgoing channels, the definition of a packet “owner” is not restricted in any way: it can run on different threads or the same thread, it can dispatch packets further or process them immediately, it can process them inline or enqueue an event on an event queue. Owners can be flows, threads, processes--whatever model fits the context.
The packet dispatcher can be used in several different contexts: used in conjunction with robust accounting, it can detect a dearth in a packet owner’s resources before expending resources processing packets destined to be dropped; the packet dispatcher can be used to process non-traditional packets such as IPv6; in an active network / server environment, the packet dispatcher can be used to dispatch packets to different Execution Environments.
The example application examples/x86/more/pd_ex.c creates a packet dispatcher which uses the
OSKIT_PD_FILTER_DPF_INTERP filter type, creates and registers a packet description for ARP requests, creates and
registers a packet description for ARP replies, and dispatches incoming packets until a certain packet count is
reached.
This section describes some of the important restrictions the packet dispatcher places on its use and future work:
When the OSKit is compiled with debugging enabled (--enable-debug), a number of sanity checks are compiled to help detect bad parameters.
The following sections describe the functions exported by the Packet Dispatcher in detail. All of these functions, as well as the types necessary to use them, are defined in the header file <oskit/pd.h>.
#include <oskit/pd.h>
oskit_s32_t oskit_packet_dispatcher_create( oskit_pd_t **pd, oskit_u32_t filter_type, oskit_netio_t **push_netio, oskit_netio_t *default_outgoing);
Upon successful return, pd points to the newly created packet dispatcher. In subsequent packet dispatcher operations, the caller must pass back a pointer to the same pd structure which acts as a handle for the packet dispatcher.
The caller must provide a pointer to the default netio channel. Any packets which do not match any registered packet description will be pushed to the default netio. For example, after creation but before any oskit_packet_dispatcher_register calls, all received packets are routed to the default netio since there are no packet descriptions registered in the packet dispatcher.
The caller must provide a pointer to a netio object. This pointer is initialized during the call to represent the packet dispatcher’s incoming channel.
Returns 0 on success, or an error code specified in <oskit/error.h>, on error.
#include <oskit/pd.h>
oskit_s32_t oskit_packet_dispatcher_register( oskit_pd_t **pd, oskit_s32_t *pdid, oskit_netio_t *out_netio, void *pdescr, oskit_s32_t sz);
This function is used to associate a packet owner (flow, process, whatever) with a packet description. After successful registration, the packet dispatcher will push packets matching the given description to the given netio. It is the caller’s responsibility to ensure their description is unique so that ambiguity is avoided.
The format of the packet description is determined by the filter_type argument to the oskit_packet_dispatcher_create call.
Returns 0 on success, or an error code specified in <oskit/error.h>, on error.
#include <oskit/pd.h>
oskit_s32_t oskit_packet_dispatcher_register( oskit_pd_t **pd, oskit_s32_t fid);
This function is used to disassociate a packet owner (flow, process, whatever) from a packet description.
Returns 0 on success, or an error code specified in <oskit/error.h>, on error.