1.\" 2.\" Copyright (c) 2010-2011 The FreeBSD Foundation 3.\" 4.\" This documentation was written at the Centre for Advanced Internet 5.\" Architectures, Swinburne University of Technology, Melbourne, Australia by 6.\" David Hayes and Lawrence Stewart under sponsorship from the FreeBSD 7.\" Foundation. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 22.\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28.\" SUCH DAMAGE. 29.\" 30.Dd October 1, 2024 31.Dt KHELP 9 32.Os 33.Sh NAME 34.Nm khelp , 35.Nm khelp_init_osd , 36.Nm khelp_destroy_osd , 37.Nm khelp_get_id , 38.Nm khelp_get_osd , 39.Nm khelp_add_hhook , 40.Nm khelp_remove_hhook , 41.Nm KHELP_DECLARE_MOD , 42.Nm KHELP_DECLARE_MOD_UMA 43.Nd Kernel Helper Framework 44.Sh SYNOPSIS 45.In sys/khelp.h 46.In sys/module_khelp.h 47.Fn "int khelp_init_osd" "uint32_t classes" "struct osd *hosd" 48.Fn "int khelp_destroy_osd" "struct osd *hosd" 49.Fn "int32_t khelp_get_id" "char *hname" 50.Fn "void * khelp_get_osd" "struct osd *hosd" "int32_t id" 51.Fn "int khelp_add_hhook" "const struct hookinfo *hki" "uint32_t flags" 52.Fn "int khelp_remove_hhook" "const struct hookinfo *hki" 53.Fn KHELP_DECLARE_MOD "hname" "hdata" "hhooks" "version" 54.Fn KHELP_DECLARE_MOD_UMA "hname" "hdata" "hhooks" "version" "ctor" "dtor" 55.Sh DESCRIPTION 56.Nm 57provides a framework for managing 58.Nm 59modules, which indirectly use the 60.Xr hhook 9 61KPI to register their hook functions with hook points of interest within the 62kernel. 63Khelp modules aim to provide a structured way to dynamically extend the kernel 64at runtime in an ABI preserving manner. 65Depending on the subsystem providing hook points, a 66.Nm 67module may be able to associate per-object data for maintaining relevant state 68between hook calls. 69The 70.Xr hhook 9 71and 72.Nm 73frameworks are tightly integrated and anyone interested in 74.Nm 75should also read the 76.Xr hhook 9 77manual page thoroughly. 78.Ss Information for Khelp Module Implementors 79.Nm 80modules are represented within the 81.Nm 82framework by a 83.Vt struct helper 84which has the following members: 85.Bd -literal -offset indent 86struct helper { 87 int (*mod_init) (void); 88 int (*mod_destroy) (void); 89#define HELPER_NAME_MAXLEN 16 90 char h_name[HELPER_NAME_MAXLEN]; 91 uma_zone_t h_zone; 92 struct hookinfo *h_hooks; 93 uint32_t h_nhooks; 94 uint32_t h_classes; 95 int32_t h_id; 96 volatile uint32_t h_refcount; 97 uint16_t h_flags; 98 TAILQ_ENTRY(helper) h_next; 99}; 100.Ed 101.Pp 102Modules must instantiate a 103.Vt struct helper , 104but are only required to set the 105.Va h_classes 106field, and may optionally set the 107.Va h_flags , 108.Va mod_init 109and 110.Va mod_destroy 111fields where required. 112The framework takes care of all other fields and modules should refrain from 113manipulating them. 114Using the C99 designated initialiser feature to set fields is encouraged. 115.Pp 116If specified, the 117.Va mod_init 118function will be run by the 119.Nm 120framework prior to completing the registration process. 121Returning a non-zero value from the 122.Va mod_init 123function will abort the registration process and fail to load the module. 124If specified, the 125.Va mod_destroy 126function will be run by the 127.Nm 128framework during the deregistration process, after the module has been 129deregistered by the 130.Nm 131framework. 132The return value is currently ignored. 133Valid 134.Nm 135classes are defined in 136.In sys/khelp.h . 137Valid flags are defined in 138.In sys/module_khelp.h . 139The HELPER_NEEDS_OSD flag should be set in the 140.Va h_flags 141field if the 142.Nm 143module requires persistent per-object data storage. 144There is no programmatic way (yet) to check if a 145.Nm 146class provides the ability for 147.Nm 148modules to associate persistent per-object data, so a manual check is required. 149.Pp 150The 151.Fn KHELP_DECLARE_MOD 152and 153.Fn KHELP_DECLARE_MOD_UMA 154macros provide convenient wrappers around the 155.Xr DECLARE_MODULE 9 156macro, and are used to register a 157.Nm 158module with the 159.Nm 160framework. 161.Fn KHELP_DECLARE_MOD_UMA 162should only be used by modules which require the use of persistent per-object 163storage i.e. modules which set the HELPER_NEEDS_OSD flag in their 164.Vt struct helper Ns 's 165.Va h_flags 166field. 167.Pp 168The first four arguments common to both macros are as follows. 169The 170.Fa hname 171argument specifies the unique 172.Xr ascii 7 173name for the 174.Nm 175module. 176It should be no longer than HELPER_NAME_MAXLEN-1 characters in length. 177The 178.Fa hdata 179argument is a pointer to the module's 180.Vt struct helper . 181The 182.Fa hhooks 183argument points to a static array of 184.Vt struct hookinfo 185structures. 186The array should contain a 187.Vt struct hookinfo 188for each 189.Xr hhook 9 190point the module wishes to hook, even when using the same hook function multiple 191times for different 192.Xr hhook 9 193points. 194The 195.Fa version 196argument specifies a version number for the module which will be passed to 197.Xr MODULE_VERSION 9 . 198The 199.Fn KHELP_DECLARE_MOD_UMA 200macro takes the additional 201.Fa ctor 202and 203.Fa dtor 204arguments, which specify optional 205.Xr uma 9 206constructor and destructor functions. 207NULL should be passed where the functionality is not required. 208.Pp 209The 210.Fn khelp_get_id 211function returns the numeric identifier for the 212.Nm 213module with name 214.Fa hname . 215.Pp 216The 217.Fn khelp_get_osd 218function is used to obtain the per-object data pointer for a specified 219.Nm 220module. 221The 222.Fa hosd 223argument is a pointer to the underlying subsystem object's 224.Vt struct osd . 225This is provided by the 226.Xr hhook 9 227framework when calling into a 228.Nm 229module's hook function. 230The 231.Fa id 232argument specifies the numeric identifier for the 233.Nm 234module to extract the data pointer from 235.Fa hosd 236for. 237The 238.Fa id 239is obtained using the 240.Fn khelp_get_id 241function. 242.Pp 243The 244.Fn khelp_add_hhook 245and 246.Fn khelp_remove_hhook 247functions allow a 248.Nm 249module to dynamically hook/unhook 250.Xr hhook 9 251points at run time. 252The 253.Fa hki 254argument specifies a pointer to a 255.Vt struct hookinfo 256which encapsulates the required information about the 257.Xr hhook 9 258point and hook function being manipulated. 259The HHOOK_WAITOK flag may be passed in via the 260.Fa flags 261argument of 262.Fn khelp_add_hhook 263if 264.Xr malloc 9 265is allowed to sleep waiting for memory to become available. 266.Ss Integrating Khelp Into a Kernel Subsystem 267Most of the work required to allow 268.Nm 269modules to do useful things relates to defining and instantiating suitable 270.Xr hhook 9 271points for 272.Nm 273modules to hook into. 274The only additional decision a subsystem needs to make is whether it wants to 275allow 276.Nm 277modules to associate persistent per-object data. 278Providing support for persistent data storage can allow 279.Nm 280modules to perform more complex functionality which may be desirable. 281Subsystems which want to allow Khelp modules to associate 282persistent per-object data with one of the subsystem's data structures need to 283make the following two key changes: 284.Bl -bullet 285.It 286Embed a 287.Vt struct osd 288pointer in the structure definition for the object. 289.It 290Add calls to 291.Fn khelp_init_osd 292and 293.Fn khelp_destroy_osd 294to the subsystem code paths which are responsible for respectively initialising 295and destroying the object. 296.El 297.Pp 298The 299.Fn khelp_init_osd 300function initialises the per-object data storage for all currently loaded 301.Nm 302modules of appropriate classes which have set the HELPER_NEEDS_OSD flag in their 303.Va h_flags 304field. 305The 306.Fa classes 307argument specifies a bitmask of 308.Nm 309classes which this subsystem associates with. 310If a 311.Nm 312module matches any of the classes in the bitmask, that module will be associated 313with the object. 314The 315.Fa hosd 316argument specifies the pointer to the object's 317.Vt struct osd 318which will be used to provide the persistent storage for use by 319.Nm 320modules. 321.Pp 322The 323.Fn khelp_destroy_osd 324function frees all memory that was associated with an object's 325.Vt struct osd 326by a previous call to 327.Fn khelp_init_osd . 328The 329.Fa hosd 330argument specifies the pointer to the object's 331.Vt struct osd 332which will be purged in preparation for destruction. 333.Sh IMPLEMENTATION NOTES 334.Nm 335modules are protected from being prematurely unloaded by a reference count. 336The count is incremented each time a subsystem calls 337.Fn khelp_init_osd 338causing persistent storage to be allocated for the module, and decremented for 339each corresponding call to 340.Fn khelp_destroy_osd . 341Only when a module's reference count has dropped to zero can the module be 342unloaded. 343.Sh RETURN VALUES 344The 345.Fn khelp_init_osd 346function returns zero if no errors occurred. 347It returns ENOMEM if a 348.Nm 349module which requires per-object storage fails to allocate the necessary memory. 350.Pp 351The 352.Fn khelp_destroy_osd 353function only returns zero to indicate that no errors occurred. 354.Pp 355The 356.Fn khelp_get_id 357function returns the unique numeric identifier for the registered 358.Nm 359module with name 360.Fa hname . 361It return -1 if no module with the specified name is currently registered. 362.Pp 363The 364.Fn khelp_get_osd 365function returns the pointer to the 366.Nm 367module's persistent object storage memory. 368If the module identified by 369.Fa id 370does not have persistent object storage registered with the object's 371.Fa hosd 372.Vt struct osd , 373NULL is returned. 374.Pp 375The 376.Fn khelp_add_hhook 377function returns zero if no errors occurred. 378It returns ENOENT if it could not find the requested 379.Xr hhook 9 380point. 381It returns ENOMEM if 382.Xr malloc 9 383failed to allocate memory. 384It returns EEXIST if attempting to register the same hook function more than 385once for the same 386.Xr hhook 9 387point. 388.Pp 389The 390.Fn khelp_remove_hhook 391function returns zero if no errors occurred. 392It returns ENOENT if it could not find the requested 393.Xr hhook 9 394point. 395.Sh EXAMPLES 396A well commented example Khelp module can be found at: 397.Pa /usr/share/examples/kld/khelp/h_example.c 398.Pp 399The Enhanced Round Trip Time (ERTT) 400.Xr h_ertt 4 401.Nm 402module provides a more complex example of what is possible. 403.Sh SEE ALSO 404.Xr h_ertt 4 , 405.Xr hhook 9 , 406.Xr osd 9 407.Sh ACKNOWLEDGEMENTS 408Development and testing of this software were made possible in part by grants 409from the FreeBSD Foundation and Cisco University Research Program Fund at 410Community Foundation Silicon Valley. 411.Sh HISTORY 412The 413.Nm 414kernel helper framework first appeared in 415.Fx 9.0 . 416.Pp 417The 418.Nm 419framework was first released in 2010 by Lawrence Stewart whilst studying at 420Swinburne University of Technology's Centre for Advanced Internet Architectures, 421Melbourne, Australia. 422More details are available at: 423.Pp 424http://caia.swin.edu.au/urp/newtcp/ 425.Sh AUTHORS 426.An -nosplit 427The 428.Nm 429framework was written by 430.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . 431.Pp 432This manual page was written by 433.An David Hayes Aq Mt david.hayes@ieee.org 434and 435.An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . 436