]> git.proxmox.com Git - mirror_frr.git/blob - lib/hook.c
Merge pull request #6114 from rgirada/frr-static
[mirror_frr.git] / lib / hook.c
1 /*
2 * Copyright (c) 2016 David Lamparter, for NetDEF, Inc.
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include <string.h>
22
23 #include "memory.h"
24 #include "hook.h"
25
26 DEFINE_MTYPE_STATIC(LIB, HOOK_ENTRY, "Hook entry")
27
28 void _hook_register(struct hook *hook, struct hookent *stackent, void *funcptr,
29 void *arg, bool has_arg, struct frrmod_runtime *module,
30 const char *funcname, int priority)
31 {
32 struct hookent *he, **pos;
33
34 if (!stackent->ent_used)
35 he = stackent;
36 else {
37 he = XCALLOC(MTYPE_HOOK_ENTRY, sizeof(*he));
38 he->ent_on_heap = true;
39 }
40 he->ent_used = true;
41 he->hookfn = funcptr;
42 he->hookarg = arg;
43 he->has_arg = has_arg;
44 he->module = module;
45 he->fnname = funcname;
46 he->priority = priority;
47
48 for (pos = &hook->entries; *pos; pos = &(*pos)->next)
49 if (hook->reverse ? (*pos)->priority < priority
50 : (*pos)->priority >= priority)
51 break;
52
53 he->next = *pos;
54 *pos = he;
55 }
56
57 void _hook_unregister(struct hook *hook, void *funcptr, void *arg, bool has_arg)
58 {
59 struct hookent *he, **prev;
60
61 for (prev = &hook->entries; (he = *prev) != NULL; prev = &he->next)
62 if (he->hookfn == funcptr && he->hookarg == arg
63 && he->has_arg == has_arg) {
64 *prev = he->next;
65 if (he->ent_on_heap)
66 XFREE(MTYPE_HOOK_ENTRY, he);
67 else
68 memset(he, 0, sizeof(*he));
69 break;
70 }
71 }