diff --git a/share/man/man9/khelp.9 b/share/man/man9/khelp.9 index 39515eef237c..d619f385d513 100644 --- a/share/man/man9/khelp.9 +++ b/share/man/man9/khelp.9 @@ -1,435 +1,435 @@ .\" .\" Copyright (c) 2010-2011 The FreeBSD Foundation .\" .\" This documentation was written at the Centre for Advanced Internet .\" Architectures, Swinburne University of Technology, Melbourne, Australia by .\" David Hayes and Lawrence Stewart under sponsorship from the FreeBSD .\" Foundation. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR .\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd February 15, 2011 +.Dd October 1, 2024 .Dt KHELP 9 .Os .Sh NAME .Nm khelp , .Nm khelp_init_osd , .Nm khelp_destroy_osd , .Nm khelp_get_id , .Nm khelp_get_osd , .Nm khelp_add_hhook , .Nm khelp_remove_hhook , .Nm KHELP_DECLARE_MOD , .Nm KHELP_DECLARE_MOD_UMA .Nd Kernel Helper Framework .Sh SYNOPSIS .In sys/khelp.h .In sys/module_khelp.h .Fn "int khelp_init_osd" "uint32_t classes" "struct osd *hosd" .Fn "int khelp_destroy_osd" "struct osd *hosd" .Fn "int32_t khelp_get_id" "char *hname" .Fn "void * khelp_get_osd" "struct osd *hosd" "int32_t id" -.Fn "int khelp_add_hhook" "struct hookinfo *hki" "uint32_t flags" -.Fn "int khelp_remove_hhook" "struct hookinfo *hki" +.Fn "int khelp_add_hhook" "const struct hookinfo *hki" "uint32_t flags" +.Fn "int khelp_remove_hhook" "const struct hookinfo *hki" .Fn KHELP_DECLARE_MOD "hname" "hdata" "hhooks" "version" .Fn KHELP_DECLARE_MOD_UMA "hname" "hdata" "hhooks" "version" "ctor" "dtor" .Sh DESCRIPTION .Nm provides a framework for managing .Nm modules, which indirectly use the .Xr hhook 9 KPI to register their hook functions with hook points of interest within the kernel. Khelp modules aim to provide a structured way to dynamically extend the kernel at runtime in an ABI preserving manner. Depending on the subsystem providing hook points, a .Nm module may be able to associate per-object data for maintaining relevant state between hook calls. The .Xr hhook 9 and .Nm frameworks are tightly integrated and anyone interested in .Nm should also read the .Xr hhook 9 manual page thoroughly. .Ss Information for Khelp Module Implementors .Nm modules are represented within the .Nm framework by a .Vt struct helper which has the following members: .Bd -literal -offset indent struct helper { int (*mod_init) (void); int (*mod_destroy) (void); #define HELPER_NAME_MAXLEN 16 char h_name[HELPER_NAME_MAXLEN]; uma_zone_t h_zone; struct hookinfo *h_hooks; uint32_t h_nhooks; uint32_t h_classes; int32_t h_id; volatile uint32_t h_refcount; uint16_t h_flags; TAILQ_ENTRY(helper) h_next; }; .Ed .Pp Modules must instantiate a .Vt struct helper , but are only required to set the .Va h_classes field, and may optionally set the .Va h_flags , .Va mod_init and .Va mod_destroy fields where required. The framework takes care of all other fields and modules should refrain from manipulating them. Using the C99 designated initialiser feature to set fields is encouraged. .Pp If specified, the .Va mod_init function will be run by the .Nm framework prior to completing the registration process. Returning a non-zero value from the .Va mod_init function will abort the registration process and fail to load the module. If specified, the .Va mod_destroy function will be run by the .Nm framework during the deregistration process, after the module has been deregistered by the .Nm framework. The return value is currently ignored. Valid .Nm classes are defined in .In sys/khelp.h . Valid flags are defined in .In sys/module_khelp.h . The HELPER_NEEDS_OSD flag should be set in the .Va h_flags field if the .Nm module requires persistent per-object data storage. There is no programmatic way (yet) to check if a .Nm class provides the ability for .Nm modules to associate persistent per-object data, so a manual check is required. .Pp The .Fn KHELP_DECLARE_MOD and .Fn KHELP_DECLARE_MOD_UMA macros provide convenient wrappers around the .Xr DECLARE_MODULE 9 macro, and are used to register a .Nm module with the .Nm framework. .Fn KHELP_DECLARE_MOD_UMA should only be used by modules which require the use of persistent per-object storage i.e. modules which set the HELPER_NEEDS_OSD flag in their .Vt struct helper Ns 's .Va h_flags field. .Pp The first four arguments common to both macros are as follows. The .Fa hname argument specifies the unique .Xr ascii 7 name for the .Nm module. It should be no longer than HELPER_NAME_MAXLEN-1 characters in length. The .Fa hdata argument is a pointer to the module's .Vt struct helper . The .Fa hhooks argument points to a static array of .Vt struct hookinfo structures. The array should contain a .Vt struct hookinfo for each .Xr hhook 9 point the module wishes to hook, even when using the same hook function multiple times for different .Xr hhook 9 points. The .Fa version argument specifies a version number for the module which will be passed to .Xr MODULE_VERSION 9 . The .Fn KHELP_DECLARE_MOD_UMA macro takes the additional .Fa ctor and .Fa dtor arguments, which specify optional .Xr uma 9 constructor and destructor functions. NULL should be passed where the functionality is not required. .Pp The .Fn khelp_get_id function returns the numeric identifier for the .Nm module with name .Fa hname . .Pp The .Fn khelp_get_osd function is used to obtain the per-object data pointer for a specified .Nm module. The .Fa hosd argument is a pointer to the underlying subsystem object's .Vt struct osd . This is provided by the .Xr hhook 9 framework when calling into a .Nm module's hook function. The .Fa id argument specifies the numeric identifier for the .Nm module to extract the data pointer from .Fa hosd for. The .Fa id is obtained using the .Fn khelp_get_id function. .Pp The .Fn khelp_add_hhook and .Fn khelp_remove_hhook functions allow a .Nm module to dynamically hook/unhook .Xr hhook 9 points at run time. The .Fa hki argument specifies a pointer to a .Vt struct hookinfo which encapsulates the required information about the .Xr hhook 9 point and hook function being manipulated. The HHOOK_WAITOK flag may be passed in via the .Fa flags argument of .Fn khelp_add_hhook if .Xr malloc 9 is allowed to sleep waiting for memory to become available. .Ss Integrating Khelp Into a Kernel Subsystem Most of the work required to allow .Nm modules to do useful things relates to defining and instantiating suitable .Xr hhook 9 points for .Nm modules to hook into. The only additional decision a subsystem needs to make is whether it wants to allow .Nm modules to associate persistent per-object data. Providing support for persistent data storage can allow .Nm modules to perform more complex functionality which may be desirable. Subsystems which want to allow Khelp modules to associate persistent per-object data with one of the subsystem's data structures need to make the following two key changes: .Bl -bullet .It Embed a .Vt struct osd pointer in the structure definition for the object. .It Add calls to .Fn khelp_init_osd and .Fn khelp_destroy_osd to the subsystem code paths which are responsible for respectively initialising and destroying the object. .El .Pp The .Fn khelp_init_osd function initialises the per-object data storage for all currently loaded .Nm modules of appropriate classes which have set the HELPER_NEEDS_OSD flag in their .Va h_flags field. The .Fa classes argument specifies a bitmask of .Nm classes which this subsystem associates with. If a .Nm module matches any of the classes in the bitmask, that module will be associated with the object. The .Fa hosd argument specifies the pointer to the object's .Vt struct osd which will be used to provide the persistent storage for use by .Nm modules. .Pp The .Fn khelp_destroy_osd function frees all memory that was associated with an object's .Vt struct osd by a previous call to .Fn khelp_init_osd . The .Fa hosd argument specifies the pointer to the object's .Vt struct osd which will be purged in preparation for destruction. .Sh IMPLEMENTATION NOTES .Nm modules are protected from being prematurely unloaded by a reference count. The count is incremented each time a subsystem calls .Fn khelp_init_osd causing persistent storage to be allocated for the module, and decremented for each corresponding call to .Fn khelp_destroy_osd . Only when a module's reference count has dropped to zero can the module be unloaded. .Sh RETURN VALUES The .Fn khelp_init_osd function returns zero if no errors occurred. It returns ENOMEM if a .Nm module which requires per-object storage fails to allocate the necessary memory. .Pp The .Fn khelp_destroy_osd function only returns zero to indicate that no errors occurred. .Pp The .Fn khelp_get_id function returns the unique numeric identifier for the registered .Nm module with name .Fa hname . It return -1 if no module with the specified name is currently registered. .Pp The .Fn khelp_get_osd function returns the pointer to the .Nm module's persistent object storage memory. If the module identified by .Fa id does not have persistent object storage registered with the object's .Fa hosd .Vt struct osd , NULL is returned. .Pp The .Fn khelp_add_hhook function returns zero if no errors occurred. It returns ENOENT if it could not find the requested .Xr hhook 9 point. It returns ENOMEM if .Xr malloc 9 failed to allocate memory. It returns EEXIST if attempting to register the same hook function more than once for the same .Xr hhook 9 point. .Pp The .Fn khelp_remove_hhook function returns zero if no errors occurred. It returns ENOENT if it could not find the requested .Xr hhook 9 point. .Sh EXAMPLES A well commented example Khelp module can be found at: .Pa /usr/share/examples/kld/khelp/h_example.c .Pp The Enhanced Round Trip Time (ERTT) .Xr h_ertt 4 .Nm module provides a more complex example of what is possible. .Sh SEE ALSO .Xr h_ertt 4 , .Xr hhook 9 , .Xr osd 9 .Sh ACKNOWLEDGEMENTS 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. .Sh HISTORY The .Nm kernel helper framework first appeared in .Fx 9.0 . .Pp The .Nm framework was first released in 2010 by Lawrence Stewart whilst studying at Swinburne University of Technology's Centre for Advanced Internet Architectures, Melbourne, Australia. More details are available at: .Pp http://caia.swin.edu.au/urp/newtcp/ .Sh AUTHORS .An -nosplit The .Nm framework was written by .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . .Pp This manual page was written by .An David Hayes Aq Mt david.hayes@ieee.org and .An Lawrence Stewart Aq Mt lstewart@FreeBSD.org . diff --git a/sys/kern/kern_khelp.c b/sys/kern/kern_khelp.c index 1ab56780f394..4a7e93ff69fa 100644 --- a/sys/kern/kern_khelp.c +++ b/sys/kern/kern_khelp.c @@ -1,367 +1,367 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2010,2013 Lawrence Stewart * Copyright (c) 2010 The FreeBSD Foundation * All rights reserved. * * This software was developed by Lawrence Stewart while studying at the Centre * for Advanced Internet Architectures, Swinburne University of Technology, * made possible in part by grants from the FreeBSD Foundation and Cisco * University Research Program Fund at Community Foundation Silicon Valley. * * Portions of this software were developed at the Centre for Advanced * Internet Architectures, Swinburne University of Technology, Melbourne, * Australia by Lawrence Stewart under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include static struct rwlock khelp_list_lock; RW_SYSINIT(khelplistlock, &khelp_list_lock, "helper list lock"); static TAILQ_HEAD(helper_head, helper) helpers = TAILQ_HEAD_INITIALIZER(helpers); /* Private function prototypes. */ static inline void khelp_remove_osd(struct helper *h, struct osd *hosd); void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags); #define KHELP_LIST_WLOCK() rw_wlock(&khelp_list_lock) #define KHELP_LIST_WUNLOCK() rw_wunlock(&khelp_list_lock) #define KHELP_LIST_RLOCK() rw_rlock(&khelp_list_lock) #define KHELP_LIST_RUNLOCK() rw_runlock(&khelp_list_lock) #define KHELP_LIST_LOCK_ASSERT() rw_assert(&khelp_list_lock, RA_LOCKED) int khelp_register_helper(struct helper *h) { struct helper *tmph; int error, i, inserted; error = inserted = 0; refcount_init(&h->h_refcount, 0); h->h_id = osd_register(OSD_KHELP, NULL, NULL); /* It's only safe to add the hooks after osd_register(). */ for (i = 0; i < h->h_nhooks && !error; i++) { /* We don't require the module to assign hook_helper. */ h->h_hooks[i].hook_helper = h; error = hhook_add_hook_lookup(&h->h_hooks[i], HHOOK_WAITOK); if (error) printf("%s: \"%s\" khelp module unable to " "hook type %d id %d due to error %d\n", __func__, h->h_name, h->h_hooks[i].hook_type, h->h_hooks[i].hook_id, error); } if (error) { for (i--; i >= 0; i--) hhook_remove_hook_lookup(&h->h_hooks[i]); osd_deregister(OSD_KHELP, h->h_id); } else { KHELP_LIST_WLOCK(); /* * Keep list of helpers sorted in descending h_id order. Due to * the way osd_set() works, a sorted list ensures * khelp_init_osd() will operate with improved efficiency. */ TAILQ_FOREACH(tmph, &helpers, h_next) { if (tmph->h_id < h->h_id) { TAILQ_INSERT_BEFORE(tmph, h, h_next); inserted = 1; break; } } if (!inserted) TAILQ_INSERT_TAIL(&helpers, h, h_next); KHELP_LIST_WUNLOCK(); } return (error); } int khelp_deregister_helper(struct helper *h) { struct helper *tmph; int error, i; KHELP_LIST_WLOCK(); if (h->h_refcount > 0) error = EBUSY; else { error = ENOENT; TAILQ_FOREACH(tmph, &helpers, h_next) { if (tmph == h) { TAILQ_REMOVE(&helpers, h, h_next); error = 0; break; } } } KHELP_LIST_WUNLOCK(); if (!error) { for (i = 0; i < h->h_nhooks; i++) hhook_remove_hook_lookup(&h->h_hooks[i]); osd_deregister(OSD_KHELP, h->h_id); } return (error); } int khelp_init_osd(uint32_t classes, struct osd *hosd) { struct helper *h; void *hdata; int error; KASSERT(hosd != NULL, ("struct osd not initialised!")); error = 0; KHELP_LIST_RLOCK(); TAILQ_FOREACH(h, &helpers, h_next) { /* If helper is correct class and needs to store OSD... */ if (h->h_classes & classes && h->h_flags & HELPER_NEEDS_OSD) { hdata = uma_zalloc(h->h_zone, M_NOWAIT); if (hdata == NULL) { error = ENOMEM; break; } osd_set(OSD_KHELP, hosd, h->h_id, hdata); refcount_acquire(&h->h_refcount); } } if (error) { /* Delete OSD that was assigned prior to the error. */ TAILQ_FOREACH(h, &helpers, h_next) { if (h->h_classes & classes) khelp_remove_osd(h, hosd); } } KHELP_LIST_RUNLOCK(); return (error); } int khelp_destroy_osd(struct osd *hosd) { struct helper *h; int error; KASSERT(hosd != NULL, ("struct osd not initialised!")); error = 0; KHELP_LIST_RLOCK(); /* * Clean up all khelp related OSD. * * XXXLAS: Would be nice to use something like osd_exit() here but it * doesn't have the right semantics for this purpose. */ TAILQ_FOREACH(h, &helpers, h_next) khelp_remove_osd(h, hosd); KHELP_LIST_RUNLOCK(); return (error); } static inline void khelp_remove_osd(struct helper *h, struct osd *hosd) { void *hdata; if (h->h_flags & HELPER_NEEDS_OSD) { /* * If the current helper uses OSD and calling osd_get() * on the helper's h_id returns non-NULL, the helper has * OSD attached to 'hosd' which needs to be cleaned up. */ hdata = osd_get(OSD_KHELP, hosd, h->h_id); if (hdata != NULL) { uma_zfree(h->h_zone, hdata); osd_del(OSD_KHELP, hosd, h->h_id); refcount_release(&h->h_refcount); } } } void * khelp_get_osd(struct osd *hosd, int32_t id) { return (osd_get(OSD_KHELP, hosd, id)); } int32_t khelp_get_id(char *hname) { struct helper *h; int32_t id; id = -1; KHELP_LIST_RLOCK(); TAILQ_FOREACH(h, &helpers, h_next) { if (strncmp(h->h_name, hname, HELPER_NAME_MAXLEN) == 0) { id = h->h_id; break; } } KHELP_LIST_RUNLOCK(); return (id); } int -khelp_add_hhook(struct hookinfo *hki, uint32_t flags) +khelp_add_hhook(const struct hookinfo *hki, uint32_t flags) { int error; /* * XXXLAS: Should probably include the functionality to update the * helper's h_hooks struct member. */ error = hhook_add_hook_lookup(hki, flags); return (error); } int -khelp_remove_hhook(struct hookinfo *hki) +khelp_remove_hhook(const struct hookinfo *hki) { int error; /* * XXXLAS: Should probably include the functionality to update the * helper's h_hooks struct member. */ error = hhook_remove_hook_lookup(hki); return (error); } /* * Private KPI between hhook and khelp that allows khelp modules to insert hook * functions into hhook points which register after the modules were loaded. */ void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags) { struct helper *h; int error, i; KHELP_LIST_RLOCK(); TAILQ_FOREACH(h, &helpers, h_next) { for (i = 0; i < h->h_nhooks; i++) { if (hhh->hhh_type != h->h_hooks[i].hook_type || hhh->hhh_id != h->h_hooks[i].hook_id) continue; error = hhook_add_hook(hhh, &h->h_hooks[i], flags); if (error) { printf("%s: \"%s\" khelp module unable to " "hook type %d id %d due to error %d\n", __func__, h->h_name, h->h_hooks[i].hook_type, h->h_hooks[i].hook_id, error); error = 0; } } } KHELP_LIST_RUNLOCK(); } int khelp_modevent(module_t mod, int event_type, void *data) { struct khelp_modevent_data *kmd; int error; kmd = (struct khelp_modevent_data *)data; error = 0; switch(event_type) { case MOD_LOAD: if (kmd->helper->h_flags & HELPER_NEEDS_OSD) { if (kmd->uma_zsize <= 0) { printf("Use KHELP_DECLARE_MOD_UMA() instead!\n"); error = EDOOFUS; break; } kmd->helper->h_zone = uma_zcreate(kmd->name, kmd->uma_zsize, kmd->umactor, kmd->umadtor, NULL, NULL, 0, 0); } strlcpy(kmd->helper->h_name, kmd->name, HELPER_NAME_MAXLEN); kmd->helper->h_hooks = kmd->hooks; kmd->helper->h_nhooks = kmd->nhooks; if (kmd->helper->mod_init != NULL) error = kmd->helper->mod_init(); if (!error) error = khelp_register_helper(kmd->helper); break; case MOD_QUIESCE: case MOD_SHUTDOWN: case MOD_UNLOAD: error = khelp_deregister_helper(kmd->helper); if (!error) { if (kmd->helper->h_flags & HELPER_NEEDS_OSD) uma_zdestroy(kmd->helper->h_zone); if (kmd->helper->mod_destroy != NULL) kmd->helper->mod_destroy(); } else if (error == ENOENT) /* Do nothing and allow unload if helper not in list. */ error = 0; else if (error == EBUSY && event_type != MOD_SHUTDOWN) printf("Khelp module \"%s\" can't unload until its " "refcount drops from %d to 0.\n", kmd->name, kmd->helper->h_refcount); break; default: error = EINVAL; break; } return (error); } diff --git a/sys/sys/khelp.h b/sys/sys/khelp.h index 2ef45806c35a..7aadb6a58faa 100644 --- a/sys/sys/khelp.h +++ b/sys/sys/khelp.h @@ -1,77 +1,77 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2010 Lawrence Stewart * Copyright (c) 2010 The FreeBSD Foundation * All rights reserved. * * This software was developed by Lawrence Stewart while studying at the Centre * for Advanced Internet Architectures, Swinburne University of Technology, made * possible in part by grants from the FreeBSD Foundation and Cisco University * Research Program Fund at Community Foundation Silicon Valley. * * Portions of this software were developed at the Centre for Advanced * Internet Architectures, Swinburne University of Technology, Melbourne, * Australia by Lawrence Stewart under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * A KPI for managing kernel helper modules which perform useful functionality * within the kernel. Originally released as part of the NewTCP research project * at Swinburne University of Technology's Centre for Advanced Internet * Architectures, Melbourne, Australia, which was made possible in part by a * grant from the Cisco University Research Program Fund at Community Foundation * Silicon Valley. More details are available at: * http://caia.swin.edu.au/urp/newtcp/ */ #ifndef _SYS_KHELP_H_ #define _SYS_KHELP_H_ struct helper; struct hookinfo; struct osd; /* Helper classes. */ #define HELPER_CLASS_TCP 0x00000001 #define HELPER_CLASS_SOCKET 0x00000002 /* Public KPI functions. */ int khelp_register_helper(struct helper *h); int khelp_deregister_helper(struct helper *h); int khelp_init_osd(uint32_t classes, struct osd *hosd); int khelp_destroy_osd(struct osd *hosd); void * khelp_get_osd(struct osd *hosd, int32_t id); int32_t khelp_get_id(char *hname); -int khelp_add_hhook(struct hookinfo *hki, uint32_t flags); +int khelp_add_hhook(const struct hookinfo *hki, uint32_t flags); -int khelp_remove_hhook(struct hookinfo *hki); +int khelp_remove_hhook(const struct hookinfo *hki); #endif /* _SYS_KHELP_H_ */