xref: /freebsd/share/man/man9/hhook.9 (revision 0cdfe2ae89834a1a4b3468bfac870941ee17f2d5)
1.\"
2.\" Copyright (c) 2010-2011 The FreeBSD Foundation
3.\" All rights reserved.
4.\"
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
8.\" Foundation.
9.\"
10.\" Redistribution and use in source and binary forms, with or without
11.\" modification, are permitted provided that the following conditions
12.\" are met:
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.
18.\"
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
29.\" SUCH DAMAGE.
30.\"
31.\" $FreeBSD$
32.\"
33.Dd June 21, 2013
34.Dt HHOOK 9
35.Os
36.Sh NAME
37.Nm hhook ,
38.Nm hhook_head_register ,
39.Nm hhook_head_deregister ,
40.Nm hhook_head_deregister_lookup ,
41.Nm hhook_run_hooks ,
42.Nm HHOOKS_RUN_IF ,
43.Nm HHOOKS_RUN_LOOKUP_IF
44.Nd Helper Hook Framework
45.Sh SYNOPSIS
46.In sys/hhook.h
47.Ft typedef int
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" \
55"struct osd *hosd"
56.Fn HHOOKS_RUN_IF "hhh" "ctx_data" "hosd"
57.Fn HHOOKS_RUN_LOOKUP_IF "hhook_type" "hhook_id" "ctx_data" "hosd"
58.Sh DESCRIPTION
59.Nm
60provides a framework for managing and running arbitrary hook functions at
61defined hook points within the kernel.
62The KPI was inspired by
63.Xr pfil 9 ,
64and in many respects can be thought of as a more generic superset of pfil.
65.Pp
66The
67.Xr khelp 9
68and
69.Nm
70frameworks are tightly integrated.
71Khelp is responsible for registering and deregistering Khelp module hook
72functions with
73.Nm
74points.
75The KPI functions used by
76.Xr khelp 9
77to do this are not documented here as they are not relevant to consumers wishing
78to instantiate hook points.
79.Ss Information for Khelp Module Implementors
80Khelp modules indirectly interact with
81.Nm
82by defining appropriate hook functions for insertion into hook points.
83Hook functions must conform to the
84.Ft hhook_func_t
85function pointer declaration
86outlined in the
87.Sx SYNOPSIS .
88.Pp
89The
90.Fa hhook_type
91and
92.Fa hhook_id
93arguments identify the hook point which has called into the hook function.
94These are useful when a single hook function is registered for multiple hook
95points and wants to know which hook point has called into it.
96.In sys/hhook.h
97lists available
98.Fa hhook_type
99defines and subsystems which export hook points are responsible for defining
100the
101.Fa hhook_id
102value in appropriate header files.
103.Pp
104The
105.Fa udata
106argument will be passed to the hook function if it was specified in the
107.Vt struct hookinfo
108at hook registration time.
109.Pp
110The
111.Fa ctx_data
112argument contains context specific data from the hook point call site.
113The data type passed is subsystem dependent.
114.Pp
115The
116.Fa hdata
117argument is a pointer to the persistent per-object storage allocated for use by
118the module if required.
119The pointer will only ever be NULL if the module did not request per-object
120storage.
121.Pp
122The
123.Fa hosd
124argument can be used with the
125.Xr khelp 9
126framework's
127.Fn khelp_get_osd
128function to access data belonging to a different Khelp module.
129.Pp
130Khelp modules instruct the Khelp framework to register their hook functions with
131.Nm
132points by creating a
133.Vt "struct hookinfo"
134per hook point, which contains the following members:
135.Bd -literal -offset indent
136struct hookinfo {
137	hhook_func_t	hook_func;
138	struct helper	*hook_helper;
139	void		*hook_udata;
140	int32_t		hook_id;
141	int32_t		hook_type;
142};
143.Ed
144.Pp
145Khelp modules are responsible for setting all members of the struct except
146.Va hook_helper
147which is handled by the Khelp framework.
148.Ss Creating and Managing Hook Points
149Kernel subsystems that wish to provide
150.Nm
151points typically need to make four and possibly five key changes to their
152implementation:
153.Bl -bullet
154.It
155Define a list of
156.Va hhook_id
157mappings in an appropriate subsystem header.
158.It
159Register each hook point with the
160.Fn hhook_head_register
161function during initialisation of the subsystem.
162.It
163Select or create a standardised data type to pass to hook functions as
164contextual data.
165.It
166Add a call to
167.Fn HHOOKS_RUN_IF
168or
169.Fn HHOOKS_RUN_IF_LOOKUP
170at the point in the subsystem's code where the hook point should be executed.
171.It
172If the subsystem can be dynamically added/removed at runtime, each hook
173point registered with the
174.Fn hhook_head_register
175function when the subsystem was initialised needs to be deregistered with the
176.Fn hhook_head_deregister
177or
178.Fn hhook_head_deregister_lookup
179functions when the subsystem is being deinitialised prior to removal.
180.El
181.Pp
182The
183.Fn hhook_head_register
184function registers a hook point with the
185.Nm
186framework.
187The
188.Fa hook_type
189argument defines the high level type for the hook point.
190Valid types are defined in
191.In sys/hhook.h
192and new types should be added as required.
193The
194.Fa hook_id
195argument specifies a unique, subsystem specific identifier for the hook point.
196The
197.Fa hhh
198argument will, if not NULL, be used to store a reference to the
199.Vt struct hhook_head
200created as part of the registration process.
201Subsystems will generally want to store a local copy of the
202.Vt struct hhook_head
203so that they can use the
204.Fn HHOOKS_RUN_IF
205macro to instantiate hook points.
206The HHOOK_WAITOK flag may be passed in via the
207.Fa flags
208argument if
209.Xr malloc 9
210is allowed to sleep waiting for memory to become available.
211If the hook point is within a virtualised subsystem (e.g. the network stack),
212the HHOOK_HEADISINVNET flag should be passed in via the
213.Fa flags
214argument so that the
215.Vt struct hhook_head
216created during the registration process will be added to a virtualised list.
217.Pp
218The
219.Fn hhook_head_deregister
220function deregisters a previously registered hook point from the
221.Nm
222framework.
223The
224.Fa hhh
225argument is the pointer to the
226.Vt struct hhook_head
227returned by
228.Fn hhoook_head_register
229when the hook point was registered.
230.Pp
231The
232.Fn hhook_head_deregister_lookup
233function can be used instead of
234.Fn hhook_head_deregister
235in situations where the caller does not have a cached copy of the
236.Vt struct hhook_head
237and wants to deregister a hook point using the appropriate
238.Fa hook_type
239and
240.Fa hook_id
241identifiers instead.
242.Pp
243The
244.Fn hhook_run_hooks
245function should normally not be called directly and should instead be called
246indirectly via the
247.Fn HHOOKS_RUN_IF
248macro.
249However, there may be circumstances where it is preferable to call the function
250directly, and so it is documented here for completeness.
251The
252.Fa hhh
253argument references the
254.Nm
255point to call all registered hook functions for.
256The
257.Fa ctx_data
258argument specifies a pointer to the contextual hook point data to pass into the
259hook functions.
260The
261.Fa hosd
262argument should be the pointer to the appropriate object's
263.Vt struct osd
264if the subsystem provides the ability for Khelp modules to associate per-object
265data.
266Subsystems which do not should pass NULL.
267.Pp
268The
269.Fn HHOOKS_RUN_IF
270macro is the preferred way to implement hook points.
271It only calls the
272.Fn hhook_run_hooks
273function if at least one hook function is registered for the hook point.
274By checking for registered hook functions, the macro minimises the cost
275associated with adding hook points to frequently used code paths by reducing to
276a simple if test in the common case where no hook functions are registered.
277The arguments are as described for the
278.Fn hhook_run_hooks
279function.
280.Pp
281The
282.Fn HHOOKS_RUN_IF_LOOKUP
283macro performs the same function as the
284.Fn HHOOKS_RUN_IF
285macro, but performs an additional step to look up the
286.Vt struct hhook_head
287for the specified
288.Fa hook_type
289and
290.Fa hook_id
291identifiers.
292It should not be used except in code paths which are infrequently executed
293because of the reference counting overhead associated with the look up.
294.Sh IMPLEMENTATION NOTES
295Each
296.Vt struct hhook_head
297protects its internal list of hook functions with a
298.Xr rmlock 9 .
299Therefore, anytime
300.Fn hhook_run_hooks
301is called directly or indirectly via the
302.Fn HHOOKS_RUN_IF
303or
304.Fn HHOOKS_RUN_IF_LOOKUP
305macros, a non-sleepable read lock will be acquired and held across the calls to
306all registered hook functions.
307.Sh RETURN VALUES
308.Fn hhook_head_register
309returns 0 if no errors occurred.
310It returns EEXIST if a hook point with the same
311.Fa hook_type
312and
313.Fa hook_id
314is already registered.
315It returns EINVAL if the HHOOK_HEADISINVNET flag is not set in
316.Fa flags
317because the implementation does not yet support hook points in non-virtualised
318subsystems (see the
319.Sx BUGS
320section for details).
321It returns ENOMEM if
322.Xr malloc 9
323failed to allocate memory for the new
324.Vt struct hhook_head .
325.Pp
326.Fn hhook_head_deregister
327and
328.Fn hhook_head_deregister_lookup
329return 0 if no errors occurred.
330They return ENOENT if
331.Fa hhh
332is NULL.
333They return EBUSY if the reference count of
334.Fa hhh
335is greater than one.
336.Sh EXAMPLES
337A well commented example Khelp module can be found at:
338.Pa /usr/share/examples/kld/khelp/h_example.c
339.Pp
340The
341.Xr tcp 4
342implementation provides two
343.Nm
344points which are called for packets sent/received when a connection is in the
345established phase.
346Search 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
350and
351.Pa sys/netinet/tcp_subr.c .
352.Sh SEE ALSO
353.Xr khelp 9
354.Sh ACKNOWLEDGEMENTS
355Development and testing of this software were made possible in part by grants
356from the FreeBSD Foundation and Cisco University Research Program Fund at
357Community Foundation Silicon Valley.
358.Sh HISTORY
359The
360.Nm
361framework first appeared in
362.Fx 9.0 .
363.Pp
364The
365.Nm
366framework was first released in 2010 by Lawrence Stewart whilst studying at
367Swinburne University of Technology's Centre for Advanced Internet Architectures,
368Melbourne, Australia.
369More details are available at:
370.Pp
371http://caia.swin.edu.au/urp/newtcp/
372.Sh AUTHORS
373.An -nosplit
374The
375.Nm
376framework was written by
377.An Lawrence Stewart Aq lstewart@FreeBSD.org .
378.Pp
379This manual page was written by
380.An David Hayes Aq david.hayes@ieee.org
381and
382.An Lawrence Stewart Aq lstewart@FreeBSD.org .
383