A module that wants to be an accept filter must provide a structaccept_filter to the system:
struct accept_filter {
char accf_name[16];
void (*accf_callback)(struct socket *so, void *arg, int waitflag);
void * (*accf_create)(struct socket *so, char *arg);
void (*accf_destroy)(struct socket *so);
SLIST_ENTRY(accept_filter) accf_next; /* next on the list */
};
The module should register it with the function accept_filt_add(), passing a pointer to a structaccept_filter, allocated with malloc(9).
The fields of structaccept_filter are as follows:
accf_name Name of the filter; this is how it will be accessed from userland.
accf_callback The callback that the kernel will do once the connection is established. It is the same
as a socket upcall and will be called when the connection is established and whenever new
data arrives on the socket, unless the callback modifies the socket's flags.
accf_create Called whenever a setsockopt(2) installs the filter onto a listening socket.
accf_destroy Called whenever the user removes the accept filter on the socket.
The accept_filt_del() function passed the same string used in accept_filter.accf_name during registration
with accept_filt_add(), the kernel will then disallow and further userland use of the filter.
The accept_filt_get() function is used internally to locate which accept filter to use via the
setsockopt(2) system call.
The accept_filt_generic_mod_event() function provides a simple way to avoid duplication of code for
accept filters which do not use the argument field to load and unload themselves. This function can be
used in the moduledata_t struct for the DECLARE_MODULE(9) macro.