ACCEPT_FILTER(9)

πŸ“¦ version 15.1, in freebsd 14.5, freebsd 15.1

πŸ¦‹ ACCEPT_FILTER(9) β€” the kernel-dev manual, bestie edition ✨

okay so this one lives in the Kernel Developer's Manual section 9, and it's literally all about accept filters β€” filtering incoming connections before your app even has to deal with them πŸ‘‘


✨ NAME ✨

accept_filter, accept_filt_add, accept_filt_del, accept_filt_generic_mod_event, accept_filt_get β€” the whole lil squad that filters incoming connections πŸ’…


πŸŽ€ SYNOPSIS πŸŽ€

#include <sys/types.h>
#include <sys/module.h>
#include <sys/socket.h>
#define ACCEPT_FILTER_MOD
#include <sys/socketvar.h>

int
accept_filt_add(struct accept_filter *filt);

int
accept_filt_del(char *name);

int
accept_filt_generic_mod_event(module_t mod, int event, void *data);

struct accept_filter *
accept_filt_get(char *name);

like, copy that include order exactly, don't get creative with it πŸ™ˆ


πŸ’– DESCRIPTION πŸ’–

Accept filters let an application ask the kernel to pre-process incoming connections for it. So instead of your app waking up for every single connection the second it lands, the kernel does the vibes check first. iconic behavior tbh 🌸

You request an accept filter through the setsockopt(2) system call, passing in an optname of SO_ACCEPTFILTER. that's the whole handshake, slay ✨


🧚 IMPLEMENTATION NOTES 🧚

so if a module wants to be an accept filter, it has to hand the system a struct accept_filter, and it looks like this β€” verbatim, no edits bestie:

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 struct accept_filter β€” and that struct should be allocated with malloc(9). no cap, that part matters 🫢


🌈 the fields of struct accept_filter, explained 🌈

  • accf_name β€” the name of the filter; this is literally how it gets accessed from userland. it's your filter's whole identity πŸ’«
  • accf_callback β€” the callback the kernel does once the connection is established. it's the same as a socket upcall, and it gets 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 gets passed the same string that was used in accept_filter.accf_name during registration with accept_filt_add() β€” and then the kernel will disallow any further userland use of that filter. bye bestie πŸ‘‹

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 is a cute lil shortcut β€” it gives you a simple way to avoid duplicating code for accept filters that don't use the argument field to load and unload themselves. You can use it in the moduledata_t struct for the DECLARE_MODULE(9) macro ✨


πŸ”₯ SEE ALSO πŸ”₯


πŸ‘‘ HISTORY πŸ‘‘

The accept filter mechanism was introduced in FreeBSD 4.0. vintage but make it fashion πŸ’œ


🌸 AUTHORS 🌸

This manual page was written by Alfred Perlstein, Sheldon Hearn and Jeroen Ruigrok van der Werven. 🫢

The accept filter concept was pioneered by David Filo at Yahoo! and refined into a loadable module system by Alfred Perlstein. literally main character energy from both of them ⭐


πŸ’­ tiny reminder bestie: this page is from the Debian build of the manpage, dated June 25, 2000 β€” so yeah, it's giving retro, but the facts are all still here. mwah πŸ’…πŸ’–
πŸ“¦ where this page comes from