2 .\" Copyright (c) 2010-2011 The FreeBSD Foundation
3 .\" All rights reserved.
5 .\" This documentation was written at the Centre for Advanced Internet
6 .\" Architectures, Swinburne University of Technology, Melbourne, Australia by
7 .\" David Hayes and Lawrence Stewart under sponsorship from the FreeBSD
10 .\" Redistribution and use in source and binary forms, with or without
11 .\" modification, are permitted provided that the following conditions
13 .\" 1. Redistributions of source code must retain the above copyright
14 .\" notice, this list of conditions and the following disclaimer.
15 .\" 2. Redistributions in binary form must reproduce the above copyright
16 .\" notice, this list of conditions and the following disclaimer in the
17 .\" documentation and/or other materials provided with the distribution.
19 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
23 .\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 .Nm hhook_head_register ,
39 .Nm hhook_head_deregister ,
40 .Nm hhook_head_deregister_lookup ,
43 .Nm HHOOKS_RUN_LOOKUP_IF
44 .Nd Helper Hook Framework
48 .Fn "\*(lp*hhook_func_t\*(rp" "int32_t hhook_type" "int32_t hhook_id" \
49 "void *udata" "void *ctx_data" "void *hdata" "struct osd *hosd"
50 .Fn "int hhook_head_register" "int32_t hhook_type" "int32_t hhook_id" \
51 "struct hhook_head **hhh" "uint32_t flags"
52 .Fn "int hhook_head_deregister" "struct hhook_head *hhh"
53 .Fn "int hhook_head_deregister_lookup" "int32_t hhook_type" "int32_t hhook_id"
54 .Fn "void hhook_run_hooks" "struct hhook_head *hhh" "void *ctx_data" \
56 .Fn HHOOKS_RUN_IF "hhh" "ctx_data" "hosd"
57 .Fn HHOOKS_RUN_LOOKUP_IF "hhook_type" "hhook_id" "ctx_data" "hosd"
60 provides a framework for managing and running arbitrary hook functions at
61 defined hook points within the kernel.
62 The KPI was inspired by
64 and in many respects can be thought of as a more generic superset of pfil.
70 frameworks are tightly integrated.
71 Khelp is responsible for registering and deregistering Khelp module hook
75 The KPI functions used by
77 to do this are not documented here as they are not relevant to consumers wishing
78 to instantiate hook points.
79 .Ss Information for Khelp Module Implementors
80 Khelp modules indirectly interact with
82 by defining appropriate hook functions for insertion into hook points.
83 Hook functions must conform to the
85 function pointer declaration
93 arguments identify the hook point which has called into the hook function.
94 These are useful when a single hook function is registered for multiple hook
95 points and wants to know which hook point has called into it.
99 defines and subsystems which export hook points are responsible for defining
102 value in appropriate header files.
106 argument will be passed to the hook function if it was specified in the
108 at hook registration time.
112 argument contains context specific data from the hook point call site.
113 The data type passed is subsystem dependent.
117 argument is a pointer to the persistent per-object storage allocated for use by
118 the module if required.
119 The pointer will only ever be NULL if the module did not request per-object
124 argument can be used with the
128 function to access data belonging to a different Khelp module.
130 Khelp modules instruct the Khelp framework to register their hook functions with
133 .Vt "struct hookinfo"
134 per hook point, which contains the following members:
135 .Bd -literal -offset indent
137 hhook_func_t hook_func;
138 struct helper *hook_helper;
145 Khelp modules are responsible for setting all members of the struct except
147 which is handled by the Khelp framework.
148 .Ss Creating and Managing Hook Points
149 Kernel subsystems that wish to provide
151 points typically need to make four and possibly five key changes to their
157 mappings in an appropriate subsystem header.
159 Register each hook point with the
160 .Fn hhook_head_register
161 function during initialisation of the subsystem.
163 Select or create a standardised data type to pass to hook functions as
169 .Fn HHOOKS_RUN_IF_LOOKUP
170 at the point in the subsystem's code where the hook point should be executed.
172 If the subsystem can be dynamically added/removed at runtime, each hook
173 point registered with the
174 .Fn hhook_head_register
175 function when the subsystem was initialised needs to be deregistered with the
176 .Fn hhook_head_deregister
178 .Fn hhook_head_deregister_lookup
179 functions when the subsystem is being deinitialised prior to removal.
183 .Fn hhook_head_register
184 function registers a hook point with the
189 argument defines the high level type for the hook point.
190 Valid types are defined in
192 and new types should be added as required.
195 argument specifies a unique, subsystem specific identifier for the hook point.
198 argument will, if not NULL, be used to store a reference to the
199 .Vt struct hhook_head
200 created as part of the registration process.
201 Subsystems will generally want to store a local copy of the
202 .Vt struct hhook_head
203 so that they can use the
205 macro to instantiate hook points.
206 The HHOOK_WAITOK flag may be passed in via the
210 is allowed to sleep waiting for memory to become available.
211 If the hook point is within a virtualised subsystem (e.g. the network stack),
212 the HHOOK_HEADISINVNET flag should be passed in via the
215 .Vt struct hhook_head
216 created during the registration process will be added to a virtualised list.
219 .Fn hhook_head_deregister
220 function deregisters a previously registered hook point from the
225 argument is the pointer to the
226 .Vt struct hhook_head
228 .Fn hhoook_head_register
229 when the hook point was registered.
232 .Fn hhook_head_deregister_lookup
233 function can be used instead of
234 .Fn hhook_head_deregister
235 in situations where the caller does not have a cached copy of the
236 .Vt struct hhook_head
237 and wants to deregister a hook point using the appropriate
245 function should normally not be called directly and should instead be called
249 However, there may be circumstances where it is preferable to call the function
250 directly, and so it is documented here for completeness.
253 argument references the
255 point to call all registered hook functions for.
258 argument specifies a pointer to the contextual hook point data to pass into the
262 argument should be the pointer to the appropriate object's
264 if the subsystem provides the ability for Khelp modules to associate per-object
266 Subsystems which do not should pass NULL.
270 macro is the preferred way to implement hook points.
273 function if at least one hook function is registered for the hook point.
274 By checking for registered hook functions, the macro minimises the cost
275 associated with adding hook points to frequently used code paths by reducing to
276 a simple if test in the common case where no hook functions are registered.
277 The arguments are as described for the
282 .Fn HHOOKS_RUN_IF_LOOKUP
283 macro performs the same function as the
285 macro, but performs an additional step to look up the
286 .Vt struct hhook_head
292 It should not be used except in code paths which are infrequently executed
293 because of the reference counting overhead associated with the look up.
294 .Sh IMPLEMENTATION NOTES
296 .Vt struct hhook_head
297 protects its internal list of hook functions with a
301 is called directly or indirectly via the
304 .Fn HHOOKS_RUN_IF_LOOKUP
305 macros, a non-sleepable read lock will be acquired and held across the calls to
306 all registered hook functions.
308 .Fn hhook_head_register
309 returns 0 if no errors occurred.
310 It returns EEXIST if a hook point with the same
314 is already registered.
315 It returns EINVAL if the HHOOK_HEADISINVNET flag is not set in
317 because the implementation does not yet support hook points in non-virtualised
320 section for details).
323 failed to allocate memory for the new
324 .Vt struct hhook_head .
326 .Fn hhook_head_deregister
328 .Fn hhook_head_deregister_lookup
329 return 0 if no errors occurred.
330 They return ENOENT if
333 They return EBUSY if the reference count of
337 A well commented example Khelp module can be found at:
338 .Pa /usr/share/examples/kld/khelp/h_example.c
342 implementation provides two
344 points which are called for packets sent/received when a connection is in the
346 Search for HHOOK in the following files:
347 .Pa sys/netinet/tcp_var.h ,
348 .Pa sys/netinet/tcp_input.c ,
349 .Pa sys/netinet/tcp_output.c
351 .Pa sys/netinet/tcp_subr.c .
355 Development and testing of this software were made possible in part by grants
356 from the FreeBSD Foundation and Cisco University Research Program Fund at
357 Community Foundation Silicon Valley.
361 framework first appeared in
366 framework was first released in 2010 by Lawrence Stewart whilst studying at
367 Swinburne University of Technology's Centre for Advanced Internet Architectures,
368 Melbourne, Australia.
369 More details are available at:
371 http://caia.swin.edu.au/urp/newtcp/
376 framework was written by
377 .An Lawrence Stewart Aq lstewart@FreeBSD.org .
379 This manual page was written by
380 .An David Hayes Aq david.hayes@ieee.org
382 .An Lawrence Stewart Aq lstewart@FreeBSD.org .