Prepare hooks direct pointers on setup to avoid heavy ng_findhook() calls

during operarion.
This commit is contained in:
mav 2008-02-04 19:26:53 +00:00
parent 5c5b24c7a8
commit cd7d07a63f

View File

@ -85,8 +85,9 @@ MALLOC_DEFINE(M_NETGRAPH_BPF, "netgraph_bpf", "netgraph bpf node ");
/* Per hook private info */
struct ng_bpf_hookinfo {
node_p node;
hook_p hook;
hook_p match;
hook_p nomatch;
struct ng_bpf_hookprog *prog;
#ifdef BPF_JITTER
bpf_jit_filter *jit_prog;
@ -233,6 +234,35 @@ ng_bpf_constructor(node_p node)
return (0);
}
/*
* Callback functions to be used by NG_NODE_FOREACH_HOOK() macro.
*/
static int
ng_bpf_addrefs(hook_p hook, void* arg)
{
hinfo_p hip = NG_HOOK_PRIVATE(hook);
hook_p h = (hook_p)arg;
if (strcmp(hip->prog->ifMatch, NG_HOOK_NAME(h)) == 0)
hip->match = h;
if (strcmp(hip->prog->ifNotMatch, NG_HOOK_NAME(h)) == 0)
hip->nomatch = h;
return (1);
}
static int
ng_bpf_remrefs(hook_p hook, void* arg)
{
hinfo_p hip = NG_HOOK_PRIVATE(hook);
hook_p h = (hook_p)arg;
if (hip->match == h)
hip->match = NULL;
if (hip->nomatch == h)
hip->nomatch = NULL;
return (1);
}
/*
* Add a hook
*/
@ -240,6 +270,7 @@ static int
ng_bpf_newhook(node_p node, hook_p hook, const char *name)
{
hinfo_p hip;
hook_p tmp;
int error;
/* Create hook private structure */
@ -248,7 +279,9 @@ ng_bpf_newhook(node_p node, hook_p hook, const char *name)
return (ENOMEM);
hip->hook = hook;
NG_HOOK_SET_PRIVATE(hook, hip);
hip->node = node;
/* Add our reference into other hooks data. */
NG_NODE_FOREACH_HOOK(node, ng_bpf_addrefs, hook, tmp);
/* Attach the default BPF program */
if ((error = ng_bpf_setprog(hook, &ng_bpf_default_prog)) != 0) {
@ -258,8 +291,7 @@ ng_bpf_newhook(node_p node, hook_p hook, const char *name)
}
/* Set hook name */
strncpy(hip->prog->thisHook, name, sizeof(hip->prog->thisHook) - 1);
hip->prog->thisHook[sizeof(hip->prog->thisHook) - 1] = '\0';
strlcpy(hip->prog->thisHook, name, sizeof(hip->prog->thisHook));
return (0);
}
@ -396,6 +428,12 @@ ng_bpf_rcvdata(hook_p hook, item_p item)
hip->stats.recvFrames++;
hip->stats.recvOctets += totlen;
/* Don't call bpf_filter() with totlen == 0! */
if (totlen == 0) {
len = 0;
goto ready;
}
#ifdef BPF_JITTER
if (bpf_jitter_enable != 0 && hip->jit_prog != NULL)
usejit = 1;
@ -424,25 +462,18 @@ ng_bpf_rcvdata(hook_p hook, item_p item)
}
/* Run packet through filter */
if (totlen == 0)
len = 0; /* don't call bpf_filter() with totlen == 0! */
else {
#ifdef BPF_JITTER
if (usejit)
len = (*(hip->jit_prog->func))(data, totlen, totlen);
else
if (usejit)
len = (*(hip->jit_prog->func))(data, totlen, totlen);
else
#endif
if (data) {
len = bpf_filter(hip->prog->bpf_prog, data,
totlen, totlen);
} else {
len = bpf_filter(hip->prog->bpf_prog, (u_char *) m,
totlen, 0);
}
}
if (data)
len = bpf_filter(hip->prog->bpf_prog, data, totlen, totlen);
else
len = bpf_filter(hip->prog->bpf_prog, (u_char *)m, totlen, 0);
if (needfree)
FREE(data, M_NETGRAPH_BPF);
ready:
/* See if we got a match and find destination hook */
if (len > 0) {
@ -455,11 +486,11 @@ ng_bpf_rcvdata(hook_p hook, item_p item)
/* Assume this never changes m */
if (len < totlen) {
m_adj(m, -(totlen - len));
totlen -= len;
totlen = len;
}
dest = ng_findhook(hip->node, hip->prog->ifMatch);
dest = hip->match;
} else
dest = ng_findhook(hip->node, hip->prog->ifNotMatch);
dest = hip->nomatch;
if (dest == NULL) {
NG_FREE_ITEM(item);
return (0);
@ -489,20 +520,24 @@ ng_bpf_shutdown(node_p node)
static int
ng_bpf_disconnect(hook_p hook)
{
const node_p node = NG_HOOK_NODE(hook);
const hinfo_p hip = NG_HOOK_PRIVATE(hook);
hook_p tmp;
KASSERT(hip != NULL, ("%s: null info", __func__));
/* Remove our reference from other hooks data. */
NG_NODE_FOREACH_HOOK(node, ng_bpf_remrefs, hook, tmp);
FREE(hip->prog, M_NETGRAPH_BPF);
#ifdef BPF_JITTER
if (hip->jit_prog != NULL)
bpf_destroy_jit_filter(hip->jit_prog);
#endif
bzero(hip, sizeof(*hip));
FREE(hip, M_NETGRAPH_BPF);
NG_HOOK_SET_PRIVATE(hook, NULL); /* for good measure */
if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
&& (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) {
ng_rmnode_self(NG_HOOK_NODE(hook));
if ((NG_NODE_NUMHOOKS(node) == 0) &&
(NG_NODE_IS_VALID(node))) {
ng_rmnode_self(node);
}
return (0);
}
@ -547,5 +582,9 @@ ng_bpf_setprog(hook_p hook, const struct ng_bpf_hookprog *hp0)
bpf_destroy_jit_filter(hip->jit_prog);
hip->jit_prog = jit_prog;
#endif
/* Prepare direct references on target hooks. */
hip->match = ng_findhook(NG_HOOK_NODE(hook), hip->prog->ifMatch);
hip->nomatch = ng_findhook(NG_HOOK_NODE(hook), hip->prog->ifNotMatch);
return (0);
}