Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
HHOOK(9)		 BSD Kernel Developer's	Manual		      HHOOK(9)

     hhook, hhook_head_register, hhook_head_deregister,
     hhook_head_deregister_lookup, hhook_run_hooks, HHOOKS_RUN_IF,
     HHOOKS_RUN_LOOKUP_IF -- Helper Hook Framework

     #include <sys/hhook.h>

     typedef int
     (*hhook_func_t)(int32_t hhook_type, int32_t hhook_id, void	*udata,
	 void *ctx_data, void *hdata, struct osd *hosd);

     int hhook_head_register(int32_t hhook_type, int32_t hhook_id,
	 struct	hhook_head **hhh, uint32_t flags);

     int hhook_head_deregister(struct hhook_head *hhh);

     int hhook_head_deregister_lookup(int32_t hhook_type, int32_t hhook_id);

     void hhook_run_hooks(struct hhook_head *hhh, void *ctx_data,
	 struct	osd *hosd);

     HHOOKS_RUN_IF(hhh,	ctx_data, hosd);

     HHOOKS_RUN_LOOKUP_IF(hhook_type, hhook_id,	ctx_data, hosd);

     hhook provides a framework	for managing and running arbitrary hook	func-
     tions at defined hook points within the kernel.  The KPI was inspired by
     pfil(9), and in many respects can be thought of as	a more generic super-
     set of pfil.

     The khelp(9) and hhook frameworks are tightly integrated.	Khelp is re-
     sponsible for registering and deregistering Khelp module hook functions
     with hhook	points.	 The KPI functions used	by khelp(9) to do this are not
     documented	here as	they are not relevant to consumers wishing to instan-
     tiate hook	points.

   Information for Khelp Module	Implementors
     Khelp modules indirectly interact with hhook by defining appropriate hook
     functions for insertion into hook points.	Hook functions must conform to
     the hhook_func_t function pointer declaration outlined in the SYNOPSIS.

     The hhook_type and	hhook_id arguments identify the	hook point which has
     called into the hook function.  These are useful when a single hook func-
     tion is registered	for multiple hook points and wants to know which hook
     point has called into it.	<sys/hhook.h> lists available hhook_type de-
     fines and subsystems which	export hook points are responsible for defin-
     ing the hhook_id value in appropriate header files.

     The udata argument	will be	passed to the hook function if it was speci-
     fied in the struct	hookinfo at hook registration time.

     The ctx_data argument contains context specific data from the hook	point
     call site.	 The data type passed is subsystem dependent.

     The hdata argument	is a pointer to	the persistent per-object storage al-
     located for use by	the module if required.	 The pointer will only ever be
     NULL if the module	did not	request	per-object storage.

     The hosd argument can be used with	the khelp(9) framework's
     khelp_get_osd() function to access	data belonging to a different Khelp

     Khelp modules instruct the	Khelp framework	to register their hook func-
     tions with	hhook points by	creating a struct hookinfo per hook point,
     which contains the	following members:

	   struct hookinfo {
		   hhook_func_t	   hook_func;
		   struct helper   *hook_helper;
		   void		   *hook_udata;
		   int32_t	   hook_id;
		   int32_t	   hook_type;

     Khelp modules are responsible for setting all members of the struct ex-
     cept hook_helper which is handled by the Khelp framework.

   Creating and	Managing Hook Points
     Kernel subsystems that wish to provide hhook points typically need	to
     make four and possibly five key changes to	their implementation:

     +o	 Define	a list of hhook_id mappings in an appropriate subsystem

     +o	 Register each hook point with the hhook_head_register() function dur-
	 ing initialisation of the subsystem.

     +o	 Select	or create a standardised data type to pass to hook functions
	 as contextual data.

     +o	 Add a call to HHOOKS_RUN_IF() or HHOOKS_RUN_IF_LOOKUP() at the	point
	 in the	subsystem's code where the hook	point should be	executed.

     +o	 If the	subsystem can be dynamically added/removed at runtime, each
	 hook point registered with the	hhook_head_register() function when
	 the subsystem was initialised needs to	be deregistered	with the
	 hhook_head_deregister() or hhook_head_deregister_lookup() functions
	 when the subsystem is being deinitialised prior to removal.

     The hhook_head_register() function	registers a hook point with the	hhook
     framework.	 The hook_type argument	defines	the high level type for	the
     hook point.  Valid	types are defined in <sys/hhook.h> and new types
     should be added as	required.  The hook_id argument	specifies a unique,
     subsystem specific	identifier for the hook	point.	The hhh	argument will,
     if	not NULL, be used to store a reference to the struct hhook_head	cre-
     ated as part of the registration process.	Subsystems will	generally want
     to	store a	local copy of the struct hhook_head so that they can use the
     HHOOKS_RUN_IF() macro to instantiate hook points.	The HHOOK_WAITOK flag
     may be passed in via the flags argument if	malloc(9) is allowed to	sleep
     waiting for memory	to become available.  If the hook point	is within a
     virtualised subsystem (e.g. the network stack), the HHOOK_HEADISINVNET
     flag should be passed in via the flags argument so	that the struct
     hhook_head	created	during the registration	process	will be	added to a
     virtualised list.

     The hhook_head_deregister() function deregisters a	previously registered
     hook point	from the hhook framework.  The hhh argument is the pointer to
     the struct	hhook_head returned by hhoook_head_register() when the hook
     point was registered.

     The hhook_head_deregister_lookup()	function can be	used instead of
     hhook_head_deregister() in	situations where the caller does not have a
     cached copy of the	struct hhook_head and wants to deregister a hook point
     using the appropriate hook_type and hook_id identifiers instead.

     The hhook_run_hooks() function should normally not	be called directly and
     should instead be called indirectly via the HHOOKS_RUN_IF() macro.	 How-
     ever, there may be	circumstances where it is preferable to	call the func-
     tion directly, and	so it is documented here for completeness.  The	hhh
     argument references the hhook point to call all registered	hook functions
     for.  The ctx_data	argument specifies a pointer to	the contextual hook
     point data	to pass	into the hook functions.  The hosd argument should be
     the pointer to the	appropriate object's struct osd	if the subsystem pro-
     vides the ability for Khelp modules to associate per-object data.	Sub-
     systems which do not should pass NULL.

     The HHOOKS_RUN_IF() macro is the preferred	way to implement hook points.
     It	only calls the hhook_run_hooks() function if at	least one hook func-
     tion is registered	for the	hook point.  By	checking for registered	hook
     functions,	the macro minimises the	cost associated	with adding hook
     points to frequently used code paths by reducing to a simple if test in
     the common	case where no hook functions are registered.  The arguments
     are as described for the hhook_run_hooks()	function.

     The HHOOKS_RUN_IF_LOOKUP()	macro performs the same	function as the
     HHOOKS_RUN_IF() macro, but	performs an additional step to look up the
     struct hhook_head for the specified hook_type and hook_id identifiers.
     It	should not be used except in code paths	which are infrequently exe-
     cuted because of the reference counting overhead associated with the look

     Each struct hhook_head protects its internal list of hook functions with
     a rmlock(9).  Therefore, anytime hhook_run_hooks()	is called directly or
     indirectly	via the	HHOOKS_RUN_IF()	or HHOOKS_RUN_IF_LOOKUP() macros, a
     non-sleepable read	lock will be acquired and held across the calls	to all
     registered	hook functions.

     hhook_head_register() returns 0 if	no errors occurred.  It	returns	EEXIST
     if	a hook point with the same hook_type and hook_id is already regis-
     tered.  It	returns	EINVAL if the HHOOK_HEADISINVNET flag is not set in
     flags because the implementation does not yet support hook	points in non-
     virtualised subsystems (see the BUGS section for details).	 It returns
     ENOMEM if malloc(9) failed	to allocate memory for the new struct

     hhook_head_deregister() and hhook_head_deregister_lookup()	return 0 if no
     errors occurred.  They return ENOENT if hhh is NULL.  They	return EBUSY
     if	the reference count of hhh is greater than one.

     A well commented example Khelp module can be found	at:

     The tcp(4)	implementation provides	two hhook points which are called for
     packets sent/received when	a connection is	in the established phase.
     Search for	HHOOK in the following files: sys/netinet/tcp_var.h,
     sys/netinet/tcp_input.c, sys/netinet/tcp_output.c and


     Development and testing of	this software were made	possible in part by
     grants from the FreeBSD Foundation	and Cisco University Research Program
     Fund at Community Foundation Silicon Valley.

     The hhook framework first appeared	in FreeBSD 9.0.

     The hhook framework was first released in 2010 by Lawrence	Stewart	whilst
     studying at Swinburne University of Technology's Centre for Advanced In-
     ternet Architectures, Melbourne, Australia.  More details are available

     The hhook framework was written by	Lawrence Stewart

     This manual page was written by David Hayes <>	and
     Lawrence Stewart <>.

     The framework does	not currently support registering hook points in sub-
     systems which have	not been virtualised with VIMAGE.  Fairly minimal in-
     ternal changes to the hhook implementation	are required to	address	this.

BSD			       February	15, 2011			   BSD


Want to link to this manual page? Use this URL:

home | help