From cd7d07a63fb88b7beb7cb677e79c5eadde070c4a Mon Sep 17 00:00:00 2001 From: mav Date: Mon, 4 Feb 2008 19:26:53 +0000 Subject: Prepare hooks direct pointers on setup to avoid heavy ng_findhook() calls during operarion. --- sys/netgraph/ng_bpf.c | 93 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 27 deletions(-) (limited to 'sys/netgraph/ng_bpf.c') diff --git a/sys/netgraph/ng_bpf.c b/sys/netgraph/ng_bpf.c index f31872f..6c4c212 100644 --- a/sys/netgraph/ng_bpf.c +++ b/sys/netgraph/ng_bpf.c @@ -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; @@ -234,12 +235,42 @@ ng_bpf_constructor(node_p node) } /* + * 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 */ 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); } -- cgit v1.1